Skip to content

Commit

Permalink
Merge tag 'pm-6.12-rc1-2' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/rafael/linux-pm

Pull power management fix from Rafael Wysocki:
 "Fix idle states enumeration in the intel_idle driver on platforms
  supporting multiple flavors of the C6 idle state (Artem Bityutskiy)"

* tag 'pm-6.12-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  intel_idle: fix ACPI _CST matching for newer Xeon platforms
  • Loading branch information
torvalds committed Sep 27, 2024
2 parents 12cc524 + 4c411cc commit ad46e8f
Showing 1 changed file with 29 additions and 8 deletions.
37 changes: 29 additions & 8 deletions drivers/idle/intel_idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ static unsigned int mwait_substates __initdata;
*/
#define CPUIDLE_FLAG_INIT_XSTATE BIT(17)

/*
* Ignore the sub-state when matching mwait hints between the ACPI _CST and
* custom tables.
*/
#define CPUIDLE_FLAG_PARTIAL_HINT_MATCH BIT(18)

/*
* MWAIT takes an 8-bit "hint" in EAX "suggesting"
* the C-state (top nibble) and sub-state (bottom nibble)
Expand Down Expand Up @@ -1043,7 +1049,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = {
.name = "C6",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_INIT_XSTATE,
CPUIDLE_FLAG_INIT_XSTATE |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 170,
.target_residency = 650,
.enter = &intel_idle,
Expand All @@ -1052,7 +1059,8 @@ static struct cpuidle_state gnr_cstates[] __initdata = {
.name = "C6P",
.desc = "MWAIT 0x21",
.flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_INIT_XSTATE,
CPUIDLE_FLAG_INIT_XSTATE |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 210,
.target_residency = 1000,
.enter = &intel_idle,
Expand Down Expand Up @@ -1354,15 +1362,17 @@ static struct cpuidle_state srf_cstates[] __initdata = {
{
.name = "C6S",
.desc = "MWAIT 0x22",
.flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED,
.flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 270,
.target_residency = 700,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C6SP",
.desc = "MWAIT 0x23",
.flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED,
.flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 310,
.target_residency = 900,
.enter = &intel_idle,
Expand Down Expand Up @@ -1744,7 +1754,7 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv)
}
}

static bool __init intel_idle_off_by_default(u32 mwait_hint)
static bool __init intel_idle_off_by_default(unsigned int flags, u32 mwait_hint)
{
int cstate, limit;

Expand All @@ -1761,7 +1771,15 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)
* the interesting states are ACPI_CSTATE_FFH.
*/
for (cstate = 1; cstate < limit; cstate++) {
if (acpi_state_table.states[cstate].address == mwait_hint)
u32 acpi_hint = acpi_state_table.states[cstate].address;
u32 table_hint = mwait_hint;

if (flags & CPUIDLE_FLAG_PARTIAL_HINT_MATCH) {
acpi_hint &= ~MWAIT_SUBSTATE_MASK;
table_hint &= ~MWAIT_SUBSTATE_MASK;
}

if (acpi_hint == table_hint)
return false;
}
return true;
Expand All @@ -1771,7 +1789,10 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)

static inline bool intel_idle_acpi_cst_extract(void) { return false; }
static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
static inline bool intel_idle_off_by_default(unsigned int flags, u32 mwait_hint)
{
return false;
}
#endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */

/**
Expand Down Expand Up @@ -2098,7 +2119,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)

if ((disabled_states_mask & BIT(drv->state_count)) ||
((icpu->use_acpi || force_use_acpi) &&
intel_idle_off_by_default(mwait_hint) &&
intel_idle_off_by_default(state->flags, mwait_hint) &&
!(state->flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
state->flags |= CPUIDLE_FLAG_OFF;

Expand Down

0 comments on commit ad46e8f

Please sign in to comment.