linux/kernel/sched
Zhongqiu Han f0a3f04229 cpufreq: schedutil: Publish util hooks only after all sg_cpu are initialized
Commit 16a03c71bb ("cpufreq: schedutil: Merge initialization code of
sg_cpu in single loop") merged the per-CPU initialization and the
utilization-hook registration into a single loop in sugov_start().

For a shared cpufreq policy this re-introduces the race originally fixed
by commit ab2f7cf141 ("cpufreq: schedutil: Fix sugov_start() versus
sugov_update_shared() race").

The scheduler's util path reaches the hook under RCU-sched and never takes
policy->rwsem, so the rwsem held across sugov_start() cannot serialize the
two. Once the first CPU's hook is published, sugov_update_shared() may run
and, via sugov_next_freq_shared(), read/write each sibling sugov_cpu
(iowait_boost, util, bw_min, ...) concurrently with the memset() still
initializing them, with no lock common to both sides: the update side holds
sg_policy->update_lock while the init side holds only policy->rwsem, which
the scheduler's util path never takes.

The walk only accesses scalar members, never a pointer like ->sg_policy,
so it does not crash today; it merely uses stale (or zero on first start)
values that skew the frequency selection and tracepoints. It is still a
genuine data race, and a latent crash once any pointer member is
dereferenced there.

Restore the two-phase approach: initialize all per-CPU structures first,
and only then publish the per-CPU utilization update hooks.

Fixes: 16a03c71bb ("cpufreq: schedutil: Merge initialization code of sg_cpu in single loop")
Cc: stable@vger.kernel.org
Signed-off-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
Reviewed-by: Christian Loehle <christian.loehle@arm.com>
Link: https://patch.msgid.link/20260716115159.848403-1-zhongqiu.han@oss.qualcomm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-07-22 15:20:39 +02:00
..
ext sched_ext: Skip ops.set_weight() for disabled tasks 2026-07-10 06:41:28 -10:00
autogroup.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
autogroup.h sched: Clean up and standardize #if/#else/#endif markers in sched/autogroup.[ch] 2025-06-13 08:47:14 +02:00
build_policy.c sched_ext: Move sources under kernel/sched/ext/ 2026-06-22 05:32:56 -10:00
build_utility.c sched/smp: Make SMP unconditional 2025-06-13 08:47:18 +02:00
clock.c sched/clock: Avoid false sharing for sched_clock_irqtime 2026-02-03 12:04:19 +01:00
completion.c sched: Make clangd usable 2025-06-11 11:20:53 +02:00
core_sched.c sched: Unify SMT active check via sched_smt_active() 2026-05-19 12:17:37 +02:00
core.c block-7.2-20260625 2026-06-25 09:56:47 -07:00
cpuacct.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cpudeadline.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cpudeadline.h sched/deadline: only set free_cpus for online runqueues 2025-10-16 11:13:49 +02:00
cpufreq_schedutil.c cpufreq: schedutil: Publish util hooks only after all sg_cpu are initialized 2026-07-22 15:20:39 +02:00
cpufreq.c sched: Make clangd usable 2025-06-11 11:20:53 +02:00
cpupri.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cpupri.h sched/smp: Make SMP unconditional 2025-06-13 08:47:18 +02:00
cputime.c Merge branch 'idle-time-acc' into features 2026-06-16 16:21:46 +02:00
deadline.c Scheduler updates for v7.2: 2026-06-15 14:50:18 +05:30
debug.c sched/fair: Remove task_group->se pointer array 2026-06-02 12:26:11 +02:00
fair.c sched/fair: Fix newidle vs core-sched 2026-06-11 13:41:23 +02:00
features.h sched/rt: Have RT_PUSH_IPI be default off for non PREEMPT_RT 2026-05-19 12:17:39 +02:00
idle.c Scheduler updates for v7.2: 2026-06-15 14:50:18 +05:30
isolation.c cgroup/cpuset: Call housekeeping_update() without holding cpus_read_lock 2026-02-23 10:46:49 -10:00
loadavg.c Merge branch 'tip/sched/urgent' 2025-07-14 17:16:28 +02:00
Makefile sched: Enable context analysis for core.c and fair.c 2026-01-05 16:43:36 +01:00
membarrier.c Locking updates for v7.2: 2026-06-15 14:21:14 +05:30
pelt.c treewide: Update email address 2026-01-11 06:09:11 -10:00
pelt.h sched/fair: Switch to task based throttle model 2025-09-03 10:03:14 +02:00
psi.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
rq-offsets.c sched: Make migrate_{en,dis}able() inline 2025-09-25 09:57:16 +02:00
rt.c sched: Rework prev_balance() to avoid stale prev references 2026-06-02 12:26:06 +02:00
sched-pelt.h sched: Make clangd usable 2025-06-11 11:20:53 +02:00
sched.h sched_ext: Move sources under kernel/sched/ext/ 2026-06-22 05:32:56 -10:00
smp.h sched: Make clangd usable 2025-06-11 11:20:53 +02:00
stats.c sched/smp: Use the SMP version of schedstats 2025-06-13 08:47:21 +02:00
stats.h sched/fair: Co-locate cfs_rq and sched_entity in cfs_tg_state 2026-06-02 12:26:10 +02:00
stop_task.c sched: Rework prev_balance() to avoid stale prev references 2026-06-02 12:26:06 +02:00
swait.c sched: Make clangd usable 2025-06-11 11:20:53 +02:00
syscalls.c Linux 7.0-rc4 2026-03-17 07:14:42 +01:00
topology.c sched/topology: Provide arch_llc_mask for cache aware scheduling 2026-05-29 12:43:15 +02:00
wait_bit.c sched: Make clangd usable 2025-06-11 11:20:53 +02:00
wait.c ARM: 2025-07-30 17:14:01 -07:00