[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86/mwait_idle: remove assumption of one C-state per MWAIT flag



commit 3642ba0f692cfa9319fdeca82268238daba23794
Author:     Len Brown <len.brown@xxxxxxxxx>
AuthorDate: Fri Aug 30 10:58:21 2013 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Aug 30 10:58:21 2013 +0200

    x86/mwait_idle: remove assumption of one C-state per MWAIT flag
    
    Remove the assumption that cstate_tables are indexed by MWAIT flag
    values. Each entry identifies itself via its own flags value. This
    change is needed to support multiple states that share the same MWAIT
    flags.
    
    Note that this can have an effect on what state is described by 'N' on
    cmdline max_cstate=N on some systems.
    
    Signed-off-by: Len Brown <len.brown@xxxxxxxxx>
    
    Avoided the effect of changing the meaning of "max_cstate=".
    Drop MWAIT_MAX_NUM_CSTATES (done differently in a prior patch on
    Linux).
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Keir Fraser <keir@xxxxxxx>
---
 xen/arch/x86/cpu/mwait-idle.c |  106 +++++++++++++++++++---------------------
 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 e0c9707..ccfa750 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 3ad3d9c..ba9c0ea 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
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.