summaryrefslogtreecommitdiffstats
path: root/core/timebase.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-05-22 15:53:01 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-06-06 20:49:06 +1000
commitdb9c1422002c1333fd09177d32edb8c2003fb4ea (patch)
tree5f6e4186e87b1c7927a1d9d915e59529c3929c19 /core/timebase.c
parent38b0c8454b56a74fe785f0db1d218afa8f6ea478 (diff)
downloadblackbird-skiboot-db9c1422002c1333fd09177d32edb8c2003fb4ea.tar.gz
blackbird-skiboot-db9c1422002c1333fd09177d32edb8c2003fb4ea.zip
Improve cpu_idle when PM is disabled
Split cpu_idle() into cpu_idle_delay() and cpu_idle_job() rather than requesting the idle type as a function argument. Have those functions provide a default polling (non-PM) implentation which spin at the lowest SMT priority. This moves all the decrementer delay code into the CPU idle code rather than the caller. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/timebase.c')
-rw-r--r--core/timebase.c28
1 files changed, 8 insertions, 20 deletions
diff --git a/core/timebase.c b/core/timebase.c
index a3c0fec5..ca961c39 100644
--- a/core/timebase.c
+++ b/core/timebase.c
@@ -24,8 +24,8 @@ unsigned long tb_hz = 512000000;
static void time_wait_poll(unsigned long duration)
{
- unsigned long remaining = duration;
- unsigned long end = mftb() + duration;
+ unsigned long now = mftb();
+ unsigned long end = now + duration;
unsigned long period = msecs_to_tb(5);
if (this_cpu()->tb_invalid) {
@@ -33,7 +33,9 @@ static void time_wait_poll(unsigned long duration)
return;
}
- while (tb_compare(mftb(), end) != TB_AAFTERB) {
+ while (tb_compare(now, end) != TB_AAFTERB) {
+ unsigned long remaining = end - now;
+
/* Call pollers periodically but not continually to avoid
* bouncing cachelines due to lock contention. */
if (remaining >= period) {
@@ -43,7 +45,7 @@ static void time_wait_poll(unsigned long duration)
} else
time_wait_nopoll(remaining);
- cpu_relax();
+ now = mftb();
}
}
@@ -64,28 +66,14 @@ void time_wait(unsigned long duration)
void time_wait_nopoll(unsigned long duration)
{
- unsigned long end = mftb() + duration;
- unsigned long min = usecs_to_tb(10);
+ unsigned long min_sleep = usecs_to_tb(10);
if (this_cpu()->tb_invalid) {
cpu_relax();
return;
}
- for (;;) {
- uint64_t delay, tb = mftb();
-
- if (tb_compare(tb, end) == TB_AAFTERB)
- break;
- delay = end - tb;
- if (delay >= 0x7fffffff)
- delay = 0x7fffffff;
- if (delay >= min) {
- mtspr(SPR_DEC, delay);
- cpu_idle(cpu_wake_on_dec);
- } else
- cpu_relax();
- }
+ cpu_idle_delay(duration, min_sleep);
}
void time_wait_ms(unsigned long ms)
OpenPOWER on IntegriCloud