[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 2/4] x86: Allow limiting the max C-state sub-state
Allow limiting the max C-state sub-state by appending to the max_cstate command-line parameter. E.g. max_cstate=1,0 The limit only applies to the highest legal C-state. For example: max_cstate = 1, max_csubstate = 0 ==> C0, C1 okay, but not C1E max_cstate = 1, max_csubstate = 1 ==> C0, C1 and C1E okay, but not C2 max_cstate = 2, max_csubstate = 0 ==> C0, C1, C1E, C2 okay, but not C3 max_cstate = 2, max_csubstate = 1 ==> C0, C1, C1E, C2 okay, but not C3 Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> --- docs/misc/xen-command-line.markdown | 8 +++++++- xen/arch/x86/acpi/cpu_idle.c | 20 +++++++++++++++++--- xen/arch/x86/cpu/mwait-idle.c | 4 +++- xen/include/xen/acpi.h | 16 ++++++++++++---- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown index a7ac53d..1122f2c 100644 --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -692,7 +692,13 @@ so the crash kernel may find find them. Should be used in combination with **crashinfo_maxaddr**. ### max\_cstate -> `= <integer>` +> `= <cstate>[,<substate>]` + +`cstate` is an integer which limits the maximum C-state that Xen uses. + +`substate` is an integer which limits the maximum sub C-state that Xen +uses. The limit only applies to the highest legal C-state. + ### max\_gsi\_irqs > `= <integer>` diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index b05fb39..a16c0b5 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -105,7 +105,16 @@ static uint64_t (*__read_mostly tick_to_ns)(uint64_t) = acpi_pm_tick_to_ns; void (*__read_mostly pm_idle_save)(void); unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER - 1; -integer_param("max_cstate", max_cstate); +unsigned int max_csubstate __read_mostly = UINT_MAX; + +static void __init parse_cstate(const char *s) +{ + max_cstate = simple_strtoul(s, &s, 0); + if ( *s == ',' ) + max_csubstate = simple_strtoul(s + 1, &s, 0); +} +custom_param("max_cstate", parse_cstate); + static bool_t __read_mostly local_apic_timer_c2_ok; boolean_param("lapic_timer_c2_ok", local_apic_timer_c2_ok); @@ -240,6 +249,7 @@ static void print_acpi_power(uint32_t cpu, struct acpi_processor_power *power) last_state_idx = power->last_state ? power->last_state->idx : -1; printk("active state:\t\tC%d\n", last_state_idx); printk("max_cstate:\t\tC%d\n", max_cstate); + printk("max_csubstate:\t\t%u\n", max_csubstate); printk("states:\n"); for ( i = 1; i < power->count; i++ ) @@ -484,8 +494,12 @@ static void acpi_processor_idle(void) if ( cx->type == ACPI_STATE_C3 && power->flags.bm_check && acpi_idle_bm_check() ) cx = power->safe_state; - if ( cx->idx > max_cstate ) - cx = &power->states[max_cstate]; + while ( ( cx->idx > max_cstate || + ( cx->entry_method == ACPI_CSTATE_EM_FFH && + cx->idx == max_cstate && + ( cx->address & MWAIT_SUBSTATE_MASK ) > max_csubstate ) ) && + next_state-- ); + cx = &power->states[next_state]; menu_get_trace_data(&exp, &pred); } if ( !cx ) diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c index 38172e5..3bad6d8 100644 --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -330,7 +330,9 @@ static void mwait_idle(void) (next_state = cpuidle_current_governor->select(power)) > 0) { do { cx = &power->states[next_state]; - } while (cx->type > max_cstate && --next_state); + } while ((cx->type > max_cstate || (cx->type == max_cstate && + MWAIT_HINT2SUBSTATE(cx->address) > max_csubstate)) && + --next_state); if (!next_state) cx = NULL; menu_get_trace_data(&exp, &pred); diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index aedec65..c3925bc 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -123,13 +123,21 @@ void acpi_unregister_gsi (u32 gsi); #ifdef CONFIG_ACPI_CSTATE /* - * Set highest legal C-state - * 0: C0 okay, but not C1 - * 1: C1 okay, but not C2 - * 2: C2 okay, but not C3 etc. + * max_cstate sets the highest legal C-state. + * max_cstate = 0: C0 okay, but not C1 + * max_cstate = 1: C1 okay, but not C2 + * max_cstate = 2: C2 okay, but not C3 etc. + + * max_csubstate sets the highest legal C-state sub-state. Only applies to the + * highest legal C-state. + * max_cstate = 1, max_csubstate = 0 ==> C0, C1 okay, but not C1E + * max_cstate = 1, max_csubstate = 1 ==> C0, C1 and C1E okay, but not C2 + * max_cstate = 2, max_csubstate = 0 ==> C0, C1, C1E, C2 okay, but not C3 + * max_cstate = 2, max_csubstate = 1 ==> C0, C1, C1E, C2 okay, but not C3 */ extern unsigned int max_cstate; +extern unsigned int max_csubstate; static inline unsigned int acpi_get_cstate_limit(void) { -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |