diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2017-05-22 15:53:01 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-06-06 20:49:06 +1000 |
commit | db9c1422002c1333fd09177d32edb8c2003fb4ea (patch) | |
tree | 5f6e4186e87b1c7927a1d9d915e59529c3929c19 /core/timebase.c | |
parent | 38b0c8454b56a74fe785f0db1d218afa8f6ea478 (diff) | |
download | blackbird-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.c | 28 |
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) |