Commit 1fa9970a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull power management fixes from Rafael Wysocki:
 "These fix a handful of issues in the amd-pstate driver, the airoha
  cpufreq driver build, a (recently added) possible NULL pointer
  dereference in the cpufreq code and a possible memory leak in the
  power capping subsystem:

   - Fix cpufreq_policy reference counting and prevent max_perf from
     going above the current limit in amd-pstate, and drop a redundant
     goto label from it (Dhananjay Ugwekar)

   - Prevent the per-policy boost_enabled flag in amd-pstate from
     getting out of sync with the actual state after boot failures
     (Lifeng Zheng)

   - Fix a recently added possible NULL pointer dereference in the
     cpufreq core (Aboorva Devarajan)

   - Fix a build issue related to CONFIG_OF and COMPILE_TEST
     dependencies in the airoha cpufreq driver (Arnd Bergmann)

   - Fix a possible memory leak in the power capping subsystem (Joe
     Hattori)"

* tag 'pm-6.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq/amd-pstate: Fix cpufreq_policy ref counting
  cpufreq: prevent NULL dereference in cpufreq_online()
  cpufreq: airoha: modify CONFIG_OF dependency
  cpufreq/amd-pstate: Fix max_perf updation with schedutil
  cpufreq/amd-pstate: Remove the goto label in amd_pstate_update_limits
  cpufreq/amd-pstate: Fix per-policy boost flag incorrect when fail
  powercap: call put_device() on an error path in powercap_register_control_type()
parents 0aa0282a 73195bed
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -17,7 +17,8 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM

config ARM_AIROHA_SOC_CPUFREQ
	tristate "Airoha EN7581 SoC CPUFreq support"
	depends on (ARCH_AIROHA && OF) || COMPILE_TEST
	depends on ARCH_AIROHA || COMPILE_TEST
	depends on OF
	select PM_OPP
	default ARCH_AIROHA
	help
+10 −10
Original line number Diff line number Diff line
@@ -699,7 +699,7 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
	if (min_perf < lowest_nonlinear_perf)
		min_perf = lowest_nonlinear_perf;

	max_perf = cap_perf;
	max_perf = cpudata->max_limit_perf;
	if (max_perf < min_perf)
		max_perf = min_perf;

@@ -747,7 +747,6 @@ static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
	guard(mutex)(&amd_pstate_driver_lock);

	ret = amd_pstate_cpu_boost_update(policy, state);
	policy->boost_enabled = !ret ? state : false;
	refresh_frequency_limits(policy);

	return ret;
@@ -822,25 +821,28 @@ static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata)

static void amd_pstate_update_limits(unsigned int cpu)
{
	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
	struct cpufreq_policy *policy = NULL;
	struct amd_cpudata *cpudata;
	u32 prev_high = 0, cur_high = 0;
	int ret;
	bool highest_perf_changed = false;

	if (!amd_pstate_prefcore)
		return;

	policy = cpufreq_cpu_get(cpu);
	if (!policy)
		return;

	cpudata = policy->driver_data;

	if (!amd_pstate_prefcore)
		return;

	guard(mutex)(&amd_pstate_driver_lock);

	ret = amd_get_highest_perf(cpu, &cur_high);
	if (ret)
		goto free_cpufreq_put;
	if (ret) {
		cpufreq_cpu_put(policy);
		return;
	}

	prev_high = READ_ONCE(cpudata->prefcore_ranking);
	highest_perf_changed = (prev_high != cur_high);
@@ -850,8 +852,6 @@ static void amd_pstate_update_limits(unsigned int cpu)
		if (cur_high < CPPC_MAX_PERF)
			sched_set_itmt_core_prio((int)cur_high, cpu);
	}

free_cpufreq_put:
	cpufreq_cpu_put(policy);

	if (!highest_perf_changed)
+2 −1
Original line number Diff line number Diff line
@@ -1571,7 +1571,8 @@ static int cpufreq_online(unsigned int cpu)
		policy->cdev = of_cpufreq_cooling_register(policy);

	/* Let the per-policy boost flag mirror the cpufreq_driver boost during init */
	if (policy->boost_enabled != cpufreq_boost_enabled()) {
	if (cpufreq_driver->set_boost &&
	    policy->boost_enabled != cpufreq_boost_enabled()) {
		policy->boost_enabled = cpufreq_boost_enabled();
		ret = cpufreq_driver->set_boost(policy, policy->boost_enabled);
		if (ret) {
+1 −2
Original line number Diff line number Diff line
@@ -627,8 +627,7 @@ struct powercap_control_type *powercap_register_control_type(
	dev_set_name(&control_type->dev, "%s", name);
	result = device_register(&control_type->dev);
	if (result) {
		if (control_type->allocated)
			kfree(control_type);
		put_device(&control_type->dev);
		return ERR_PTR(result);
	}
	idr_init(&control_type->idr);