Commit d813f421 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull power management fixes from Rafael Wysocki:
 "These fix two cpufreq issues, one in the core and one in the
  conservative governor, and two issues related to system sleep:

   - Restore the cpufreq core behavior changed inadvertently during the
     6.19 development cycle to call cpufreq_frequency_table_cpuinfo()
     for cpufreq policies getting re-initialized which ensures that
     policy->max and policy->cpuinfo_max_freq will be valid going
     forward (Viresh Kumar)

   - Adjust the cached requested frequency in the conservative cpufreq
     governor on policy limits changes to prevent it from becoming stale
     in some cases (Viresh Kumar)

   - Prevent pm_restore_gfp_mask() from triggering a WARN_ON() in some
     code paths in which it is legitimately called without invoking
     pm_restrict_gfp_mask() previously (Youngjun Park)

   - Update snapshot_write_finalize() to take trailing zero pages into
     account properly which prevents user space restore from failing
     subsequently in some cases (Alberto Garcia)"

* tag 'pm-7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  PM: sleep: Drop spurious WARN_ON() from pm_restore_gfp_mask()
  PM: hibernate: Drain trailing zero pages on userspace restore
  cpufreq: conservative: Reset requested_freq on limits change
  cpufreq: Don't skip cpufreq_frequency_table_cpuinfo()
parents 9c2b23a2 042f99c4
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -1427,12 +1427,9 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
		 * If there is a problem with its frequency table, take it
		 * offline and drop it.
		 */
		if (policy->freq_table_sorted != CPUFREQ_TABLE_SORTED_ASCENDING &&
		    policy->freq_table_sorted != CPUFREQ_TABLE_SORTED_DESCENDING) {
		ret = cpufreq_table_validate_and_sort(policy);
		if (ret)
			goto out_offline_policy;
		}

		/* related_cpus should at least include policy->cpus. */
		cpumask_copy(policy->related_cpus, policy->cpus);
+12 −0
Original line number Diff line number Diff line
@@ -313,6 +313,17 @@ static void cs_start(struct cpufreq_policy *policy)
	dbs_info->requested_freq = policy->cur;
}

static void cs_limits(struct cpufreq_policy *policy)
{
	struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);

	/*
	 * The limits have changed, so may have the current frequency. Reset
	 * requested_freq to avoid any unintended outcomes due to the mismatch.
	 */
	dbs_info->requested_freq = policy->cur;
}

static struct dbs_governor cs_governor = {
	.gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("conservative"),
	.kobj_type = { .default_groups = cs_groups },
@@ -322,6 +333,7 @@ static struct dbs_governor cs_governor = {
	.init = cs_init,
	.exit = cs_exit,
	.start = cs_start,
	.limits = cs_limits,
};

#define CPU_FREQ_GOV_CONSERVATIVE	(cs_governor.gov)
+3 −0
Original line number Diff line number Diff line
@@ -563,6 +563,7 @@ EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_stop);

void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy)
{
	struct dbs_governor *gov = dbs_governor_of(policy);
	struct policy_dbs_info *policy_dbs;

	/* Protect gov->gdbs_data against cpufreq_dbs_governor_exit() */
@@ -574,6 +575,8 @@ void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy)
	mutex_lock(&policy_dbs->update_mutex);
	cpufreq_policy_apply_limits(policy);
	gov_update_sample_delay(policy_dbs, 0);
	if (gov->limits)
		gov->limits(policy);
	mutex_unlock(&policy_dbs->update_mutex);

out:
+1 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ struct dbs_governor {
	int (*init)(struct dbs_data *dbs_data);
	void (*exit)(struct dbs_data *dbs_data);
	void (*start)(struct cpufreq_policy *policy);
	void (*limits)(struct cpufreq_policy *policy);
};

static inline struct dbs_governor *dbs_governor_of(struct cpufreq_policy *policy)
+4 −0
Original line number Diff line number Diff line
@@ -360,6 +360,10 @@ int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy)
	if (policy_has_boost_freq(policy))
		policy->boost_supported = true;

	if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING ||
	    policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_DESCENDING)
		return 0;

	return set_freq_table_sorted(policy);
}

Loading