Commit 0a9b9d17 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull power management fix from Rafael Wysocki:
 "Fix a locking issue in the asymmetric CPU capacity setup code in the
  intel_pstate driver that may lead to a deadlock if CPU online/offline
  runs in parallel with the code in question, which is unlikely but not
  impossible (Rafael Wysocki)"

* tag 'pm-6.12-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: intel_pstate: Rearrange locking in hybrid_init_cpu_capacity_scaling()
parents 4ba05b0e 1a1030d1
Loading
Loading
Loading
Loading
+16 −19
Original line number Diff line number Diff line
@@ -1028,26 +1028,29 @@ static void hybrid_update_cpu_capacity_scaling(void)
	}
}

static void __hybrid_init_cpu_capacity_scaling(void)
static void __hybrid_refresh_cpu_capacity_scaling(void)
{
	hybrid_max_perf_cpu = NULL;
	hybrid_update_cpu_capacity_scaling();
}

static void hybrid_init_cpu_capacity_scaling(bool refresh)
static void hybrid_refresh_cpu_capacity_scaling(void)
{
	bool disable_itmt = false;
	guard(mutex)(&hybrid_capacity_lock);

	mutex_lock(&hybrid_capacity_lock);
	__hybrid_refresh_cpu_capacity_scaling();
}

static void hybrid_init_cpu_capacity_scaling(bool refresh)
{
	/*
	 * If hybrid_max_perf_cpu is set at this point, the hybrid CPU capacity
	 * scaling has been enabled already and the driver is just changing the
	 * operation mode.
	 */
	if (refresh) {
		__hybrid_init_cpu_capacity_scaling();
		goto unlock;
		hybrid_refresh_cpu_capacity_scaling();
		return;
	}

	/*
@@ -1056,20 +1059,14 @@ static void hybrid_init_cpu_capacity_scaling(bool refresh)
	 * do not do that when SMT is in use.
	 */
	if (hwp_is_hybrid && !sched_smt_active() && arch_enable_hybrid_capacity_scale()) {
		__hybrid_init_cpu_capacity_scaling();
		disable_itmt = true;
	}

unlock:
	mutex_unlock(&hybrid_capacity_lock);

		hybrid_refresh_cpu_capacity_scaling();
		/*
		 * Disabling ITMT causes sched domains to be rebuilt to disable asym
		 * packing and enable asym capacity.
		 */
	if (disable_itmt)
		sched_clear_itmt_support();
	}
}

static bool hybrid_clear_max_perf_cpu(void)
{
@@ -1404,7 +1401,7 @@ static void intel_pstate_update_limits_for_all(void)
	mutex_lock(&hybrid_capacity_lock);

	if (hybrid_max_perf_cpu)
		__hybrid_init_cpu_capacity_scaling();
		__hybrid_refresh_cpu_capacity_scaling();

	mutex_unlock(&hybrid_capacity_lock);
}