aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process.c
diff options
context:
space:
mode:
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