mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	intel_idle: export both C1 and C1E
Here we disable HW promotion of C1 to C1E and export both C1 and C1E and 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. Note that if you use "intel_idle.max_cstate=N", then you must increment N by 1 to get the same behavior after this change. Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
		
							parent
							
								
									e022e7eb90
								
							
						
					
					
						commit
						32e9518005
					
				
					 1 changed files with 49 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -90,6 +90,7 @@ struct idle_cpu {
 | 
			
		|||
	 * Indicate which enable bits to clear here.
 | 
			
		||||
	 */
 | 
			
		||||
	unsigned long auto_demotion_disable_flags;
 | 
			
		||||
	bool disable_promotion_to_c1e;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct idle_cpu *icpu;
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +132,13 @@ static struct cpuidle_state nehalem_cstates[CPUIDLE_STATE_MAX] = {
 | 
			
		|||
		.exit_latency = 3,
 | 
			
		||||
		.target_residency = 6,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C1E-NHM",
 | 
			
		||||
		.desc = "MWAIT 0x01",
 | 
			
		||||
		.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
 | 
			
		||||
		.exit_latency = 10,
 | 
			
		||||
		.target_residency = 20,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C3-NHM",
 | 
			
		||||
		.desc = "MWAIT 0x10",
 | 
			
		||||
| 
						 | 
				
			
			@ -154,8 +162,15 @@ static struct cpuidle_state snb_cstates[CPUIDLE_STATE_MAX] = {
 | 
			
		|||
		.name = "C1-SNB",
 | 
			
		||||
		.desc = "MWAIT 0x00",
 | 
			
		||||
		.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
 | 
			
		||||
		.exit_latency = 1,
 | 
			
		||||
		.target_residency = 1,
 | 
			
		||||
		.exit_latency = 2,
 | 
			
		||||
		.target_residency = 2,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C1E-SNB",
 | 
			
		||||
		.desc = "MWAIT 0x01",
 | 
			
		||||
		.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
 | 
			
		||||
		.exit_latency = 10,
 | 
			
		||||
		.target_residency = 20,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C3-SNB",
 | 
			
		||||
| 
						 | 
				
			
			@ -190,6 +205,13 @@ static struct cpuidle_state ivb_cstates[CPUIDLE_STATE_MAX] = {
 | 
			
		|||
		.exit_latency = 1,
 | 
			
		||||
		.target_residency = 1,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C1E-IVB",
 | 
			
		||||
		.desc = "MWAIT 0x01",
 | 
			
		||||
		.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
 | 
			
		||||
		.exit_latency = 10,
 | 
			
		||||
		.target_residency = 20,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C3-IVB",
 | 
			
		||||
		.desc = "MWAIT 0x10",
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +245,13 @@ static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = {
 | 
			
		|||
		.exit_latency = 2,
 | 
			
		||||
		.target_residency = 2,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C1E-HSW",
 | 
			
		||||
		.desc = "MWAIT 0x01",
 | 
			
		||||
		.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
 | 
			
		||||
		.exit_latency = 10,
 | 
			
		||||
		.target_residency = 20,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C3-HSW",
 | 
			
		||||
		.desc = "MWAIT 0x10",
 | 
			
		||||
| 
						 | 
				
			
			@ -250,11 +279,11 @@ static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = {
 | 
			
		|||
 | 
			
		||||
static struct cpuidle_state atom_cstates[CPUIDLE_STATE_MAX] = {
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C1-ATM",
 | 
			
		||||
		.name = "C1E-ATM",
 | 
			
		||||
		.desc = "MWAIT 0x00",
 | 
			
		||||
		.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
 | 
			
		||||
		.exit_latency = 1,
 | 
			
		||||
		.target_residency = 4,
 | 
			
		||||
		.exit_latency = 10,
 | 
			
		||||
		.target_residency = 20,
 | 
			
		||||
		.enter = &intel_idle },
 | 
			
		||||
	{
 | 
			
		||||
		.name = "C2-ATM",
 | 
			
		||||
| 
						 | 
				
			
			@ -377,10 +406,19 @@ static void auto_demotion_disable(void *dummy)
 | 
			
		|||
	msr_bits &= ~(icpu->auto_demotion_disable_flags);
 | 
			
		||||
	wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
 | 
			
		||||
}
 | 
			
		||||
static void c1e_promotion_disable(void *dummy)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long long 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 = true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct idle_cpu idle_cpu_atom = {
 | 
			
		||||
| 
						 | 
				
			
			@ -394,14 +432,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 = true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct idle_cpu idle_cpu_ivb = {
 | 
			
		||||
	.state_table = ivb_cstates,
 | 
			
		||||
	.disable_promotion_to_c1e = true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct idle_cpu idle_cpu_hsw = {
 | 
			
		||||
	.state_table = hsw_cstates,
 | 
			
		||||
	.disable_promotion_to_c1e = true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define ICPU(model, cpu) \
 | 
			
		||||
| 
						 | 
				
			
			@ -544,6 +585,9 @@ static int intel_idle_cpuidle_driver_init(void)
 | 
			
		|||
	if (icpu->auto_demotion_disable_flags)
 | 
			
		||||
		on_each_cpu(auto_demotion_disable, NULL, 1);
 | 
			
		||||
 | 
			
		||||
	if (icpu->disable_promotion_to_c1e)	/* each-cpu is redundant */
 | 
			
		||||
		on_each_cpu(c1e_promotion_disable, NULL, 1);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue