All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: David Vernet <void@manifault.com>,
	Andrea Righi <arighi@nvidia.com>,
	Changwoo Min <changwoo@igalia.com>
Cc: sched-ext@lists.linux.dev, Emil Tsalapatis <emil@etsalapatis.com>,
	linux-kernel@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH v5 sched_ext/for-7.3 01/33] sched_ext: Assert per-task ops run on the task's owner
Date: Thu,  9 Jul 2026 12:50:09 -1000	[thread overview]
Message-ID: <20260709225041.1695495-2-tj@kernel.org> (raw)
In-Reply-To: <20260709225041.1695495-1-tj@kernel.org>

A per-task op must be dispatched on the scheduler that owns the task.
SCX_CALL_OP_TASK() and its _RET twin take @sch explicitly, and a caller that
passes the wrong scheduler would silently run the op on it. Add a
WARN_ON_ONCE() that @sch matches the task's owner so such a mismatch is
caught rather than hidden.

Two sites legitimately target a scheduler other than the task's owner:
cgroup_move() runs on the root sched, and scx_sub_init_cancel_task() fires
exit_task() on a task not yet associated with @sch. Both switch to the inner
__SCX_CALL_OP_TASK(), which dispatches on the explicit @sch without the
assert.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 kernel/sched/ext/ext.c      | 20 +++++++++++++-------
 kernel/sched/ext/internal.h | 10 +++++++++-
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 5241b55a58ec..acc3b43fe88a 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -1436,8 +1436,12 @@ static void scx_dispatch_enqueue(struct scx_sched *sch, struct rq *rq,
 		local_dsq_post_enq(sch, dsq, p, enq_flags);
 	} else {
 		/*
-		 * Task on global/bypass DSQ: leave custody, task on
-		 * non-terminal DSQ: enter custody.
+		 * Global and bypass DSQs are terminal - the task leaves the
+		 * scheduler's custody, so ops.dequeue() fires here. It can run
+		 * without @p's rq lock (finish_dispatch() passes the dispatch
+		 * rq); that's safe because dequeue_task_scx() waits on
+		 * SCX_OPSS_DISPATCHING (see the ops_state note above) and so
+		 * can't race it. A non-terminal DSQ keeps the task in custody.
 		 */
 		if (dsq->id == SCX_DSQ_GLOBAL || dsq->id == SCX_DSQ_BYPASS)
 			call_task_dequeue(sch, rq, p, 0);
@@ -3446,8 +3450,9 @@ void scx_sub_init_cancel_task(struct scx_sched *sch, struct task_struct *p)
 	lockdep_assert_held(&p->pi_lock);
 	lockdep_assert_rq_held(task_rq(p));
 
+	/* @p was never associated with @sch, dispatch on the explicit @sch */
 	if (SCX_HAS_OP(sch, exit_task))
-		SCX_CALL_OP_TASK(sch, exit_task, task_rq(p), p, &args);
+		__SCX_CALL_OP_TASK(sch, ops, exit_task, task_rq(p), p, &args);
 }
 
 void scx_disable_and_exit_task(struct scx_sched *sch, struct task_struct *p)
@@ -4184,12 +4189,13 @@ void scx_cgroup_move_task(struct task_struct *p)
 	 * cgroup changes. Migration keys off css rather than cgroup identity,
 	 * so it can hand an unchanged-cgroup task here with cgrp_moving_from
 	 * NULL. Nothing to report to the BPF scheduler then, so skip it and
-	 * keep prep_move and move paired.
+	 * keep prep_move and move paired. Cgroup ops run on the root sched,
+	 * dispatch on the explicit @sch.
 	 */
 	if (SCX_HAS_OP(sch, cgroup_move) && p->scx.cgrp_moving_from)
-		SCX_CALL_OP_TASK(sch, cgroup_move, task_rq(p),
-				 p, p->scx.cgrp_moving_from,
-				 tg_cgrp(task_group(p)));
+		__SCX_CALL_OP_TASK(sch, ops, cgroup_move, task_rq(p),
+				   p, p->scx.cgrp_moving_from,
+				   tg_cgrp(task_group(p)));
 	p->scx.cgrp_moving_from = NULL;
 }
 
diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
index 5ca44ad88786..8aabd92fae3b 100644
--- a/kernel/sched/ext/internal.h
+++ b/kernel/sched/ext/internal.h
@@ -1810,8 +1810,15 @@ do {										\
 	current->scx.kf_tasks[0] = NULL;					\
 } while (0)
 
+/*
+ * A per-task op runs on @task's owner - WARN if @sch isn't it. Sites that must
+ * target a different scheduler call __SCX_CALL_OP_TASK() directly.
+ */
 #define SCX_CALL_OP_TASK(sch, op, locked_rq, task, args...)			\
