[PATCH v4 0/2] Fix uclamp race against non atomic static key enable

From: Qais Yousef

Date: Thu Oct 29 2026 - 09:15:53 EST


Changes since v3:
- Fix Sashiko report about force_idle paths where
rq->nr_running is not 0 highlighted by Christian
- Update patch 1 commit message to reflect jump_label call
sites on the same CPU might not be updated atomically too

Changes since v2:
- Use uclamp_rq_is_idle() instead of scanning buckets to detect
imbalance
- Do some cleanup on accessing the flag as an additional patch

Changes since v1:
- Fix kernel test robot report due to missing static inline in dummy
definition of init_uclamp_rq()

Tested with the patch below to force imbalance via sched_feat. I could see the
warning appearing and frequencies spiking during imbalance. Correct behavior is
restored when sched_feat is disabled where the idle entry reset fixes things
up.

I had a mix of uclamp_max mainly used in the system via schedqosd.

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a2035d66270b9..14f9f1e419e02 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1889,6 +1889,11 @@ static inline void uclamp_rq_inc(struct rq *rq, struct task_struct *p, int flags
for_each_clamp_id(clamp_id)
uclamp_rq_inc_id(rq, p, clamp_id);

+ if (sched_feat(UCLAMP_IMBALANCED)) {
+ for_each_clamp_id(clamp_id)
+ uclamp_rq_inc_id(rq, p, clamp_id);
+ }
+
/* Reset clamp idle holding when there is one RUNNABLE task */
if (uclamp_rq_is_idle(rq))
uclamp_rq_clear_idle(rq);
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index 8f0dee8fc4755..b59e532500fd9 100644
--- a/kernel/sched/features.h
+++ b/kernel/sched/features.h
@@ -142,3 +142,5 @@ SCHED_FEAT(LATENCY_WARN, false)
*/
SCHED_FEAT(NI_RANDOM, true)
SCHED_FEAT(NI_RATE, true)
+
+SCHED_FEAT(UCLAMP_IMBALANCED, false)
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 84301fc49e699..dbc3f5e1a7e01 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -519,7 +519,7 @@ static void set_next_task_idle(struct rq *rq, struct task_struct *next, enum snt
* are still queued.
*/
if (uclamp_is_used() &&
- !rq->nr_running && unlikely(!uclamp_rq_is_idle(rq)))
+ !rq->nr_running && unlikely(WARN_ON(!uclamp_rq_is_idle(rq))))
init_uclamp_rq(rq);
}

Qais Yousef (2):
sched/uclamp: Fix race condition leading to imbalanced uclamp_rq
sched/uclamp: Use wrappers instead of open coding UCLAMP_FLAG_IDLE

kernel/sched/core.c | 16 ++++++++--------
kernel/sched/idle.c | 19 +++++++++++++++++++
kernel/sched/sched.h | 13 +++++++++++++
3 files changed, 40 insertions(+), 8 deletions(-)

--
2.53.0