aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2013-02-10 01:38:39 -0500
committerLen Brown <len.brown@intel.com>2013-02-10 03:03:41 -0500
commit69fb3676df3329a7142803bb3502fa59dc0db2e3 (patch)
treee2cfa5a6513e07d01e6b1fe935f09be8300d7bde /arch/x86/kernel/process.c
parent6a377ddc4e4ede2eeb9cd46ada23bbe417704fc9 (diff)
x86 idle: remove mwait_idle() and "idle=mwait" cmdline param
mwait_idle() is a C1-only idle loop intended to be more efficient than HLT, starting on Pentium-4 HT-enabled processors. But mwait_idle() has been replaced by the more general mwait_idle_with_hints(), which handles both C1 and deeper C-states. ACPI processor_idle and intel_idle use only mwait_idle_with_hints(), and no longer use mwait_idle(). Here we simplify the x86 native idle code by removing mwait_idle(), and the "idle=mwait" bootparam used to invoke it. Since Linux 3.0 there has been a boot-time warning when "idle=mwait" was invoked saying it would be removed in 2012. This removal was also noted in the (now removed:-) feature-removal-schedule.txt. After this change, kernels configured with (CONFIG_ACPI=n && CONFIG_INTEL_IDLE=n) when run on hardware that supports MWAIT will simply use HLT. If MWAIT is desired on those systems, cpuidle and the cpuidle drivers above can be enabled. Signed-off-by: Len Brown <len.brown@intel.com> Cc: x86@kernel.org
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r--arch/x86/kernel/process.c79
1 files changed, 1 insertions, 78 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 7ed9f6b08ba0..cd5a4c9ef835 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -421,27 +421,6 @@ void stop_this_cpu(void *dummy)
421 } 421 }
422} 422}
423 423
424/* Default MONITOR/MWAIT with no hints, used for default C1 state */
425static void mwait_idle(void)
426{
427 if (!need_resched()) {
428 trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
429 trace_cpu_idle_rcuidle(1, smp_processor_id());
430 if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
431 clflush((void *)&current_thread_info()->flags);
432
433 __monitor((void *)&current_thread_info()->flags, 0, 0);
434 smp_mb();
435 if (!need_resched())
436 __sti_mwait(0, 0);
437 else
438 local_irq_enable();
439 trace_power_end_rcuidle(smp_processor_id());
440 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
441 } else
442 local_irq_enable();
443}
444
445/* 424/*
446 * On SMP it's slightly faster (but much more power-consuming!) 425 * On SMP it's slightly faster (but much more power-consuming!)
447 * to poll the ->work.need_resched flag instead of waiting for the 426 * to poll the ->work.need_resched flag instead of waiting for the
@@ -458,53 +437,6 @@ static void poll_idle(void)
458 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); 437 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
459} 438}
460 439
461/*
462 * mwait selection logic:
463 *
464 * It depends on the CPU. For AMD CPUs that support MWAIT this is
465 * wrong. Family 0x10 and 0x11 CPUs will enter C1 on HLT. Powersavings
466 * then depend on a clock divisor and current Pstate of the core. If
467 * all cores of a processor are in halt state (C1) the processor can
468 * enter the C1E (C1 enhanced) state. If mwait is used this will never
469 * happen.
470 *
471 * idle=mwait overrides this decision and forces the usage of mwait.
472 */
473
474#define MWAIT_INFO 0x05
475#define MWAIT_ECX_EXTENDED_INFO 0x01
476#define MWAIT_EDX_C1 0xf0
477
478int mwait_usable(const struct cpuinfo_x86 *c)
479{
480 u32 eax, ebx, ecx, edx;
481
482 /* Use mwait if idle=mwait boot option is given */
483 if (boot_option_idle_override == IDLE_FORCE_MWAIT)
484 return 1;
485
486 /*
487 * Any idle= boot option other than idle=mwait means that we must not
488 * use mwait. Eg: idle=halt or idle=poll or idle=nomwait
489 */
490 if (boot_option_idle_override != IDLE_NO_OVERRIDE)
491 return 0;
492
493 if (c->cpuid_level < MWAIT_INFO)
494 return 0;
495
496 cpuid(MWAIT_INFO, &eax, &ebx, &ecx, &edx);
497 /* Check, whether EDX has extended info about MWAIT */
498 if (!(ecx & MWAIT_ECX_EXTENDED_INFO))
499 return 1;
500
501 /*
502 * edx enumeratios MONITOR/MWAIT extensions. Check, whether
503 * C1 supports MWAIT
504 */
505 return (edx & MWAIT_EDX_C1);
506}
507
508bool amd_e400_c1e_detected; 440bool amd_e400_c1e_detected;
509EXPORT_SYMBOL(amd_e400_c1e_detected); 441EXPORT_SYMBOL(amd_e400_c1e_detected);
510 442
@@ -576,13 +508,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
576 if (pm_idle) 508 if (pm_idle)
577 return; 509 return;
578 510
579 if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) { 511 if (cpu_has_amd_erratum(amd_erratum_400)) {
580 /*
581 * One CPU supports mwait => All CPUs supports mwait
582 */
583 pr_info("using mwait in idle threads\n");
584 pm_idle = mwait_idle;
585 } else if (cpu_has_amd_erratum(amd_erratum_400)) {
586 /* E400: APIC timer interrupt does not wake up CPU from C1e */ 512 /* E400: APIC timer interrupt does not wake up CPU from C1e */
587 pr_info("using AMD E400 aware idle routine\n"); 513 pr_info("using AMD E400 aware idle routine\n");
588 pm_idle = amd_e400_idle; 514 pm_idle = amd_e400_idle;
@@ -606,9 +532,6 @@ static int __init idle_setup(char *str)
606 pr_info("using polling idle threads\n"); 532 pr_info("using polling idle threads\n");
607 pm_idle = poll_idle; 533 pm_idle = poll_idle;
608 boot_option_idle_override = IDLE_POLL; 534 boot_option_idle_override = IDLE_POLL;
609 } else if (!strcmp(str, "mwait")) {
610 boot_option_idle_override = IDLE_FORCE_MWAIT;
611 WARN_ONCE(1, "\"idle=mwait\" will be removed in 2012\n");
612 } else if (!strcmp(str, "halt")) { 535 } else if (!strcmp(str, "halt")) {
613 /* 536 /*
614 * When the boot option of idle=halt is added, halt is 537 * When the boot option of idle=halt is added, halt is