From: sashiko-bot@kernel.org
To: "Tejun Heo" <tj@kernel.org>
Cc: sched-ext@lists.linux.dev
Subject: Re: [PATCH v2 sched_ext/for-7.3 35/36] tools/sched_ext: scx_qmap - Expand hierarchical sub-scheduling
Date: Mon, 06 Jul 2026 02:10:12 +0000 [thread overview]
Message-ID: <20260706021014.BEB9F1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260706014058.439853-36-tj@kernel.org>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Tasks dispatched to time-shared CIDs via `qmap_dispatch` lack the required `SCX_ENQ_IMMED` flag, causing the kernel to reject them and trigger an infinite bounce loop.
- [High] Concurrent modifications to `qa.sub_sched_ctxs[i].cgroup_id` during attach/detach race with `compute_partition()`, causing `nr_shared` to wrap negative or overflow `MAX_PARTS` and triggering a fatal `scx_bpf_error()` crash.
- [Medium] In `redistribute()`, elapsed time is incorrectly charged to the newly computed partition layout rather than the outgoing one, resulting in corrupt allocation statistics.
--
commit 93bb924468eaef8590cfd599f15e87393f92eaa9
Author: Tejun Heo <tj@kernel.org>
tools/sched_ext: scx_qmap - Expand hierarchical sub-scheduling
This patch expands the scx_qmap demonstration scheduler to support
capacity-based hierarchical sub-scheduling delegation. It introduces logic
to split exclusive CIDs and a shared round-robin pool among child cgroups
based on CPU weight.
> diff --git a/tools/sched_ext/scx_qmap.bpf.c b/tools/sched_ext/scx_qmap.bpf.c
> index f6cfe63425d36..64422e9e1db88 100644
> --- a/tools/sched_ext/scx_qmap.bpf.c
> +++ b/tools/sched_ext/scx_qmap.bpf.c
[ ... ]
> @@ -567,11 +627,34 @@ void BPF_STRUCT_OPS(qmap_dispatch, s32 cid, struct task_struct *prev)
> struct cpu_ctx __arena *cpuc;
> task_ctx_t *taskc;
> u32 batch = dsp_batch ?: 1;
> + s32 owner;
> s32 i;
>
> if (dispatch_highpri(false))
> return;
[Severity: High]
Does this dispatch logic need to include the SCX_ENQ_IMMED flag when moving
tasks to a time-shared CID?
When a child scheduler receives a time-shared CID, it is only granted the
SCX_CAP_ENQ_IMMED capability for it. However, the subsequent calls to
scx_bpf_dsq_move_to_local() in qmap_dispatch() pass 0 as the enq_flags.
Similarly, in dispatch_highpri(), scx_bpf_dsq_move() passes SCX_ENQ_PREEMPT.
If a task is moved to the local DSQ of a time-shared CID without including
the SCX_ENQ_IMMED flag (for instance, via needs_immed(cid)), the kernel will
reject the local DSQ insert because the child lacks the stronger SCX_CAP_ENQ
and SCX_CAP_PREEMPT capabilities. This rejection bounces the task back to the
global DSQ with SCX_TASK_REENQ_CAP, which can cause an endless bounce loop
and a spike in CPU utilization.
[ ... ]
> +static void redistribute(void)
> +{
> + s32 i;
> +
> + __sync_fetch_and_or(&part_pending, 1);
> +
> + if (!part_try_start())
> + return;
> +
> + bpf_for(i, 0, 1024) {
> + __sync_fetch_and_and(&part_pending, 0);
> + compute_partition();
> + apply_partition();
[Severity: Medium]
Is the elapsed time being incorrectly charged to the newly computed partition
layout instead of the outgoing one?
Inside this loop, compute_partition() overwrites the qa.part layout,
including the owners and round-robin positions. Then, apply_partition() is
called, which in turn calls account_alloc().
Because account_alloc() executes after the layout has already been mutated,
it uses the new qa.part structure to calculate the time delta for the
outgoing layout. This could lead to time being attributed to the wrong CIDs
or sub-schedulers, resulting in corrupted allocation statistics. Should
account_alloc() be invoked before the qa.part structure is overwritten?
> + if (!__sync_fetch_and_or(&part_pending, 0))
> + break;
> + }
> +
> + part_end();
> +}
[ ... ]
> @@ -1202,13 +1793,20 @@ s32 BPF_STRUCT_OPS(qmap_sub_attach, struct scx_sub_attach_args *args)
> {
> s32 i;
>
> + /* as long as there is at least one excl cpu, children can attach */
> + if (!cmask_weight(&qa.held_excl.mask))
> + return -ENOSPC;
> +
> for (i = 0; i < MAX_SUB_SCHEDS; i++) {
> - if (!qa.sub_sched_cgroup_ids[i]) {
> - qa.sub_sched_cgroup_ids[i] = args->ops->sub_cgroup_id;
> - bpf_printk("attaching sub-sched[%d] on %s",
> - i, args->cgroup_path);
> - return 0;
> - }
> + if (qa.sub_sched_ctxs[i].cgroup_id)
> + continue;
> +
> + qa.sub_sched_ctxs[i].cgroup_id = args->ops->sub_cgroup_id;
[Severity: High]
Could these concurrent modifications to the cgroup_id cause a race condition
with compute_partition()?
In qmap_sub_attach() and qmap_sub_detach(), the cgroup_id is modified directly
without acquiring the part_busy synchronization guard. If a userspace process
triggers a repartition (via BPF_PROG_RUN) at the same time the cgroup core
calls ops.sub_attach or ops.sub_detach, compute_partition() could observe
inconsistent state.
Specifically, the first loop in compute_partition() calculates sum_w based on
one state of the cgroup_id array, while the second loop allocates total_excl
based on a potentially different state. This mismatch could cause total_excl
to exceed nr_excl (resulting in a negative nr_shared that wraps around) or
fall short (making nr_shared > MAX_PARTS), which would then trigger a fatal
scx_bpf_error("-ERANGE") in apply_partition() and force a revert to CFS.
> + qa.sub_sched_ctxs[i].weight = 100; /* until userspace feeds it */
> + qa.nr_sub_scheds++;
> + bpf_printk("attaching sub-sched[%d] on %s", i, args->cgroup_path);
> + redistribute();
> + return 0;
> }
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260706014058.439853-1-tj@kernel.org?part=35
next prev parent reply other threads:[~2026-07-06 2:10 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-06 1:40 [PATCHSET v2 sched_ext/for-7.3] sched_ext: Capability-based CPU delegation for sub-schedulers Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 01/36] sched_ext: Add SCX_CALL_CID_OP_TASK() for cid-form op dispatch Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 02/36] sched_ext: Rename extra_enq_flags to remote_activate_enq_flags Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 03/36] sched_ext: Fix premature ops->priv publication in scx_alloc_and_add_sched() Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 04/36] tools/sched_ext: scx - Fix cmask_subset(), cmask_equal() and cmask_weight() Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 05/36] sched_ext: Use READ_ONCE/WRITE_ONCE in cmask word ops and drop _RACY variants Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 06/36] tools/sched_ext: scx_qmap - Use bare u64/u32/s32 integer types Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 07/36] sched_ext: Reject direct slice and dsq_vtime writes for cid-form schedulers Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 08/36] sched_ext: Make scx_bpf_kick_cid() return void Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 09/36] sched_ext: Make the kick machinery per-sched Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 10/36] sched_ext: Add ops.init_cids() to finalize the cid layout before init Tejun Heo
2026-07-06 2:08 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 11/36] sched_ext: Add CID sharding Tejun Heo
2026-07-06 1:53 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 12/36] sched_ext: Add shard boundaries to scx_bpf_cid_override() Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 13/36] sched_ext: Defer scx_sched kobj sysfs add into the enable workfns Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 14/36] sched_ext: Add per-shard scx_sched storage scaffolding Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 15/36] sched_ext: Add scx_cmask_ref for validated arena cmask access Tejun Heo
2026-07-06 1:58 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 9:04 ` Andrea Righi
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 16/36] sched_ext: Build the set_cmask scratch from trusted geometry Tejun Heo
2026-07-06 1:59 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 17/36] sched_ext: RCU-protect the sub-sched tree's children/sibling lists Tejun Heo
2026-07-06 2:08 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 18/36] sched_ext: Add scx_skip_subtree_pre() Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 19/36] sched_ext: Add per-shard cap delegation for sub-schedulers Tejun Heo
2026-07-06 2:13 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 20/36] sched_ext: Add coalescing sub_caps_updated() notifier " Tejun Heo
2026-07-06 2:06 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 21/36] sched_ext: Maintain per-cpu effective cap copies for single-read checks Tejun Heo
2026-07-06 2:07 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 22/36] sched_ext: Add sub_ecaps_updated() effective-cap change notifier Tejun Heo
2026-07-06 2:09 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 23/36] sched_ext: Generalize local-DSQ handling to rq-owned DSQs Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 24/36] sched_ext: Add reject DSQ for cap-rejected dispatches Tejun Heo
2026-07-06 2:08 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 25/36] sched_ext: Add the SCX_CAP_ENQ_IMMED cap Tejun Heo
2026-07-06 2:10 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 26/36] sched_ext: Assign a unique id to each scheduler instance Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 27/36] sched_ext: Route task slice writes through set_task_slice() Tejun Heo
2026-07-06 2:05 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 9:10 ` Andrea Righi
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 28/36] sched_ext: Tie cpu occupancy to SCX_CAP_BASE through the task slice Tejun Heo
2026-07-06 2:07 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 29/36] sched_ext: Add the SCX_CAP_ENQ cap Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 30/36] sched_ext: Gate kicks on SCX_CAP_BASE and preemption on SCX_CAP_PREEMPT Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 31/36] sched_ext: Authorize remote-move inserts against the placing scheduler Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 32/36] sched_ext: Route ops.update_idle() to sub-schedulers and re-notify owed scheds Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 33/36] sched_ext: Replay ecaps notifications suppressed by bypass Tejun Heo
2026-07-06 2:11 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 34/36] sched_ext: Add scx_bpf_sub_kill() to evict a child sub-scheduler Tejun Heo
2026-07-06 2:12 ` sashiko-bot
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 35/36] tools/sched_ext: scx_qmap - Expand hierarchical sub-scheduling Tejun Heo
2026-07-06 2:10 ` sashiko-bot [this message]
2026-07-06 23:40 ` Tejun Heo
2026-07-06 1:40 ` [PATCH v2 sched_ext/for-7.3 36/36] tools/sched_ext: scx_qmap - Add sub-sched cap fault injection 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=20260706021014.BEB9F1F000E9@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.