Skip to content

Commit 9beb40b

Browse files
dedekindMahmoud Adam
authored andcommitted
intel_idle: Fix the 'preferred_cstates' module parameter
Problem description. When user boots kernel up with the 'intel_idle.preferred_cstates=4' option, we enable C1E and disable C1 states on Sapphire Rapids Xeon (SPR). In order for C1E to work on SPR, we have to enable the C1E promotion bit on all CPUs. However, we enable it only on one CPU. Fix description. The 'intel_idle' driver already has the infrastructure for disabling C1E promotion on every CPU. This patch uses the same infrastructure for enabling C1E promotion on every CPU. It changes the boolean 'disable_promotion_to_c1e' variable to a tri-state 'c1e_promotion' variable. Tested on a 2-socket SPR system. I verified the following combinations: * C1E promotion enabled and disabled in BIOS. * Booted with and without the 'intel_idle.preferred_cstates=4' kernel argument. In all 4 cases C1E promotion was correctly set on all CPUs. Also tested on an old Broadwell system, just to make sure it does not cause a regression. C1E promotion was correctly disabled on that system, both C1 and C1E were exposed (as expected). Fixes: da0e58c ("intel_idle: add 'preferred_cstates' module argument") Reported-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> [ rjw: Minor changelog edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent bbc8151 commit 9beb40b

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

drivers/idle/intel_idle.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ static unsigned int preferred_states_mask;
7272
static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
7373

7474
static unsigned long auto_demotion_disable_flags;
75-
static bool disable_promotion_to_c1e;
75+
76+
static enum {
77+
C1E_PROMOTION_PRESERVE,
78+
C1E_PROMOTION_ENABLE,
79+
C1E_PROMOTION_DISABLE
80+
} c1e_promotion = C1E_PROMOTION_PRESERVE;
7681

7782
struct idle_cpu {
7883
struct cpuidle_state *state_table;
@@ -1422,8 +1427,6 @@ static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
14221427
static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
14231428
#endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */
14241429

1425-
static void c1e_promotion_enable(void);
1426-
14271430
/**
14281431
* ivt_idle_state_table_update - Tune the idle states table for Ivy Town.
14291432
*
@@ -1611,8 +1614,7 @@ static void __init spr_idle_state_table_update(void)
16111614
spr_cstates[1].flags &= ~CPUIDLE_FLAG_UNUSABLE;
16121615

16131616
/* Enable C1E using the "C1E promotion" bit. */
1614-
c1e_promotion_enable();
1615-
disable_promotion_to_c1e = false;
1617+
c1e_promotion = C1E_PROMOTION_ENABLE;
16161618
}
16171619

16181620
/*
@@ -1783,7 +1785,9 @@ static int intel_idle_cpu_init(unsigned int cpu)
17831785
if (auto_demotion_disable_flags)
17841786
auto_demotion_disable();
17851787

1786-
if (disable_promotion_to_c1e)
1788+
if (c1e_promotion == C1E_PROMOTION_ENABLE)
1789+
c1e_promotion_enable();
1790+
else if (c1e_promotion == C1E_PROMOTION_DISABLE)
17871791
c1e_promotion_disable();
17881792

17891793
return 0;
@@ -1862,7 +1866,8 @@ static int __init intel_idle_init(void)
18621866
if (icpu) {
18631867
cpuidle_state_table = icpu->state_table;
18641868
auto_demotion_disable_flags = icpu->auto_demotion_disable_flags;
1865-
disable_promotion_to_c1e = icpu->disable_promotion_to_c1e;
1869+
if (icpu->disable_promotion_to_c1e)
1870+
c1e_promotion = C1E_PROMOTION_DISABLE;
18661871
if (icpu->use_acpi || force_use_acpi)
18671872
intel_idle_acpi_cst_extract();
18681873
} else if (!intel_idle_acpi_cst_extract()) {

0 commit comments

Comments
 (0)