aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2013-08-30 10:59:09 +0200
committerJan Beulich <jbeulich@suse.com>2013-08-30 10:59:09 +0200
commit91413b51963127d435cfba38e382e81188527ef5 (patch)
tree442fdbcd3fdd3df564a01957a6dded995ef1e1d1 /xen
parent3642ba0f692cfa9319fdeca82268238daba23794 (diff)
downloadxen-91413b51963127d435cfba38e382e81188527ef5.tar.gz
xen-91413b51963127d435cfba38e382e81188527ef5.tar.bz2
xen-91413b51963127d435cfba38e382e81188527ef5.zip
x86/mwait_idle: export both C1 and C1E
Here we disable HW promotion of C1 to C1E and export both C1 and C1E as distinct C-states. This allows a cpuidle governor to choose a lower latency C-state than C1E when necessary to satisfy performance and QOS constraints -- and still save power versus polling. This also corrects the erroneous latency previously reported for C1E -- it is 10usec, not 1usec. Signed-off-by: Len Brown <len.brown@intel.com> Avoided the effect of changing the meaning of "max_cstate=". Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen')
-rw-r--r--xen/arch/x86/cpu/mwait-idle.c51
-rw-r--r--xen/include/asm-x86/msr-index.h2
2 files changed, 48 insertions, 5 deletions
diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c
index ccfa750908..879963215f 100644
--- a/xen/arch/x86/cpu/mwait-idle.c
+++ b/xen/arch/x86/cpu/mwait-idle.c
@@ -88,6 +88,7 @@ struct idle_cpu {
* Indicate which enable bits to clear here.
*/
unsigned long auto_demotion_disable_flags;
+ bool_t disable_promotion_to_c1e;
};
static const struct idle_cpu *icpu;
@@ -132,6 +133,12 @@ static const struct cpuidle_state nehalem_cstates[] = {
.target_residency = 6,
},
{
+ .name = "C1E-NHM",
+ .flags = MWAIT2flg(0x01),
+ .exit_latency = 10,
+ .target_residency = 20,
+ },
+ {
.name = "C3-NHM",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 20,
@@ -150,8 +157,14 @@ static const struct cpuidle_state snb_cstates[] = {
{
.name = "C1-SNB",
.flags = MWAIT2flg(0x00),
- .exit_latency = 1,
- .target_residency = 1,
+ .exit_latency = 2,
+ .target_residency = 2,
+ },
+ {
+ .name = "C1E-SNB",
+ .flags = MWAIT2flg(0x01),
+ .exit_latency = 10,
+ .target_residency = 20,
},
{
.name = "C3-SNB",
@@ -182,6 +195,12 @@ static const struct cpuidle_state ivb_cstates[] = {
.target_residency = 1,
},
{
+ .name = "C1E-IVB",
+ .flags = MWAIT2flg(0x01),
+ .exit_latency = 10,
+ .target_residency = 20,
+ },
+ {
.name = "C3-IVB",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
@@ -210,6 +229,12 @@ static const struct cpuidle_state hsw_cstates[] = {
.target_residency = 2,
},
{
+ .name = "C1E-HSW",
+ .flags = MWAIT2flg(0x01),
+ .exit_latency = 10,
+ .target_residency = 20,
+ },
+ {
.name = "C3-HSW",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 33,
@@ -232,10 +257,10 @@ static const struct cpuidle_state hsw_cstates[] = {
static const struct cpuidle_state atom_cstates[] = {
{
- .name = "C1-ATM",
+ .name = "C1E-ATM",
.flags = MWAIT2flg(0x00),
- .exit_latency = 1,
- .target_residency = 4,
+ .exit_latency = 10,
+ .target_residency = 20,
},
{
.name = "C2-ATM",
@@ -354,9 +379,19 @@ static void auto_demotion_disable(void *dummy)
wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
}
+static void c1e_promotion_disable(void *dummy)
+{
+ u64 msr_bits;
+
+ rdmsrl(MSR_IA32_POWER_CTL, msr_bits);
+ msr_bits &= ~0x2;
+ wrmsrl(MSR_IA32_POWER_CTL, msr_bits);
+}
+
static const struct idle_cpu idle_cpu_nehalem = {
.state_table = nehalem_cstates,
.auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
+ .disable_promotion_to_c1e = 1,
};
static const struct idle_cpu idle_cpu_atom = {
@@ -370,14 +405,17 @@ static const struct idle_cpu idle_cpu_lincroft = {
static const struct idle_cpu idle_cpu_snb = {
.state_table = snb_cstates,
+ .disable_promotion_to_c1e = 1,
};
static const struct idle_cpu idle_cpu_ivb = {
.state_table = ivb_cstates,
+ .disable_promotion_to_c1e = 1,
};
static const struct idle_cpu idle_cpu_hsw = {
.state_table = hsw_cstates,
+ .disable_promotion_to_c1e = 1,
};
#define ICPU(model, cpu) { 6, model, &idle_cpu_##cpu }
@@ -520,6 +558,9 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb,
if (icpu->auto_demotion_disable_flags)
on_selected_cpus(cpumask_of(cpu), auto_demotion_disable, NULL, 1);
+ if (icpu->disable_promotion_to_c1e)
+ on_selected_cpus(cpumask_of(cpu), c1e_promotion_disable, NULL, 1);
+
return NOTIFY_DONE;
}
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index 03cb00ecaf..e597a28a23 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -83,6 +83,8 @@
#define MSR_IA32_LASTINTFROMIP 0x000001dd
#define MSR_IA32_LASTINTTOIP 0x000001de
+#define MSR_IA32_POWER_CTL 0x000001fc
+
#define MSR_IA32_MTRR_PHYSBASE0 0x00000200
#define MSR_IA32_MTRR_PHYSMASK0 0x00000201
#define MSR_IA32_MTRR_PHYSBASE1 0x00000202