-	__SCX_CALL_OP_TASK(sch, ops, op, locked_rq, task, ##args)
+do {										\
+	WARN_ON_ONCE((sch) != scx_task_sched_rcu(task));			\
+	__SCX_CALL_OP_TASK((sch), ops, op, locked_rq, task, ##args);		\
+} while (0)
 
 /*
  * Dispatch a task op through the cid-form ops_cid table. Only set_cmask() needs
@@ -1824,6 +1831,7 @@ do {										\
 #define SCX_CALL_OP_TASK_RET(sch, op, locked_rq, task, args...)			\
 ({										\
 	__typeof__((sch)->ops.op(task, ##args)) __ret;				\
+	WARN_ON_ONCE((sch) != scx_task_sched_rcu(task));			\
 	WARN_ON_ONCE(current->scx.kf_tasks[0]);					\
 	current->scx.kf_tasks[0] = task;					\
 	__ret = SCX_CALL_OP_RET((sch), op, locked_rq, task, ##args);		\
-- 
2.55.0


  reply	other threads:[~2026-07-09 22:50 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-09 22:50 [PATCHSET v5 sched_ext/for-7.3] sched_ext: Capability-based CPU delegation for sub-schedulers Tejun Heo
2026-07-09 22:50 ` Tejun Heo [this message]
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 02/33] sched_ext: Make the kick machinery per-sched Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 03/33] sched_ext: Add ops.init_cids() to finalize the cid layout before init Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 04/33] sched_ext: Add CID sharding Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 05/33] sched_ext: Add shard boundaries to scx_bpf_cid_override() Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 06/33] sched_ext: Defer scx_sched kobj sysfs add into the enable workfns Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 07/33] sched_ext: Add per-shard scx_sched storage scaffolding Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 08/33] sched_ext: Add scx_cmask_ref for validated arena cmask access Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 09/33] sched_ext: Build the set_cmask scratch from trusted geometry Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 10/33] sched_ext: RCU-protect the sub-sched tree's children/sibling lists Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 11/33] sched_ext: Add scx_skip_subtree_pre() Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 12/33] sched_ext: Stop resolving a disabled scheduler's programs Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 13/33] sched_ext: Add per-shard cap delegation for sub-schedulers Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 14/33] sched_ext: Add coalescing sub_caps_updated() notifier " Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 15/33] sched_ext: Maintain per-cpu effective cap copies for single-read checks Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 16/33] sched_ext: Add sub_ecaps_updated() effective-cap change notifier Tejun Heo
2026-07-14  6:00   ` Andrea Righi
2026-07-14  8:07     ` Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 17/33] sched_ext: Generalize local-DSQ handling to rq-owned DSQs Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 18/33] sched_ext: Add reject DSQ for cap-rejected dispatches Tejun Heo
2026-07-14  6:49   ` Andrea Righi
2026-07-14  8:08     ` Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 19/33] sched_ext: Add SCX_ENQ_IGNORE_CAPS for in-place restore Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 20/33] sched_ext: Add the SCX_CAP_ENQ_IMMED cap Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 21/33] sched_ext: Assign a unique id to each scheduler instance Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 22/33] sched_ext: Route task slice writes through set_task_slice() Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 23/33] sched_ext: Track the cpu a task is runnable on Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 24/33] sched_ext: Tie cpu occupancy to SCX_CAP_BASE through the task slice Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 25/33] sched_ext: Add the SCX_CAP_ENQ cap Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 26/33] sched_ext: Gate kicks on SCX_CAP_BASE and preemption on SCX_CAP_PREEMPT Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 27/33] sched_ext: Authorize remote-move inserts against the placing scheduler Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 28/33] sched_ext: Route ops.update_idle() to sub-schedulers and re-notify owed scheds Tejun Heo
2026-07-14  6:18   ` Andrea Righi
2026-07-14  8:08     ` Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 29/33] sched_ext: Replay ecaps notifications suppressed by bypass Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 30/33] sched_ext: Add scx_bpf_sub_kill() to evict a child sub-scheduler Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 31/33] tools/sched_ext: Add three-mask cmask intersection iterator Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 32/33] tools/sched_ext: scx_qmap - Expand hierarchical sub-scheduling Tejun Heo
2026-07-09 22:50 ` [PATCH v5 sched_ext/for-7.3 33/33] tools/sched_ext: scx_qmap - Add sub-sched cap fault injection Tejun Heo
2026-07-14  7:10 ` [PATCHSET v5 sched_ext/for-7.3] sched_ext: Capability-based CPU delegation for sub-schedulers Andrea Righi
2026-07-14  8:07   ` Tejun Heo
2026-07-14  8:27 ` Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260709225041.1695495-2-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=arighi@nvidia.com \
    --cc=changwoo@igalia.com \
    --cc=emil@etsalapatis.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sched-ext@lists.linux.dev \
    --cc=void@manifault.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.