[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 1/3] mwait-idle: add support for using halt
From: Brian Woods <brian.woods@xxxxxxx> Some AMD processors can use a mixture of mwait and halt for accessing various c-states. In preparation for adding support for AMD processors, update the mwait-idle driver to optionally use halt. Signed-off-by: Brian Woods <brian.woods@xxxxxxx> --- xen/arch/x86/acpi/cpu_idle.c | 2 +- xen/arch/x86/cpu/mwait-idle.c | 19 +++++++++++++------ xen/include/asm-x86/cpuidle.h | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index 654de24f40..b45824d343 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -439,7 +439,7 @@ static void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) mwait_idle_with_hints(cx->address, MWAIT_ECX_INTERRUPT_BREAK); } -static void acpi_idle_do_entry(struct acpi_processor_cx *cx) +void acpi_idle_do_entry(struct acpi_processor_cx *cx) { struct cpu_info *info = get_cpu_info(); diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c index f89c52f256..b9c7f75882 100644 --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -103,6 +103,11 @@ static const struct cpuidle_state { #define CPUIDLE_FLAG_DISABLED 0x1 /* + * On certain AMD families that support mwait, only c1 can be reached by + * mwait and to reach c2, halt has to be used. + */ +#define CPUIDLE_FLAG_USE_HALT 0x2 +/* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. * If this flag is set, SW flushes the TLB, so even if the @@ -784,7 +789,7 @@ static void mwait_idle(void) update_last_cx_stat(power, cx, before); if (cpu_is_haltable(cpu)) - mwait_idle_with_hints(eax, MWAIT_ECX_INTERRUPT_BREAK); + acpi_idle_do_entry(cx); after = cpuidle_get_tick(); @@ -1184,8 +1189,9 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb, for (cstate = 0; cpuidle_state_table[cstate].target_residency; ++cstate) { unsigned int num_substates, hint, state; struct acpi_processor_cx *cx; + const unsigned int cflags = cpuidle_state_table[cstate].flags; - hint = flg2MWAIT(cpuidle_state_table[cstate].flags); + hint = flg2MWAIT(cflags); state = MWAIT_HINT2CSTATE(hint) + 1; if (state > max_cstate) { @@ -1196,13 +1202,13 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb, /* Number of sub-states for this state in CPUID.MWAIT. */ num_substates = (mwait_substates >> (state * 4)) & MWAIT_SUBSTATE_MASK; + /* If NO sub-states for this state in CPUID, skip it. */ - if (num_substates == 0) + if (num_substates == 0 && !(cflags & CPUIDLE_FLAG_USE_HALT)) continue; /* if state marked as disabled, skip it */ - if (cpuidle_state_table[cstate].flags & - CPUIDLE_FLAG_DISABLED) { + if (cflags & CPUIDLE_FLAG_DISABLED) { printk(XENLOG_DEBUG PREFIX "state %s is disabled", cpuidle_state_table[cstate].name); continue; @@ -1221,7 +1227,8 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb, cx = dev->states + dev->count; cx->type = state; cx->address = hint; - cx->entry_method = ACPI_CSTATE_EM_FFH; + cx->entry_method = cflags & CPUIDLE_FLAG_USE_HALT ? + ACPI_CSTATE_EM_HALT : ACPI_CSTATE_EM_FFH; cx->latency = cpuidle_state_table[cstate].exit_latency; cx->target_residency = cpuidle_state_table[cstate].target_residency; diff --git a/xen/include/asm-x86/cpuidle.h b/xen/include/asm-x86/cpuidle.h index 08da01803f..33c8cf1593 100644 --- a/xen/include/asm-x86/cpuidle.h +++ b/xen/include/asm-x86/cpuidle.h @@ -18,6 +18,7 @@ extern uint64_t (*cpuidle_get_tick)(void); int mwait_idle_init(struct notifier_block *); int cpuidle_init_cpu(unsigned int cpu); +void acpi_idle_do_entry(struct acpi_processor_cx *cx); void default_dead_idle(void); void acpi_dead_idle(void); void trace_exit_reason(u32 *irq_traced); -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |