From: sashiko-bot@kernel.org
To: "Tejun Heo" <tj@kernel.org>
Cc: sched-ext@lists.linux.dev
Subject: Re: [PATCH v4 sched_ext/for-7.3 20/40] sched_ext: Stop resolving a disabled scheduler's programs
Date: Wed, 08 Jul 2026 21:55:20 +0000 [thread overview]
Message-ID: <20260708215520.8C5461F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260708212429.3405787-21-tj@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] The `sch->dead` check was omitted from the `!CONFIG_EXT_SUB_SCHED` fallback version of `scx_prog_sched()`, leaving the Use-After-Exit hazard unfixed.
- [High] A parent scheduler can invoke a child scheduler's `ops.dispatch()` after the child's `ops.exit()` has already executed, bypassing the newly introduced `dead` flag protection.
--
--- Patch [20]: [PATCH v4 sched_ext/for-7.3 20/40] sched_ext: Stop resolving a disabled scheduler's programs ---
commit 4eb6882510c7d2ef68878ed595f1b7ecec9ef3cc
Author: Tejun Heo <tj@kernel.org>
sched_ext: Stop resolving a disabled scheduler's programs
A scheduler's BPF programs can outlive it. A timer it armed or a tracing
program it loaded can fire after ops.exit() has run, before the programs are
unloaded, and scx_prog_sched() still resolves the program to its scheduler
through ops->priv. Harmless while kfuncs touch only lifetime-stable state,
but a hazard once a kfunc reads global state a newly loaded scheduler can
change underneath it.
Add scx_sched->dead, set right after ops.exit() and drained with
synchronize_rcu(). It follows exit() rather than preceding it so exit()'s own
kfunc calls still resolve to @sch. scx_prog_sched() returns NULL for a dead
scheduler, so every kfunc's existing !sch bail rejects it at one choke
point.
> diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
> index dce07b83c1663..87582bca5cc4f 100644
> --- a/kernel/sched/ext/internal.h
> +++ b/kernel/sched/ext/internal.h
[ ... ]
> @@ -1968,14 +1969,20 @@ static inline bool scx_task_on_sched(struct scx_sched *sch,
> static inline struct scx_sched *scx_prog_sched(const struct bpf_prog_aux *aux)
> {
> struct sched_ext_ops *ops;
> - struct scx_sched *root;
> + struct scx_sched *sch, *root;
>
> ops = bpf_prog_get_assoc_struct_ops(aux);
> - if (likely(ops))
> - return rcu_dereference_all(ops->priv);
> + if (likely(ops)) {
> + sch = rcu_dereference_all(ops->priv);
> + if (sch && unlikely(READ_ONCE(sch->dead)))
> + return NULL;
> + return sch;
> + }
>
> root = rcu_dereference_all(scx_root);
> if (root) {
> + if (unlikely(READ_ONCE(root->dead)))
> + return NULL;
> /*
> * COMPAT-v6.19: Schedulers built before sub-sched support was
> * introduced may have unassociated non-struct_ops programs.
[Severity: High]
This isn't a bug introduced by this patch, but does the fallback definition of
scx_prog_sched() also need the sch->dead check?
When the kernel is built with CONFIG_EXT_SUB_SCHED=n, scx_prog_sched() in
kernel/sched/ext/internal.h is defined as:
static inline struct scx_sched *scx_prog_sched(const struct bpf_prog_aux *aux)
{
return rcu_dereference_all(scx_root);
}
If a BPF timer fires during the synchronize_rcu() window in scx_root_disable(),
it seems this fallback will unconditionally return scx_root without checking
its dead flag, allowing kfuncs to execute on torn-down scheduler state.
> diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c
> index 17ed0d28f3839..8d98250936497 100644
> --- a/kernel/sched/ext/sub.c
> +++ b/kernel/sched/ext/sub.c
> @@ -344,6 +344,15 @@ void scx_sub_disable(struct scx_sched *sch)
>
> if (sch->ops.exit)
> SCX_CALL_OP(sch, exit, NULL, sch->exit_info);
> +
> + /*
> + * @sch's programs (an armed timer, a tracing prog) can fire after
> + * exit(). Now that exit()'s own kfuncs have resolved, stop
> + * scx_prog_sched() from resolving to @sch and drain in-flight resolvers.
> + */
> + WRITE_ONCE(sch->dead, true);
> + synchronize_rcu();
> +
[Severity: High]
This is a pre-existing issue, but can a parent scheduler bypass the newly
introduced dead flag and invoke a torn-down child scheduler's ops.dispatch()?
If a parent scheduler calls scx_dispatch_sched(child) from a BPF program
holding the RCU read lock while scx_sub_disable() is waiting on
synchronize_rcu():
Parent BPF program scx_sub_disable()
child->ops.exit()
WRITE_ONCE(child->dead, true);
synchronize_rcu(); (blocks on parent)
scx_find_sub_sched()
scx_dispatch_sched(child)
child->ops.dispatch()
It looks like scx_dispatch_sched() unconditionally invokes the dispatch
operation without checking the dead flag. Does scx_dispatch_sched() or
scx_bpf_sub_dispatch() need to check if the child is already dead to
prevent access to torn-down state?
> if (sch->sub_kset)
> kobject_del(&sch->sub_kset->kobj);
> /* not added if enable failed before scx_sched_sysfs_add() */
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260708212429.3405787-1-tj@kernel.org?part=20
next prev parent reply other threads:[~2026-07-08 21:55 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 21:23 [PATCHSET v4 sched_ext/for-7.3] sched_ext: Capability-based CPU delegation for sub-schedulers Tejun Heo
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 01/40] sched_ext: Record an error on errno-only sub-enable failure Tejun Heo
2026-07-09 20:37 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 02/40] sched_ext: Fix premature ops->priv publication in scx_alloc_and_add_sched() Tejun Heo
2026-07-09 20:38 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 03/40] tools/sched_ext: scx - Fix cmask_subset(), cmask_equal() and cmask_weight() Tejun Heo
2026-07-09 20:39 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 04/40] sched_ext: Use READ_ONCE/WRITE_ONCE in cmask word ops and drop _RACY variants Tejun Heo
2026-07-09 20:39 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 05/40] sched_ext: Add SCX_CALL_CID_OP_TASK() for cid-form op dispatch Tejun Heo
2026-07-09 20:41 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 06/40] sched_ext: Rename extra_enq_flags to remote_activate_enq_flags Tejun Heo
2026-07-09 20:41 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 07/40] tools/sched_ext: scx_qmap - Use bare u64/u32/s32 integer types Tejun Heo
2026-07-09 20:42 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 08/40] sched_ext: Reject direct slice and dsq_vtime writes for cid-form schedulers Tejun Heo
2026-07-08 21:41 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-09 20:56 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 09/40] sched_ext: Make scx_bpf_kick_cid() return void Tejun Heo
2026-07-09 20:57 ` Andrea Righi
2026-07-08 21:23 ` [PATCH v4 sched_ext/for-7.3 10/40] sched_ext: Make the kick machinery per-sched Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 11/40] sched_ext: Add ops.init_cids() to finalize the cid layout before init Tejun Heo
2026-07-08 21:54 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 12/40] sched_ext: Add CID sharding Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 13/40] sched_ext: Add shard boundaries to scx_bpf_cid_override() Tejun Heo
2026-07-08 21:47 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 14/40] sched_ext: Defer scx_sched kobj sysfs add into the enable workfns Tejun Heo
2026-07-08 21:47 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 15/40] sched_ext: Add per-shard scx_sched storage scaffolding Tejun Heo
2026-07-08 21:44 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 16/40] sched_ext: Add scx_cmask_ref for validated arena cmask access Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 17/40] sched_ext: Build the set_cmask scratch from trusted geometry Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 18/40] sched_ext: RCU-protect the sub-sched tree's children/sibling lists Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 19/40] sched_ext: Add scx_skip_subtree_pre() Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 20/40] sched_ext: Stop resolving a disabled scheduler's programs Tejun Heo
2026-07-08 21:55 ` sashiko-bot [this message]
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 21/40] sched_ext: Add per-shard cap delegation for sub-schedulers Tejun Heo
2026-07-08 22:00 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 22/40] sched_ext: Add coalescing sub_caps_updated() notifier " Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 23/40] sched_ext: Maintain per-cpu effective cap copies for single-read checks Tejun Heo
2026-07-08 22:03 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 24/40] sched_ext: Add sub_ecaps_updated() effective-cap change notifier Tejun Heo
2026-07-08 22:02 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 25/40] sched_ext: Generalize local-DSQ handling to rq-owned DSQs Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 26/40] sched_ext: Add reject DSQ for cap-rejected dispatches Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 27/40] sched_ext: Add the SCX_CAP_ENQ_IMMED cap Tejun Heo
2026-07-08 21:56 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 28/40] sched_ext: Assign a unique id to each scheduler instance Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 29/40] sched_ext: Route task slice writes through set_task_slice() Tejun Heo
2026-07-08 21:53 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 30/40] sched_ext: Track the cpu a task is runnable on Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 31/40] sched_ext: Tie cpu occupancy to SCX_CAP_BASE through the task slice Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 32/40] sched_ext: Add the SCX_CAP_ENQ cap Tejun Heo
2026-07-08 22:00 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 33/40] sched_ext: Gate kicks on SCX_CAP_BASE and preemption on SCX_CAP_PREEMPT Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 34/40] sched_ext: Authorize remote-move inserts against the placing scheduler Tejun Heo
2026-07-08 22:04 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-09 20:09 ` Andrea Righi
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 35/40] sched_ext: Route ops.update_idle() to sub-schedulers and re-notify owed scheds Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 36/40] sched_ext: Replay ecaps notifications suppressed by bypass Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 37/40] sched_ext: Add scx_bpf_sub_kill() to evict a child sub-scheduler Tejun Heo
2026-07-08 22:11 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 38/40] tools/sched_ext: Add three-mask cmask intersection iterator Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 39/40] tools/sched_ext: scx_qmap - Expand hierarchical sub-scheduling Tejun Heo
2026-07-08 22:03 ` sashiko-bot
2026-07-09 22:28 ` Tejun Heo
2026-07-08 21:24 ` [PATCH v4 sched_ext/for-7.3 40/40] tools/sched_ext: scx_qmap - Add sub-sched cap fault injection Tejun Heo
2026-07-09 21:18 ` [PATCHSET v4 sched_ext/for-7.3] sched_ext: Capability-based CPU delegation for sub-schedulers Tejun Heo
2026-07-09 22:13 ` 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=20260708215520.8C5461F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=sched-ext@lists.linux.dev \
--cc=tj@kernel.org \
/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.