summaryrefslogtreecommitdiff
path: root/tools/sched_ext
AgeCommit message (Collapse)Author
11 dayssched_ext: Merge branch 'for-7.3-arena-args' into for-7.3Tejun Heo
Pull to receive the __arena argument conversion: 67f1f4a48c24 ("sched_ext: Pass kernel arena pointers to ops_cid callbacks") a8dc810968af ("sched_ext: Convert sub-cap kfuncs to __arena cmask arguments") a05c5b5cb5cf ("sched_ext: Convert scx_bpf_cid_override() to __arena array arguments") along with the bpf-next branch carrying the __arena argument support they depend on. Conflict in kernel/sched/ext/ext.c between: c384ab8a0b13 ("sched_ext: Move the config-off sub-cap kfunc stubs into sub.c") and: a8dc810968af ("sched_ext: Convert sub-cap kfuncs to __arena cmask arguments") which updated the stubs in their old ext.c location. Resolved by keeping ext.c without the stubs and applying the prototype conversion to the relocated stubs in sub.c. Signed-off-by: Tejun Heo <tj@kernel.org>
13 dayssched_ext: Make core-sched task ordering hierarchy-awareTejun Heo
With sub-schedulers, tasks of different schedulers routinely share rqs and SMT siblings, but scx_prio_less() consults ops.core_sched_before() only when both tasks belong to the same scheduler. Every pair spanning two schedulers falls back to the default ordering, so no scheduler can express ordering across a scheduler boundary, including a root over its sub-schedulers' tasks. Order a pair spanning schedulers by the nearest common ancestor that implements ops.core_sched_before(): both tasks are in its subtree, making this the one op where a scheduler is called on tasks it delegated to its sub-schedulers and may not be scheduling anymore. Same-scheduler pairs keep using the owning scheduler's op so a parent never orders inside a subtree it delegated. The op is skipped when the deciding scheduler is bypassing on either task's CPU. Update scx_qmap to fall back to the kernel's default ordering when handed a delegated task it has no task_ctx for. Signed-off-by: Tejun Heo <tj@kernel.org>
13 dayssched_ext: Fix inverted ops.core_sched_before() invocationTejun Heo
scx_prio_less() implements prio_less() semantics - %true means that @a is the lower priority and should run after @b. ops.core_sched_before() is documented to return %true when @a should run before @b. scx_prio_less() returns the op's value as-is, inverting the documented semantics at runtime. Call the op with the arguments swapped. scx_qmap followed the wiring instead of the documentation and returned %true for the younger task, so the two inversions canceled out and it behaved as intended. Flip its comparison to match. scx_qmap is likely the only current user in or out of the kernel tree. Any scheduler written the same way needs the same flip, while schedulers following the documentation are fixed by this change. Fixes: 7b0888b7cc19 ("sched_ext: Implement core-sched support") Cc: stable@vger.kernel.org # v6.12+ Signed-off-by: Tejun Heo <tj@kernel.org>
14 dayssched_ext: Rename balance-era identifiers to dispatch termsTejun Heo
sched_class->balance() is gone from sched_ext and what balance_one() does is run dispatch to produce something pickable. Update the balance-era names to dispatch terms: - balance_one() -> dispatch_one() - SCX_RQ_IN_BALANCE -> SCX_RQ_IN_DISPATCH No BPF scheduler reads the flag. The enum autogen headers gain the new name with the old entry retained like other removed enumerators, zero-filling at load time. No functional changes. Signed-off-by: Tejun Heo <tj@kernel.org>
14 dayssched_ext/scx_flatcg: Fix cvtime true-up on slice expiryTao Cui
fcg_dispatch() true-ups the current cgroup's cvtime when its slice expires or its DSQ runs empty while the slice is still active: __sync_fetch_and_add(&cgc->cvtime_delta, (cpuc->cur_at + cgrp_slice_ns - now) * FCG_HWEIGHT_ONE / (cgc->hweight ?: 1)); The true-up should be actual minus charged: on CNS_EXPIRE, the overrun (now - cur_at - cgrp_slice_ns) should be added; on CNS_EMPTY, the unused portion of the slice should be subtracted. The expression above has the sign inverted, and in the CNS_EXPIRE case now is already past cur_at + cgrp_slice_ns, so the u64 subtraction wraps. The multiplication preserves the two's complement encoding but the unsigned division by hweight destroys it, adding roughly 2^64/hweight per expiry instead of a small correction. Under saturation the hweight budget clamp in cgrp_cap_budget() masks most of the garbage, so the weight distribution barely moves, but the accounting is broken all the same. Compute the delta as a signed value and use fetch_and_add()/fetch_and_sub() so that the dividends stay positive, as BPF division is unsigned. Instrumented the true-up and ran a saturated three-leaf cgroup tree on a 4-CPU VM: without the fix, each expiry added ~5e15 (2^64/hweight territory) to cvtime_delta; with it, the corrections are back to slice scale, with the overrun added and the unused portion subtracted. Fixes: a4103eacc2ab ("sched_ext: Add a cgroup scheduler which uses flattened hierarchy") Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
14 dayssched_ext: Fix scx_bpf_dsq_move_to_local___v2 compat detectionfangqiurong
libbpf strips the last ___flavor suffix when resolving kfunc externs, so the bare ___v2 declaration resolves to scx_bpf_dsq_move_to_local, whose BTF proto lacks @enq_flags. The extern never matches, bpf_ksym_exists() returns false on every kernel that has the ___v2 kfunc, and the macro falls back to ___v1, silently dropping @enq_flags. Add the trailing ___compat suffix used by the other versioned externs in this file (scx_bpf_dsq_insert___v2, scx_bpf_reenqueue_local___v2). Any caller passing non-zero @enq_flags through the compat macro silently loses them. Fixes: 860683763ebf ("sched_ext: Add enq_flags to scx_bpf_dsq_move_to_local()") Cc: stable@vger.kernel.org # v7.1+ Assisted-by: Z.ai:glm-5.2 Signed-off-by: fangqiurong <fangqiurong@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-14sched_ext: Fix scx_bpf_dsq_reenq___compat kfunc extern prototypeTejun Heo
scx_bpf_dsq_reenq() is registered with KF_IMPLICIT_ARGS and its kernel BTF prototype omits the trailing bpf_prog_aux argument. The ___compat extern declares the argument explicitly, so libbpf never matches the prototype and the weak extern silently stays unresolved on every kernel. The wrapper always takes the old fallback path, which disables generic reenq users like scx_qmap's lowpri mechanism and fails non-local reenq with "kernel too old" even on kernels that have the kfunc. Drop the explicit aux argument. Also correct the stale v6.20 reference, the kfunc was added in v7.1. Fixes: 9c34c5074d1b ("sched_ext: Introduce scx_bpf_dsq_reenq() for remote local DSQ reenqueue") Cc: stable@vger.kernel.org # v7.1+ Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-14sched_ext/scx_flatcg: expire cached hweights on weight changesTao Cui
fcg_cgroup_set_weight() updates cgc->weight and the parent's child_weight_sum but doesn't bump hweight_gen, so the hweights cached by cgrp_refresh_hweight() stay stale until some task activation bumps the generation. For cgroups whose tasks never go through a 0->n runnable transition (e.g. persistently busy ones), a cpu.weight change never propagates to scheduling at all. Bump hweight_gen on weight changes so the next refresh recomputes with the new weight. Verified on a flatcg VM: a live cpu.weight 100->800 change on a busy cgroup leaves HWT update at 0 and the distribution unchanged; with it, hweight_gen increments and the refresh recomputes. Signed-off-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-12sched_ext: Convert scx_bpf_cid_override() to __arena array argumentsTejun Heo
scx_bpf_cid_override() predates the cid-form arena transition and takes its arrays as verifier-checked mem+size buffers, forcing scx_qmap to keep the cpu_to_cid and shard_start arrays in writable bss while the rest of its state lives in the arena. Unify on arena arguments before cid-form schedulers start seeing real use. BPF now translates between BPF and kernel arena addresses for __arena arguments. Take the arrays as __arena arguments, with the counts passed in entries. The counts now size the snapshot copies and are bounds-checked before them. scx_qmap moves the arrays into struct qmap_arena. As the arena is mmapped at load, the loader populates them between load and attach instead of before load. The arena argument address translation is currently implemented only on x86-64. Schedulers calling this kfunc load only there for now. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-12sched_ext: Convert sub-cap kfuncs to __arena cmask argumentsTejun Heo
The sub-cap kfuncs take their cmask arguments as __ign pointers. The values cross the kfunc boundary as unchecked scalars and scx_cmask_ref_init() rebases them into the arena by hand. BPF now translates between BPF and kernel arena addresses for __arena arguments. Tag the cmask arguments __arena so the kfuncs receive kernel addresses and scx_cmask_ref_init() loses the hand-rolled conversion. The optional denied_out keeps its NULL not-provided signal via __arena__nullable. The mandatory masks use plain __arena. scx_qmap's call sites drop the (void *)(long) casts since the BPF-side declarations type the cmask arguments __arena and take arena pointers directly. The arena argument address translation is currently implemented only on x86-64. Schedulers calling these kfuncs load only there for now. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-12Merge branch 'for-7.3' into for-7.3-arena-argsTejun Heo
2026-08-12sched_ext: Merge branch 'for-7.2-fixes' into for-7.3Tejun Heo
Pull to receive: c10b216a072f ("sched/core: Handle pick_task() releasing the rq lock") f3629c63a4af ("sched/core: Make core-sched flips wait for in-flight selections") ffaab58d2175 ("sched_ext: Replace SCX_RQ_BAL_KEEP with a dispatch verdict return") 3dd52416e44a ("sched_ext: Fix this_rq() assumptions in dispatch kfuncs") f2da9587118d ("sched_ext: Count rq lock releases in rq->scx.lock_drop_seq") d954004205c1 ("sched_ext: Fix rq->core_pick corruption under core scheduling") for the pending core scheduling follow-ups and to resolve the conflicts with the code reorganization and cap gate work on for-7.3. ffaab58d2175 converts scx_dispatch_sched() to a dispatch verdict return which for-7.3 moved from ext.c into inlines.h. Resolved by applying the conversion to the relocated copy and combining balance_one()'s verdict returns with the scx_task_can_stay_on_cpu() gate from the cap work. ffaab58d2175 and 3dd52416e44a update scx_bpf_sub_dispatch() which for-7.3 moved into sub.c. Resolved by applying the scx_locked_rq() switch and the verdict test to the sub.c copy. f2da9587118d instruments the open-coded lock releases in consume_remote_task() which for-7.3 folded into switch_rq_lock(). Resolved by keeping the accounting in switch_rq_lock() which covers all its callers. d954004205c1 widens the put_prev_task_scx() WARN suppression to all core-sched rqs on the same condition that for-7.3 gated with scx_task_can_stay_on_cpu(). Resolved by combining both. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-11sched_ext: Replace SCX_RQ_BAL_KEEP with a dispatch verdict returnTejun Heo
SCX_RQ_BAL_KEEP tells the pick to keep running the previous task, a leftover from when balancing and picking were separate operations. An rq-level flag only works while dispatches and picks pair up one to one, which core scheduling breaks: selections interleave through dispatch's lock drops and a pick can consume a stale flag, keeping a task that has since been dequeued. Fixing core scheduling support requires the decision to travel with the dispatch that made it. Make scx_dispatch_sched() and balance_one() return an explicit verdict instead and drop the flag's plumbing from the tools autogen enum headers. Also factor the pick-side invocation, its follow-up queueing and the post-dispatch checks out of do_pick_task_scx() into dispatch_pick(). No functional changes intended. v2: Drop the SCX_RQ_BAL_KEEP plumbing from the tools autogen enum headers as well (Andrea). Fixes: 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") Cc: stable@vger.kernel.org # v6.19+ Signed-off-by: Tejun Heo <tj@kernel.org>
2026-08-10Merge branch 'master' of ↵Tejun Heo
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next into for-7.3-arena-args Pull bpf-next d114bb989367 ("Merge branch 'add-arena-argument-support-to-kfuncs-and-struct_ops'") to make the __arena and __arena__nullable kfunc and struct_ops argument suffixes available. The suffixed arguments will be used to convert sched_ext kfuncs and struct_ops callbacks that currently pass arena pointers as scalars and rebase them by hand.
2026-08-03sched_ext: scx_qmap - Add rescue supportTejun Heo
A sched holds only the cids its parent granted and nothing guarantees that they cover its tasks' affinities. A task that can run on none of them has nowhere to go and qmap stalls out: it force-inserts the task onto its first allowed cid, but the kernel bounces the insert back and the task parks in SHARED_DSQ, which is drained only on self cids it can't run on. Set SCX_ENQ_RESCUE on these inserts so the kernel diverts such tasks to its rescue path instead of bouncing them. The force-insert covers scheds with and without children and fires on re-enqueues, and the SHARED_DSQ scan on every dispatch rescues tasks stranded there - the enqueue-time check misses a task whose cids were lost while it was already queued. The wrong-cid fault injection carries the flag too and doubles as a deterministic rescue-traffic generator. -B and -q set the root-only rescue bandwidth and quantum ops knobs. -B 0 maps to SCX_RESCUE_DISABLE and turns rescue off kernel-side. Rescue inserts are counted and reported in the hier stats line. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-08-03sched_ext: scx_qmap - Idle-check pinned tasks before direct dispatchTejun Heo
pick_direct_dispatch_cid() sent a pinned task straight to its only cpu without an idle check. An insert onto a time-shared cid is forced IMMED, which may not wait on a busy cpu - the kernel bounces the task back to ops.enqueue(), the shortcut re-inserts it, and the loop runs into the reenqueue repeat limit. Run pinned tasks through the same idle test as everyone else and queue them when the cpu is busy. always_enq_immed forces IMMED on every local insert and already skipped the shortcut for the same reason. The check was the last reader of the always_enq_immed rodata mirror, so drop the variable. The -I option still sets SCX_OPS_ALWAYS_ENQ_IMMED. v2: Drop the now-unread always_enq_immed rodata mirror. (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-08-03sched_ext: Sync tools autogen enum headersTejun Heo
Mechanical regeneration for the enumerators added by the slice write rework and the rescue machinery. BPF schedulers reference SCX_ENQ_RESCUE, the rest are enum_defs presence markers. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-08-03sched_ext: Add bandwidth-limited rescue execution for stranded tasksTejun Heo
A local DSQ insert lacking the needed caps is diverted to the reject DSQ and bounced back through ops.enqueue() so the scheduler can re-decide. That recovery assumes the scheduler has somewhere legal to send the task. When it doesn't, e.g. when the task's affinity is restricted to cids delegated away, the task starves until the stall watchdog ejects the scheduler. An exiting task is worse - it skips ops.enqueue() and the rejection becomes a self-requeuing cycle that burns the CPU until the watchdog fires. Add SCX_ENQ_RESCUE, a fallback modifier on local DSQ inserts. When the insert would be rejected for missing caps, the kernel takes over and runs the task on the target CPU without consulting the owning scheduler. The kernel sets the flag itself when enqueueing an exiting task. Rescue is a last-resort forward-progress backstop with a persistent disadvantage, not a way around cap enforcement. A per-CPU token bucket accrues rescue_bandwidth_ppt (default 2%) of CPU time and rescues run one at a time in arrival order. Each is granted a slice of the rescue_quantum_us (default 5ms) quantum divided across the waiters, waits at the tail of the local DSQ claiming no priority, and rejoins its scheduler as a fresh arrival once the slice is served. The schedulers keep their normal control over an admitted rescuee and may preempt or reslice it. Service is measured on CPU time actually received, so neither shortens the rescue. Prolonged denial escalates - the remaining slice turns into protected execution (SCX_TASK_PROTECTED) and the rescuee preempts the current task. Escalation is paced by the same bucket, and delivered service converges on the configured bandwidth no matter how aggressively the schedulers dispatch. Both knobs are root-only and SCX_RESCUE_DISABLE turns rescue off, making SCX_ENQ_RESCUE inserts reject as usual. v2: - Add SCX_OPS_OPEN() fix-ups for the new ops fields so cpu-form schedulers setting them still load on older kernels. (Andrea) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-26tools/sched_ext/include: Regenerate enum_defs.autogen.hTejun Heo
Regenerate enum_defs.autogen.h from the current vmlinux.h to pick up the SCX enum changes accumulated since the last regeneration, including the SCX_REENQ_LOCAL_MAX_REPEAT to SCX_REENQ_MAX_REPEAT rename. Reported-by: Andrea Righi <arighi@nvidia.com> Link: https://lore.kernel.org/all/amZsEbZJdDgjstPF@gpd4/ Signed-off-by: Tejun Heo <tj@kernel.org>
2026-07-24sched_ext: Gate scx_bpf_cidperf_set() behind a new SCX_CAP_PERFTejun Heo
scx_bpf_cidperf_set() reaches cpufreq with no cap check, so any cid-form sub-sched can steer the frequency of any cid in its view, including ones it holds nothing on. Gate it behind a new SCX_CAP_PERF rather than SCX_CAP_BASE: hardware control is a separate axis from queue access - a parent may well delegate scheduling on a cid without handing over its frequency. PERF neither implies nor is implied by the other caps. The check runs under the target rq's lock, which ecaps updates are also folded under, so it is authoritative - a write can never land after a revoke has taken effect. Denials are counted in SCX_EV_SUB_CIDPERF_DENIED. The operation is synchronous and the outcome is reported to the caller: scx_bpf_cidperf_set() now returns 0 or -errno, -EACCES on denial. The cid-form interface is still under initial development, so the signature is changed in place without versioning. scx_qmap grants PERF alongside its existing cid grants so the cpuperf demo keeps working in sub-scheds. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-24tools/sched_ext: Don't restart over a pending exit requestTejun Heo
The tools restart when the kernel exits the scheduler with SCX_ECODE_ACT_RESTART. The restart decision doesn't consult exit_req, so an exit request arriving while the restart condition persists is ignored and the tool reloads in a tight loop. Test exit_req before restarting. scx_userland needs more: its main loop never watches the kernel-side exit and exit_req doubles as the stats printer's stop signal, set by the teardown and reset on each restart. Add the missing UEI_EXITED() test and give the printer its own stop flag so that exit_req only means an exit request and stays latched like in the other tools. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-22tools/sched_ext: scx_pair: Convert to sched_switch TPCheng-Yang Chou
ops.cpu_acquire/release() are deprecated in favor of tracking CPU preemption from a sched_switch tracepoint, see commit a3f5d4822253 ("sched_ext: Allow scx_bpf_reenqueue_local() to be called from anywhere"). Loading scx_pair currently emits a deprecation warning. Replace the pair_cpu_acquire/release() callbacks with a tp_btf/sched_switch program that edge-detects the same transitions the core used to deliver: a release when a running SCX task loses its CPU to a higher-priority class, and an acquire when the CPU switches back to an SCX task or idle while marked preempted. Tasks are classified by effective priority (p->prio) rather than by policy: rt_mutex_setprio() boosts a PI beneficiary into the rt/dl classes while leaving its policy untouched, so a policy test would both miss the release when a boosted task takes the CPU and fire a spurious acquire when a boosted task replaces a real rt task. A switch from idle straight to a higher-priority task is deliberately not treated as a release. The CPU was not running an SCX task, so there is nothing to drain, and kicking SCX_KICK_PREEMPT | SCX_KICK_WAIT on every rt wakeup would make the pair CPU wait out rt bursts it was never coupled to. The old callbacks behaved the same way, firing ops.cpu_release() only from switch_class() when an SCX task was put for a higher class. The tracepoint runs on every context switch in the system, so the common no-transition case is filtered before taking the pair-shared lock. This is safe because a CPU's own preempted_mask bit is only ever written by this tracepoint running on that CPU. sched_setscheduler() on a running task changes class in place without a context switch, so such transitions are only observed at the task's next switch. The old callbacks had the same blind spot in switch_class(), and try_dispatch() already bounds the resulting wait. Verified in virtme-ng with the script below. The scheduler must load without the deprecation warning, stay enabled through the rt churn and the idle soak (the watchdog would otherwise abort it with "runnable task stall"), keep its preemption counter advancing, and unregister cleanly at the end. A PI rt-mutex churn that repeatedly boosts SCX tasks into the rt class was exercised separately: #!/bin/bash # vng --verbose --cpus 8 -m 4G --user root -- ./verify.sh # FIFO harness: survives even if all SCHED_NORMAL tasks stall [ "${RT:-0}" = 1 ] || exec chrt -f 5 env RT=1 "$0" chrt -o 0 ./tools/sched_ext/build/bin/scx_pair & PAIR=$! sleep 3 for round in $(seq 10); do pids="" for i in 0 1 2 3; do # SCHED_FIFO churn chrt -f 10 bash -c \ 'e=$((SECONDS+1)); while [ $SECONDS -lt $e ]; do :; done' & pids="$pids $!" done for i in 0 1; do # SCHED_NORMAL load under scx chrt -o 0 bash -c \ 'n=0; while [ $n -lt 200000 ]; do n=$((n+1)); done' & pids="$pids $!" done wait $pids # explicit pids, not the scx_pair job done sleep 300 # idle soak kill -INT $PAIR # expect clean unregister in dmesg Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-07-19sched_ext: Rename the cid-form cgroup ops to cpuctl_*Tejun Heo
Two unrelated things go by "cgroup" in the cid form. Sub-schedulers attach to cgroups, and the cgroup_*() ops deliver cpu controller events. While the ops names suggest cgroup2 hierarchy, they actually operate on the cpu controller. Rename them to cpuctl_* in struct sched_ext_ops_cid, which has no users outside scx_qmap yet. The cpu form is deployed ABI and keeps the old names. The layout is unchanged and the kernel keeps calling through the cpu-form union view. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-19tools/sched_ext: Add SCX_OPS_CID_OPEN for cid-form schedulersTejun Heo
SCX_OPS_OPEN() clears compat-gated ops fields which the running kernel lacks. The clears dereference cpu-form member names and compile for cid-form skeletons only because both ops structs currently name their cgroup ops identically, which an upcoming rename will end. No load-time fix-up can apply to a cid-form scheduler anyway as the cid form postdates every compat-gated op. Factor the skeleton open path out of SCX_OPS_OPEN() and add SCX_OPS_CID_OPEN() which uses only that shared part. Switch scx_qmap, the only cid-form scheduler, over. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-19tools/sched_ext: scx_qmap - Add init fault injection modesTejun Heo
Add -J init-fail which makes ops.init_task() fail with -ENOMEM for tasks whose comm starts with "qmfail", and -J cgrp-init-fail which does the same in ops.cgroup_init() for cgroups named "qmfail*". The former exercises the migration veto path: the cgroup.procs write must fail with the injected errno while the destination sched stays up and the task stays put. The latter exercises the ownership-return failure path: a parent failing to re-init a returned cgroup leaves it unowned, and moves and set_* ops against it must be skipped instead of dereferencing the missing owner. Matching on "qmfail" names keeps the injecting scheduler's own enable unaffected. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-19tools/sched_ext: scx_qmap - Consume cgroup weights through set_weightTejun Heo
With the set_* ops delivered to the parent's sched, a parent qmap instance now receives cgroup_set_weight for its child subs' attach points. Update the matching sub_sched_ctx weight and redistribute() in-kernel, and drop the userspace feed_weights() polling. This exercises the knob routing end to end. The self weight is fixed at 100: a cgroup's weight is its parent's knob and not the scheduler's own business. This drops the self-weight polling and the repartition PROG_RUN poke with it. sub_attach seeds the slot with the cgroup's current weight, read through bpf_cgroup_from_id(), so a weight set before the sub attaches is picked up. A write racing the attach can still be lost until the next value-changing cpu.weight write. Acceptable for a demo. While at it, add a traced ops.cgroup_move() so tests can observe move delivery. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-17Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 7.2-rc4Kumar Kartikeya Dwivedi
Cross-merge BPF and other fixes after downstream PR. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-14tools/sched_ext: scx_qmap: Fix stale API name in commentLiang Luo
The comment above dispatch_highpri() still references scx_bpf_dispatch[_vtime]_from_dsq(), which was renamed to scx_bpf_dsq_move[_vtime]() in v6.13 to unload the overloaded "dispatch" verb. The code below already uses the new names; only the comment was left behind during the rename. Fixes: 5cbb302880f5 ("sched_ext: Rename scx_bpf_dispatch[_vtime]_from_dsq*() -> scx_bpf_dsq_move[_vtime]*()") Signed-off-by: Liang Luo <luoliang@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-07-13tools/sched_ext: scx_qmap - Add sub-sched cap fault injectionTejun Heo
Add a fault-injection mode to the scx_qmap sub-scheduler that deliberately dispatches one of its own tasks to a cid it does not hold. The kernel cap check must reject it and re-enqueue with SCX_TASK_REENQ_CAP, so the nr_inject_attempts counter tracks nr_reenq_cap one to one, exercising the delivery-time cap enforcement. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13tools/sched_ext: scx_qmap - Expand hierarchical sub-schedulingTejun Heo
sched_ext sub-scheduling began as dispatch delegation only: a parent could call into a child cgroup sub-scheduler's ops.dispatch() from its own dispatch path, but could not delegate cpus to the child for enqueue and the other paths. sched_ext has since gained cap-based cid delegation, where a parent grants and revokes a child's per-cid caps. Expand scx_qmap to demonstrate it. scx_qmap can now delegate the cids it holds exclusively, split among itself and its children by cpu.weight. Each gets the floor of its share as dedicated cids. The leftover from rounding forms a shared pool, round-robined among them as an ENQ_IMMED time-share. This shape is deliberate. Exclusive cids exercise the basic grant and revoke of ownership, and the shared pool exercises time-sharing one cid across several schedulers. The implemented policy is impractical, but it covers most of what a practical sub-scheduler would need without overcomplicating qmap. Delegation nests. A cid a node receives from its parent only as a round-robin share stays self-local and is never re-delegated. A node left with no exclusive cid, e.g. after its cpus went offline, evicts its children. v5: Highpri dispatch masked with self_cids, single-read dispatch cgroup_id, feed_weights race comment. (sashiko AI) v4: Track all idle cids and mask with self_cids at the dispatch pick, dropping the reseed. (sashiko AI) v3: Dispatch IMMED flags, repartition accounting order, partition-input snapshot. (sashiko AI) v2: Use __sync_fetch_and_add() for the shared nr_dsps counter. (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13tools/sched_ext: Add three-mask cmask intersection iteratorTejun Heo
Add cmask_next_and2_set() and its round-robin wrap, extending cmask_next_and_set() to a three-mask intersection: the next cid set in all three masks at or after @start. A caller iterating the intersection of three cmasks can then scan it in one pass, folding the third mask into the word-level AND rather than skipping non-members one candidate at a time. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add scx_bpf_sub_kill() to evict a child sub-schedulerTejun Heo
A cid-form scheduler can grant caps to and revoke them from its child sub-schedulers but has no way to tear one down. Add scx_bpf_sub_kill() to evict a direct child with a printf-style reason that reaches the child's scx_exit_info. No exit code is taken because the child is a separate scheduler whose exit-code semantics the parent cannot know. The child and its subtree are disabled through the usual async path under a new exit kind, SCX_EXIT_PARENT_KILL. The bstr formatting infrastructure in ext.c is exposed through internal.h with scx_ prefixes so the kfunc, which lives in sub.c, can format the reason. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add per-shard cap delegation for sub-schedulersTejun Heo
Caps are per-cid permissions parents delegate to direct children via scx_bpf_sub_grant() / scx_bpf_sub_revoke(). A child's cap set is always a subset of its parent's. Sub-scheds check their caps locally, and cross-sched communication is needed only when the delegation set itself changes. Caps will be used to implement sub-sched scheduling on the enqueue path. Picking a cid for a task at a leaf depends on which cids the leaf is allowed to use, and resolving that programmatically on every enqueue would mean a cross-sched round-trip call chain, possibly retrying if the request can't be granted as-is. The dispatch path is different - it runs as top-down recursion via scx_bpf_sub_dispatch(). Locking is per shard. cid space is split into shards, and each sub-sched has its own pshard->lock for each shard. Operations are broken up on shard boundaries. Different shards never contend. Shards are expected to be topology-aligned and likely to serve as the locality unit when cids are allocated to schedulers, so per-shard lock granularity scales naturally with the allocation pattern. This patch adds the framework with a single dummy cap. Real caps land in later patches. The enable path is reordered for pshards. scx_arena_pool_init() moves ahead of scx_link_sched() so the pshards are allocated before the sched becomes reachable - scx_alloc_pshards() skips allocation when the arena pool isn't initialized. - scx_bpf_sub_grant(): Per-cid all-or-nothing grant to direct child. - scx_bpf_sub_revoke(): Clear caps on @cmask across @child and its subtree. - scx_bpf_sub_caps(): Lockless snapshot of caps on a cid range. /sys/kernel/sched_ext/SCHED/caps shows the caps each scheduler currently holds. v4: Move the pshard[] full build/publish and the err_disable scx_error() recording to earlier patches. (sashiko AI) v3: Build pshard[] fully before publishing it, read it with READ_ONCE. (sashiko AI) v2: Validate ops before scx_link_sched() publishes the sub. (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add shard boundaries to scx_bpf_cid_override()Tejun Heo
An overridden cid mapping invalidates the auto-generated shard layout, so the override call has to provide both. Extend scx_bpf_cid_override() with a shard_start[] array that lists the first cid of each shard (starting at 0, strictly increasing, last shard implicitly extends to num_possible_cpus()). A scheduler that wants only custom shards with the auto-generated cid mapping can read the current mapping and pass it back unchanged. Overridden shards can span NUMA nodes, so scx_shard_node[] is rebuilt by majority count: each shard is assigned to the node that owns the most cpus in it. v2: Snapshot the caller's cpu_to_cid/shard_start arrays before validating. (sashiko AI) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13sched_ext: Add ops.init_cids() to finalize the cid layout before initTejun Heo
A cid-form scheduler that calls scx_bpf_cid_override() to install a custom cid layout can only do so from ops.init(). Enable-path setup that depends on the cid layout thus has to run after ops.init(), and ops.init() itself can't use anything derived from the final layout, which turned out to be too restrictive. Add an ops.init_cids() callback dedicated to finalizing the cid layout. It runs before the rest of the enable-path setup, so the final layout is in effect for everything that follows including ops.init(), which now runs after the arena pool and cmask scratch allocations. scx_bpf_cid_override() is restricted to ops.init_cids() at load time. It sits in a kfunc set gated by SCX_KF_ALLOW_INIT_CIDS, a flag set only on the init_cids op, so the verifier rejects a call from any other context. The runtime root-only check is dropped as ops.init_cids() only runs during root enable. The qmap demo moves its override into a dedicated qmap_init_cids() and, while at it, introduces an enum for the cid override modes instead of hard-coded integers. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-13tools/sched_ext: scx_flatcg: Fix uninitialized stats on allocation failureLiang Luo
In fcg_read_stats(), the memset() that zeroes the output @stats array sits after the calloc() failure check. When calloc() fails, the function returns without writing @stats. The caller in main() declares acc_stats uninitialized, passes it as the @stats argument, and then reads it unconditionally: __u64 acc_stats[FCG_NR_STATS]; fcg_read_stats(skel, acc_stats); stats[i] = acc_stats[i] - last_stats[i]; // reads garbage Because fcg_read_stats() returns void, the caller cannot detect the failure. Reading the uninitialized array is undefined behavior, and the garbage is further copied into last_stats via memcpy(), corrupting the baseline used by the next interval. This regression was introduced by commit cabd76bbc036 ("tools/sched_ext: scx_flatcg: fix potential stack overflow from VLA in fcg_read_stats"), which replaced the VLA with calloc() and inserted the failure check before the existing memset(). Move the memset() above the calloc() failure check so @stats is always zeroed regardless of allocation outcome. Fixes: cabd76bbc036 ("tools/sched_ext: scx_flatcg: fix potential stack overflow from VLA in fcg_read_stats") Signed-off-by: Liang Luo <luoliang@kylinos.cn> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-07-12bpf: Require a BPF cpumask for bpf_cpumask_populate()Nicholas Dudar
bpf_cpumask_populate() writes to its destination with bitmap_copy(), but the destination is typed as struct cpumask *. That allows the verifier to accept borrowed cpumask pointers returned by read-only kfuncs, such as scx_bpf_get_online_cpumask(), as a writable destination. Make the destination a struct bpf_cpumask * so populate follows the same ownership rule as the other mutating cpumask kfuncs. Query kfuncs continue to accept const struct cpumask * inputs. Fixes: 950ad93df2fc ("bpf: add kfunc for populating cpumask bits") Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com> Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/bpf/20260709182800.2037938-2-main.kalliope@gmail.com Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-09sched_ext: Make scx_bpf_kick_cid() return voidTejun Heo
scx_bpf_kick_cid() returned an error code, but the value conveys nothing actionable and no caller consumes it. The kick is asynchronous, so a successful return only means it was queued. An invalid @cid is already reported through scx_error() by scx_cid_to_cpu(), and a missing scheduler leaves nothing to kick. Make scx_bpf_kick_cid() return void to match scx_bpf_kick_cpu(). The cid-form kfuncs are not in practical use yet, so the ABI change is safe. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-09tools/sched_ext: scx_qmap - Use bare u64/u32/s32 integer typesTejun Heo
scx_qmap.c and the shared scx_qmap.h mixed __u64/__u32/__s32 with the bare typedefs that scx/common.h provides. Convert the remaining __-prefixed integer types to the bare forms for consistency. The struct fields become bare u64 (uint64_t), so the stats printfs that fed them to %llu now cast to unsigned long long. No functional change. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-07-09Merge branch 'for-7.2-fixes' into for-7.3Tejun Heo
Pull to receive: db4e9defd2e8 ("sched_ext: Record an error on errno-only sub-enable failure") 49b3378a750c ("sched_ext: Fix premature ops->priv publication in scx_alloc_and_add_sched()") e6979d05c6a6 ("tools/sched_ext: scx - Fix cmask_subset(), cmask_equal() and cmask_weight()") for further sub-sched changes and to resolve the conflicts with the sub-sched updates on for-7.3. db4e9defd2e8 adds scx_error() to the sub-enable err_disable sink which for-7.3 moved from ext.c into sub.c. Resolved by applying the fix to scx_sub_enable_workfn() in sub.c. 49b3378a750c drops RCU_INIT_POINTER() from an scx_alloc_and_add_sched() unwind label whose body changed with for-7.3's stall_cpus addition. Resolved by dropping the line from the updated unwind. Signed-off-by: Tejun Heo <tj@kernel.org>
2026-07-09tools/sched_ext: scx - Fix cmask_subset(), cmask_equal() and cmask_weight()Tejun Heo
cmask_equal(), cmask_weight() and cmask_subset() bounded their word walks with CMASK_NR_WORDS(nr_cids), which pads by one word and can't tell the last word in use without @base. The walks could thus cover a slack word past the active range, which cmask_reframe() leaves non-zero: a stale bit there gave cmask_equal() a spurious mismatch, cmask_weight() an inflated count, and cmask_subset() a spurious violation. cmask_subset() could also read @b->bits[] one word past its allocation (within the arena's fault-recovered range, so harmless), and deviated from the kernel scx_cmask_subset() by failing any @a range that doesn't nest inside @b's even when the overhanging bits are all clear. Bound the cmask_equal() and cmask_weight() walks by the words the range actually spans, with early returns for empty ranges. Rewrite cmask_subset() to match the kernel semantics: scan @a's overhangs for set bits with cmask_next_set() and walk the words of the range intersection. cmask_subset() moves below cmask_next_set(), which it now uses. Padding bits don't need masking as every cmask helper keeps them clear. Fixes: a58e6b79b432 ("sched_ext: Add cmask, a base-windowed bitmap over cid space") Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-06-30tools/sched_ext: use btf_vlen() helper in compat.hLiang Luo
__COMPAT_read_enum() and __COMPAT_struct_has_field() open-code the vlen lookup via the raw BTF_INFO_VLEN(t->info) UAPI macro. libbpf exposes btf_vlen() for exactly this purpose; use it in the three call sites, matching the pattern in kernel/bpf/inode.c and tools/bpf/bpftool. btf_vlen() returns __u32 (since commit cacd6729c0923, "libbpf: Adjust btf_vlen() to return a __u32", which expanded the BTF vlen field from 16 to 24 bits). Declare the loop counters as __u32 to match the return type, keeping the comparison as a plain '__u32 < __u32' and silencing the -Wsign-compare warnings. No functional change. Suggested-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Liang Luo <luoliang@kylinos.cn> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-06-26tools/sched_ext: fix getopt() option variable signednessLiang Luo
Four example schedulers (scx_simple, scx_cpu0, scx_sdt, scx_userland) declare the variable that holds getopt()'s return value as __u32. getopt() returns int and uses -1 to mark end-of-options; storing that sentinel in an unsigned variable turns it into 0xffffffff, and the subsequent 'opt != -1' test only happens to keep working because both operands of != are promoted to the same 0xffffffff. Declare the variable as __s32 instead, matching getopt()'s actual contract and the style already used in scx_qmap.c (int opt) and scx_pair/central/flatcg.c (__s32 opt). This also silences the -Wsign-compare warnings emitted for the affected files. Signed-off-by: Liang Luo <luoliang@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-06-24sched_ext/scx_flatcg: Fix cvtime_delta race and add hweight scaling to ↵Wanwu Li
bypass charging 1. cgrp_cap_budget() used __sync_fetch_and_sub(&cgc->cvtime_delta, cgc->cvtime_delta) to atomically read and clear cvtime_delta. However, this is not a true atomic read-clear operation: the second argument (cgc->cvtime_delta) is evaluated as a normal read before the atomic fetch_and_sub executes. If a concurrent __sync_fetch_and_add() happens between the read and the sub, the added value gets included in the returned delta AND remains in cvtime_delta, causing double charging. Example: CPU 0 runs cgrp_cap_budget(), CPU 1 runs fcg_stopping(). Assume cvtime_delta = 100 initially. T1 CPU 0: sub_val = cvtime_delta = 100 cvtime_delta = 100 T2 CPU 1: __sync_fetch_and_add(&cvtime_delta, 10) cvtime_delta = 110 T3 CPU 0: __sync_fetch_and_sub(&cvtime_delta, sub_val) cvtime_delta = 10 returns old=110 delta = 110 (includes the 10 from CPU 1), but cvtime_delta = 10 (the 10 also remains). The 10 is charged twice: once in delta (applied to cgv_node->cvtime) and once in the residual cvtime_delta (fetched again next time). Fix by using __sync_fetch_and_and(&cgc->cvtime_delta, 0). Disassembly comparison: (1) delta = __sync_fetch_and_sub(&cgc->cvtime_delta, cgc->cvtime_delta); 228: (79) r7 = *(u64 *)(r9 +40) 229: (87) r7 = -r7 230: (db) r7 = atomic64_fetch_add((u64 *)(r9 +40), r7) //r9 may be changed (2) delta = __sync_fetch_and_and(&cgc->cvtime_delta, 0); 228: (b7) r8 = 0 229: (db) r8 = atomic64_xchg((u64 *)(r9 +40), r8) 2. The bypass charging path in fcg_stopping() charges raw execution time to cvtime_delta without scaling by the inverse of the cgroup hweight. Since cvtime_delta is eventually applied to cgv_node->cvtime which is in vtime space (weight-scaled), the bypass path should also scale by FCG_HWEIGHT_ONE / hweight to match the units used by the dispatch path. Fixes: a4103eacc2ab ("sched_ext: Add a cgroup scheduler which uses flattened hierarchy") Signed-off-by: Wanwu Li <liwanwu@kylinos.cn> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-06-24sched_ext: Remove deprecated scx_bpf_cpu_rq()Christian Loehle
scx_bpf_cpu_rq() exposes rq pointers without requiring the rq lock and has emitted a deprecation warning since commit 5c48d88fe004 ("sched_ext: deprecation warn for scx_bpf_cpu_rq()"). The supported replacements cover the intended uses: scx_bpf_locked_rq() for locked rq access and scx_bpf_cpu_curr() for remote curr lookup. Remove the kfunc, its BTF registrations, the deprecation warning state, and the BPF-side prototype and compat fallback. Signed-off-by: Christian Loehle <christian.loehle@arm.com> Reviewed-by: Andrea Righi <arighi@nvidia.com> Reviewed-by: Hongyan Xia <hongyan.xia@transsion.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-06-22sched_ext: Move sources under kernel/sched/ext/Tejun Heo
The sched_ext sources had grown to ten ext* files directly under kernel/sched/. Move them into a new kernel/sched/ext/ subdirectory and drop the now-redundant ext_ prefix. ext.c/h keep their names. kernel/sched/ext.{c,h} -> kernel/sched/ext/ext.{c,h} kernel/sched/ext_internal.h -> kernel/sched/ext/internal.h kernel/sched/ext_types.h -> kernel/sched/ext/types.h kernel/sched/ext_idle.{c,h} -> kernel/sched/ext/idle.{c,h} kernel/sched/ext_cid.{c,h} -> kernel/sched/ext/cid.{c,h} kernel/sched/ext_arena.{c,h} -> kernel/sched/ext/arena.{c,h} The include paths in build_policy.c and sched.h, the MAINTAINERS glob, and a few documentation and comment references are updated to match. No code or symbol changes. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-06-17Merge tag 'sched_ext-for-7.2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext Pull sched_ext updates from Tejun Heo: "Most of this continues the in-development sub-scheduler support, which lets a root BPF scheduler delegate to nested sub-schedulers. The dispatch-path building blocks landed in 7.1. A follow-up patchset in development will complete enqueue-path support for hierarchical scheduling. This cycle adds most of that infrastructure: - Topological CPU IDs (cids): a dense, topology-ordered CPU numbering where the CPUs of a core, LLC, or NUMA node form contiguous ranges, so a topology unit becomes a (start, length) slice. Raw CPU numbers are sparse and don't track topological closeness, which makes them clumsy for sharding work across sub-schedulers and awkward in BPF. - cmask: bitmaps windowed over a slice of cid space, so a sub-scheduler can track, for example, the idle cids of its shard without a full NR_CPUS cpumask. - A struct_ops variant that cid-form sub-schedulers register with, along with the cid-form kfuncs they call. - BPF arena integration, which sub-scheduler support is built on. The bpf-next additions let the kernel read and write the BPF scheduler's arena directly, turning it into a real kernel/BPF shared-memory channel. Shared state like the per-CPU cmask now lives there. - scx_qmap is reworked to exercise the new arena and cid interfaces. Additionally: - Exit-dump improvements: dump the faulting CPU first, expose the exit CPU to BPF and userspace, and normalize the dump header. - Misc kfuncs and cleanups: a task-ID lookup kfunc, __printf checking on the error and dump formatters, header reorganization, and assorted fixes" * tag 'sched_ext-for-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext: (59 commits) sched_ext: Add scx_arena_to_kaddr() / scx_kaddr_to_arena() sched_ext: Make scx_bpf_kick_cid() return s32 sched_ext: Add scx_cmask_test() and scx_cmask_for_each_cid() tools/sched_ext: Order single-cid cmask helpers as (cid, mask) sched_ext: Order single-cid cmask helpers as (cid, mask) selftests/sched_ext: Fix dsq_move_to_local check sched_ext: Guard BPF arena helper calls to fix 32-bit build sched_ext: idle: Fix errno loss in scx_idle_init() sched_ext: Convert ops.set_cmask() to arena-resident cmask sched_ext: Sub-allocator over kernel-claimed BPF arena pages sched_ext: Require an arena for cid-form schedulers sched_ext: Add cmask mask ops sched_ext: Track bits[] storage size in struct scx_cmask sched_ext: Rename scx_cmask.nr_bits to nr_cids tools/sched_ext: scx_qmap: Fix qa arena placement sched_ext: Mark !CONFIG_EXT_SUB_SCHED dummy stubs static inline sched_ext: Replace tryget_task_struct() with get_task_struct() sched_ext: Add scx_task_iter_relock() and use it in scx_root_enable_workfn() sched_ext: Fix ops_cid layout assert sched_ext: Use offsetofend on both sides of the ops_cid layout assert ...
2026-06-03sched_ext: Make scx_bpf_kick_cid() return s32Tejun Heo
Switch scx_bpf_kick_cid() from void to s32 so future cap enforcement can surface failures. cid interface is introduced in this cycle and has no external users, so the ABI change is safe. Subsequent patches will add -EPERM returns when the calling sub-sched lacks the required cap on the target cid. v2: Return scx_cid_to_cpu()'s errno instead of -EINVAL. (Andrea) Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-06-03tools/sched_ext: Order single-cid cmask helpers as (cid, mask)Tejun Heo
The BPF arena single-cid cmask helpers take the cmask first and the cid second. Reorder them to (cid, mask) to match the kernel-side helpers and the test_bit(nr, addr), cpumask_test_cpu(cpu, mask) convention. Range and iteration helpers keep (mask, start). Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
2026-05-27tools/sched_ext: Fix scx_show_state per-scheduler state readsZicheng Qu
scx_show_state.py still reads scx_aborting and scx_bypass_depth as global symbols. Those symbols no longer exist after the state was moved into struct scx_sched, so the drgn script fails when it reaches either field. Read aborting and bypass_depth from scx_root instead. This preserves the script's current root-scheduler view: with sub-scheduler support, the reported values are for the root scheduler and sub-schedulers are not enumerated. Fixes: 5c8d98a1b4de ("sched_ext: Move bypass state into scx_sched") Fixes: c1743da43cf5 ("sched_ext: Move aborting flag to per-scheduler field") Signed-off-by: Zicheng Qu <quzicheng@huawei.com> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>