Commit e14fd98c authored by Breno Leitao's avatar Breno Leitao Committed by Tejun Heo
Browse files

sched/ext: Prevent update_locked_rq() calls with NULL rq



Avoid invoking update_locked_rq() when the runqueue (rq) pointer is NULL
in the SCX_CALL_OP and SCX_CALL_OP_RET macros.

Previously, calling update_locked_rq(NULL) with preemption enabled could
trigger the following warning:

    BUG: using __this_cpu_write() in preemptible [00000000]

This happens because __this_cpu_write() is unsafe to use in preemptible
context.

rq is NULL when an ops invoked from an unlocked context. In such cases, we
don't need to store any rq, since the value should already be NULL
(unlocked). Ensure that update_locked_rq() is only called when rq is
non-NULL, preventing calling __this_cpu_write() on preemptible context.

Suggested-by: default avatarPeter Zijlstra <peterz@infradead.org>
Fixes: 18853ba7 ("sched_ext: Track currently locked rq")
Signed-off-by: default avatarBreno Leitao <leitao@debian.org>
Acked-by: default avatarAndrea Righi <arighi@nvidia.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org # v6.15
parent 7980ad7e
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -1272,6 +1272,7 @@ static inline struct rq *scx_locked_rq(void)

#define SCX_CALL_OP(sch, mask, op, rq, args...)					\
do {										\
	if (rq)									\
		update_locked_rq(rq);						\
	if (mask) {								\
		scx_kf_allow(mask);						\
@@ -1280,6 +1281,7 @@ do { \
	} else {								\
		(sch)->ops.op(args);						\
	}									\
	if (rq)									\
		update_locked_rq(NULL);						\
} while (0)

@@ -1287,6 +1289,7 @@ do { \
({										\
	__typeof__((sch)->ops.op(args)) __ret;					\
										\
	if (rq)									\
		update_locked_rq(rq);						\
	if (mask) {								\
		scx_kf_allow(mask);						\
@@ -1295,6 +1298,7 @@ do { \
	} else {								\
		__ret = (sch)->ops.op(args);					\
	}									\
	if (rq)									\
		update_locked_rq(NULL);						\
	__ret;									\
})