aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2006-09-22 06:30:14 -0400
committerPaul Mackerras <paulus@samba.org>2006-09-26 01:24:34 -0400
commit0ddd3e7d07d6adc4e905ee869a85db5184a02c17 (patch)
tree9dbab98d6aa3093cd24e8ed331559444e230c32a /arch
parente12514650b167f48e952d50315fd492d01d42988 (diff)
[POWERPC] Always call cede in pseries dedicated idle loop
The smt_snooze_delay logic changed a bit when the idle loops were consolidated. A value of 0 used to mean we always polled, now it means we always sleep. Instead of restoring the old behaviour, lets put a reasonable default in smt_snooze_delay. This means we spin for a bit (in case an external interrupt comes in) and then sleep. Also the pseries dedicated idle loop currently does not cede both threads in an SMT pair. The hypervisor wants us to call in so it can power manage, so lets do that. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/sysfs.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c24
2 files changed, 5 insertions, 23 deletions
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 406f308ddead..d45a168bdaca 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -25,8 +25,8 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
25/* SMT stuff */ 25/* SMT stuff */
26 26
27#ifdef CONFIG_PPC_MULTIPLATFORM 27#ifdef CONFIG_PPC_MULTIPLATFORM
28/* default to snooze disabled */ 28/* Time in microseconds we delay before sleeping in the idle loop */
29DEFINE_PER_CPU(unsigned long, smt_snooze_delay); 29DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
30 30
31static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf, 31static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
32 size_t count) 32 size_t count)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index a6398fbe530d..2551da46b2a6 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -477,7 +477,6 @@ static void pseries_dedicated_idle_sleep(void)
477{ 477{
478 unsigned int cpu = smp_processor_id(); 478 unsigned int cpu = smp_processor_id();
479 unsigned long start_snooze; 479 unsigned long start_snooze;
480 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
481 480
482 /* 481 /*
483 * Indicate to the HV that we are idle. Now would be 482 * Indicate to the HV that we are idle. Now would be
@@ -490,9 +489,9 @@ static void pseries_dedicated_idle_sleep(void)
490 * has been checked recently. If we should poll for a little 489 * has been checked recently. If we should poll for a little
491 * while, do so. 490 * while, do so.
492 */ 491 */
493 if (*smt_snooze_delay) { 492 if (__get_cpu_var(smt_snooze_delay)) {
494 start_snooze = get_tb() + 493 start_snooze = get_tb() +
495 *smt_snooze_delay * tb_ticks_per_usec; 494 __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec;
496 local_irq_enable(); 495 local_irq_enable();
497 set_thread_flag(TIF_POLLING_NRFLAG); 496 set_thread_flag(TIF_POLLING_NRFLAG);
498 497
@@ -512,24 +511,7 @@ static void pseries_dedicated_idle_sleep(void)
512 goto out; 511 goto out;
513 } 512 }
514 513
515 /* 514 cede_processor();
516 * If not SMT, cede processor. If CPU is running SMT
517 * cede if the other thread is not idle, so that it can
518 * go single-threaded. If the other thread is idle,
519 * we ask the hypervisor if it has pending work it
520 * wants to do and cede if it does. Otherwise we keep
521 * polling in order to reduce interrupt latency.
522 *
523 * Doing the cede when the other thread is active will
524 * result in this thread going dormant, meaning the other
525 * thread gets to run in single-threaded (ST) mode, which
526 * is slightly faster than SMT mode with this thread at
527 * very low priority. The cede enables interrupts, which
528 * doesn't matter here.
529 */
530 if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
531 || poll_pending() == H_PENDING)
532 cede_processor();
533 515
534out: 516out:
535 HMT_medium(); 517 HMT_medium();