diff options
-rw-r--r-- | xen/arch/x86/cpu/mwait-idle.c | 106 | ||||
-rw-r--r-- | xen/include/asm-x86/mwait.h | 1 |
2 files changed, 50 insertions, 57 deletions
diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c index e0c97079be..ccfa750908 100644 --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -116,146 +116,146 @@ static const struct cpuidle_state { */ #define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) #define MWAIT2flg(eax) ((eax & 0xFF) << 24) +#define MWAIT_HINT2CSTATE(hint) (((hint) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) +#define MWAIT_HINT2SUBSTATE(hint) ((hint) & MWAIT_CSTATE_MASK) /* * States are indexed by the cstate number, * which is also the index into the MWAIT hint array. * Thus C0 is a dummy. */ -static const struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ +static const struct cpuidle_state nehalem_cstates[] = { + { .name = "C1-NHM", .flags = MWAIT2flg(0x00), .exit_latency = 3, .target_residency = 6, }, - { /* MWAIT C2 */ + { .name = "C3-NHM", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 20, .target_residency = 80, }, - { /* MWAIT C3 */ + { .name = "C6-NHM", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 200, .target_residency = 800, - } + }, + {} }; -static const struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ +static const struct cpuidle_state snb_cstates[] = { + { .name = "C1-SNB", .flags = MWAIT2flg(0x00), .exit_latency = 1, .target_residency = 1, }, - { /* MWAIT C2 */ + { .name = "C3-SNB", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 80, .target_residency = 211, }, - { /* MWAIT C3 */ + { .name = "C6-SNB", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 104, .target_residency = 345, }, - { /* MWAIT C4 */ + { .name = "C7-SNB", .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 109, .target_residency = 345, - } + }, + {} }; -static const struct cpuidle_state ivb_cstates[MWAIT_MAX_NUM_CSTATES] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ +static const struct cpuidle_state ivb_cstates[] = { + { .name = "C1-IVB", .flags = MWAIT2flg(0x00), .exit_latency = 1, .target_residency = 1, }, - { /* MWAIT C2 */ + { .name = "C3-IVB", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 59, .target_residency = 156, }, - { /* MWAIT C3 */ + { .name = "C6-IVB", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 80, .target_residency = 300, }, - { /* MWAIT C4 */ + { .name = "C7-IVB", .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 87, .target_residency = 300, - } + }, + {} }; -static const struct cpuidle_state hsw_cstates[MWAIT_MAX_NUM_CSTATES] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ +static const struct cpuidle_state hsw_cstates[] = { + { .name = "C1-HSW", .flags = MWAIT2flg(0x00), .exit_latency = 2, .target_residency = 2, }, - { /* MWAIT C2 */ + { .name = "C3-HSW", .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 33, .target_residency = 100, }, - { /* MWAIT C3 */ + { .name = "C6-HSW", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 133, .target_residency = 400, }, - { /* MWAIT C4 */ + { .name = "C7s-HSW", .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 166, .target_residency = 500, }, + {} }; -static const struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { - { /* MWAIT C0 */ }, - { /* MWAIT C1 */ +static const struct cpuidle_state atom_cstates[] = { + { .name = "C1-ATM", .flags = MWAIT2flg(0x00), .exit_latency = 1, .target_residency = 4, }, - { /* MWAIT C2 */ + { .name = "C2-ATM", .flags = MWAIT2flg(0x10), .exit_latency = 20, .target_residency = 80, }, - { /* MWAIT C3 */ }, - { /* MWAIT C4 */ + { .name = "C4-ATM", .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 100, .target_residency = 400, }, - { /* MWAIT C5 */ }, - { /* MWAIT C6 */ + { .name = "C6-ATM", .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 140, .target_residency = 560, - } + }, + {} }; static void mwait_idle(void) @@ -476,29 +476,25 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb, dev->count = 1; - for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { - unsigned int num_substates; + for (cstate = 0; cpuidle_state_table[cstate].target_residency; ++cstate) { + unsigned int num_substates, hint, state, substate; struct acpi_processor_cx *cx; - if (cstate > max_cstate) { + hint = flg2MWAIT(cpuidle_state_table[cstate].flags); + state = MWAIT_HINT2CSTATE(hint) + 1; + substate = MWAIT_HINT2SUBSTATE(hint); + + if (state > max_cstate) { printk(PREFIX "max C-state %u reached\n", max_cstate); break; } /* Does the state exist in CPUID.MWAIT? */ - num_substates = (mwait_substates >> (cstate * 4)) - & MWAIT_SUBSTATE_MASK; - if (!num_substates) - continue; - /* Is the state not enabled? */ - if (!cpuidle_state_table[cstate].target_residency) { - /* does the driver not know about the state? */ - if (!pm_idle_save && !*cpuidle_state_table[cstate].name) - pr_debug(PREFIX "unaware of family %#x model %#x MWAIT %u\n", - boot_cpu_data.x86, - boot_cpu_data.x86_model, cstate); + num_substates = (mwait_substates >> (state * 4)) + & MWAIT_SUBSTATE_MASK; + /* if sub-state in table is not enumerated by CPUID */ + if (substate >= num_substates) continue; - } if (dev->count >= ACPI_PROCESSOR_MAX_POWER) { printk(PREFIX "max C-state count of %u reached\n", @@ -506,15 +502,13 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb, break; } - if (cstate > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) { - if (pm_idle_save) - continue; + if (state > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC) && + !pm_idle_save) setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE); - } cx = dev->states + dev->count; - cx->type = cstate; - cx->address = flg2MWAIT(cpuidle_state_table[cstate].flags); + cx->type = state; + cx->address = hint; cx->entry_method = ACPI_CSTATE_EM_FFH; cx->latency = cpuidle_state_table[cstate].exit_latency; cx->target_residency = diff --git a/xen/include/asm-x86/mwait.h b/xen/include/asm-x86/mwait.h index 3ad3d9ca1d..ba9c0ea096 100644 --- a/xen/include/asm-x86/mwait.h +++ b/xen/include/asm-x86/mwait.h @@ -4,7 +4,6 @@ #define MWAIT_SUBSTATE_MASK 0xf #define MWAIT_CSTATE_MASK 0xf #define MWAIT_SUBSTATE_SIZE 4 -#define MWAIT_MAX_NUM_CSTATES 8 #define CPUID_MWAIT_LEAF 5 #define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1 |