From: Jan Beulich Date: Mon, 22 Jul 2019 09:32:20 +0000 (+0200) Subject: x86/cpuidle: really use C1 for "urgent" CPUs X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=1bce2a94e929ddb0aa0ba8222cdaf0fd10ef1821;p=people%2Fdariof%2Fxen.git x86/cpuidle: really use C1 for "urgent" CPUs For one on recent AMD CPUs entering C1 (if available at all) requires use of MWAIT, while HLT (i.e. default_idle()) would put the processor into as deep as CC6. And then even on other vendors' CPUs we should avoid entering default_idle() when the intended state can be reached by using the active idle driver's facilities. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index 6896cfa875..ff945da7a1 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -582,12 +582,15 @@ static void acpi_processor_idle(void) u32 exp = 0, pred = 0; u32 irq_traced[4] = { 0 }; - if ( max_cstate > 0 && power && !sched_has_urgent_vcpu() && + if ( max_cstate > 0 && power && (next_state = cpuidle_current_governor->select(power)) > 0 ) { + unsigned int max_state = sched_has_urgent_vcpu() ? ACPI_STATE_C1 + : max_cstate; + do { cx = &power->states[next_state]; - } while ( cx->type > max_cstate && --next_state ); + } while ( cx->type > max_state && --next_state ); if ( next_state ) { if ( cx->type == ACPI_STATE_C3 && power->flags.bm_check && diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c index 361de1bb35..9e7c9bc28e 100644 --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -724,11 +724,14 @@ static void mwait_idle(void) u64 before, after; u32 exp = 0, pred = 0, irq_traced[4] = { 0 }; - if (max_cstate > 0 && power && !sched_has_urgent_vcpu() && + if (max_cstate > 0 && power && (next_state = cpuidle_current_governor->select(power)) > 0) { + unsigned int max_state = sched_has_urgent_vcpu() ? ACPI_STATE_C1 + : max_cstate; + do { cx = &power->states[next_state]; - } while (cx->type > max_cstate && --next_state); + } while (cx->type > max_state && --next_state); if (!next_state) cx = NULL; else if (tb_init_done)