Skip to content

Commit

Permalink
cpufreq: intel_pstate: Rearrange locking in hybrid_init_cpu_capacity_…
Browse files Browse the repository at this point in the history
…scaling()

Notice that hybrid_init_cpu_capacity_scaling() only needs to hold
hybrid_capacity_lock around __hybrid_init_cpu_capacity_scaling()
calls, so introduce a "locked" wrapper around the latter and call
it from the former.  This allows to drop a local variable and a
label that are not needed any more.

Also, rename __hybrid_init_cpu_capacity_scaling() to
__hybrid_refresh_cpu_capacity_scaling() for consistency.

Interestingly enough, this fixes a locking issue introduced by commit
929ebc9 ("cpufreq: intel_pstate: Set asymmetric CPU capacity on
hybrid systems") that put an arch_enable_hybrid_capacity_scale() call
under hybrid_capacity_lock, which was a mistake because the latter is
acquired in CPU hotplug paths and so it cannot be held around
cpus_read_lock() calls.

Link: https://lore.kernel.org/linux-pm/SJ1PR11MB6129EDBF22F8A90FC3A3EDC8B9582@SJ1PR11MB6129.namprd11.prod.outlook.com/
Fixes: 929ebc9 ("cpufreq: intel_pstate: Set asymmetric CPU capacity on hybrid systems")
Signed-off-by: Rafael J. Wysocki <[email protected]>
Reported-by: "Borah, Chaitanya Kumar" <[email protected]>
Link: https://patch.msgid.link/[email protected]
[ rjw: Changelog update ]
Signed-off-by: Rafael J. Wysocki <[email protected]>
  • Loading branch information
rafaeljw committed Nov 11, 2024
1 parent 92447aa commit 1a1030d
Showing 1 changed file with 16 additions and 19 deletions.
35 changes: 16 additions & 19 deletions drivers/cpufreq/intel_pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/*
Expand All @@ -1056,19 +1059,13 @@ 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);

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

static bool hybrid_clear_max_perf_cpu(void)
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 1a1030d

Please sign in to comment.