Skip to content

Commit a1228f0

Browse files
committed
Merge tag 'pm-6.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix a nasty hibernation regression introduced during the 6.16 cycle, an issue related to energy model management occurring on Intel hybrid systems where some CPUs are offline to start with, and two regressions in the amd-pstate driver: - Restore a pm_restrict_gfp_mask() call in hibernation_snapshot() that was removed incorrectly during the 6.16 development cycle (Rafael Wysocki) - Introduce a function for registering a perf domain without triggering a system-wide CPU capacity update and make the intel_pstate driver use it to avoid reocurring unsuccessful attempts to update capacities of all CPUs in the system (Rafael Wysocki) - Fix setting of CPPC.min_perf in the active mode with performance governor in the amd-pstate driver to restore its expected behavior changed recently (Gautham Shenoy) - Avoid mistakenly setting EPP to 0 in the amd-pstate driver after system resume as a result of recent code changes (Mario Limonciello)" * tag 'pm-6.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM: hibernate: Restrict GFP mask in hibernation_snapshot() PM: EM: Add function for registering a PD without capacity update cpufreq/amd-pstate: Fix a regression leading to EPP 0 after resume cpufreq/amd-pstate: Fix setting of CPPC.min_perf in active mode for performance governor
2 parents b10c31b + bddce1c commit a1228f0

File tree

5 files changed

+49
-14
lines changed

5 files changed

+49
-14
lines changed

drivers/cpufreq/amd-pstate.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,13 +1554,15 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
15541554
pr_debug("CPU %d exiting\n", policy->cpu);
15551555
}
15561556

1557-
static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
1557+
static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy, bool policy_change)
15581558
{
15591559
struct amd_cpudata *cpudata = policy->driver_data;
15601560
union perf_cached perf;
15611561
u8 epp;
15621562

1563-
if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
1563+
if (policy_change ||
1564+
policy->min != cpudata->min_limit_freq ||
1565+
policy->max != cpudata->max_limit_freq)
15641566
amd_pstate_update_min_max_limit(policy);
15651567

15661568
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
@@ -1584,7 +1586,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
15841586

15851587
cpudata->policy = policy->policy;
15861588

1587-
ret = amd_pstate_epp_update_limit(policy);
1589+
ret = amd_pstate_epp_update_limit(policy, true);
15881590
if (ret)
15891591
return ret;
15901592

@@ -1626,13 +1628,14 @@ static int amd_pstate_suspend(struct cpufreq_policy *policy)
16261628
* min_perf value across kexec reboots. If this CPU is just resumed back without kexec,
16271629
* the limits, epp and desired perf will get reset to the cached values in cpudata struct
16281630
*/
1629-
ret = amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
1631+
ret = amd_pstate_update_perf(policy, perf.bios_min_perf,
1632+
FIELD_GET(AMD_CPPC_DES_PERF_MASK, cpudata->cppc_req_cached),
1633+
FIELD_GET(AMD_CPPC_MAX_PERF_MASK, cpudata->cppc_req_cached),
1634+
FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached),
1635+
false);
16301636
if (ret)
16311637
return ret;
16321638

1633-
/* invalidate to ensure it's rewritten during resume */
1634-
cpudata->cppc_req_cached = 0;
1635-
16361639
/* set this flag to avoid setting core offline*/
16371640
cpudata->suspended = true;
16381641

@@ -1658,7 +1661,7 @@ static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
16581661
int ret;
16591662

16601663
/* enable amd pstate from suspend state*/
1661-
ret = amd_pstate_epp_update_limit(policy);
1664+
ret = amd_pstate_epp_update_limit(policy, false);
16621665
if (ret)
16631666
return ret;
16641667

drivers/cpufreq/intel_pstate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,8 +1034,8 @@ static bool hybrid_register_perf_domain(unsigned int cpu)
10341034
if (!cpu_dev)
10351035
return false;
10361036

1037-
if (em_dev_register_perf_domain(cpu_dev, HYBRID_EM_STATE_COUNT, &cb,
1038-
cpumask_of(cpu), false))
1037+
if (em_dev_register_pd_no_update(cpu_dev, HYBRID_EM_STATE_COUNT, &cb,
1038+
cpumask_of(cpu), false))
10391039
return false;
10401040

10411041
cpudata->pd_registered = true;

include/linux/energy_model.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ int em_dev_update_perf_domain(struct device *dev,
171171
int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
172172
const struct em_data_callback *cb,
173173
const cpumask_t *cpus, bool microwatts);
174+
int em_dev_register_pd_no_update(struct device *dev, unsigned int nr_states,
175+
const struct em_data_callback *cb,
176+
const cpumask_t *cpus, bool microwatts);
174177
void em_dev_unregister_perf_domain(struct device *dev);
175178
struct em_perf_table *em_table_alloc(struct em_perf_domain *pd);
176179
void em_table_free(struct em_perf_table *table);
@@ -350,6 +353,13 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
350353
{
351354
return -EINVAL;
352355
}
356+
static inline
357+
int em_dev_register_pd_no_update(struct device *dev, unsigned int nr_states,
358+
const struct em_data_callback *cb,
359+
const cpumask_t *cpus, bool microwatts)
360+
{
361+
return -EINVAL;
362+
}
353363
static inline void em_dev_unregister_perf_domain(struct device *dev)
354364
{
355365
}

kernel/power/energy_model.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,30 @@ EXPORT_SYMBOL_GPL(em_cpu_get);
552552
int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
553553
const struct em_data_callback *cb,
554554
const cpumask_t *cpus, bool microwatts)
555+
{
556+
int ret = em_dev_register_pd_no_update(dev, nr_states, cb, cpus, microwatts);
557+
558+
if (_is_cpu_device(dev))
559+
em_check_capacity_update();
560+
561+
return ret;
562+
}
563+
EXPORT_SYMBOL_GPL(em_dev_register_perf_domain);
564+
565+
/**
566+
* em_dev_register_pd_no_update() - Register a perf domain for a device
567+
* @dev : Device to register the PD for
568+
* @nr_states : Number of performance states in the new PD
569+
* @cb : Callback functions for populating the energy model
570+
* @cpus : CPUs to include in the new PD (mandatory if @dev is a CPU device)
571+
* @microwatts : Whether or not the power values in the EM will be in uW
572+
*
573+
* Like em_dev_register_perf_domain(), but does not trigger a CPU capacity
574+
* update after registering the PD, even if @dev is a CPU device.
575+
*/
576+
int em_dev_register_pd_no_update(struct device *dev, unsigned int nr_states,
577+
const struct em_data_callback *cb,
578+
const cpumask_t *cpus, bool microwatts)
555579
{
556580
struct em_perf_table *em_table;
557581
unsigned long cap, prev_cap = 0;
@@ -636,12 +660,9 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
636660
unlock:
637661
mutex_unlock(&em_pd_mutex);
638662

639-
if (_is_cpu_device(dev))
640-
em_check_capacity_update();
641-
642663
return ret;
643664
}
644-
EXPORT_SYMBOL_GPL(em_dev_register_perf_domain);
665+
EXPORT_SYMBOL_GPL(em_dev_register_pd_no_update);
645666

646667
/**
647668
* em_dev_unregister_perf_domain() - Unregister Energy Model (EM) for a device

kernel/power/hibernate.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ int hibernation_snapshot(int platform_mode)
449449
shrink_shmem_memory();
450450

451451
console_suspend_all();
452+
pm_restrict_gfp_mask();
452453

453454
error = dpm_suspend(PMSG_FREEZE);
454455

0 commit comments

Comments
 (0)