* [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes
@ 2026-08-15 5:51 Tejun Heo
2026-08-15 5:51 ` [PATCH 1/2] sched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable() Tejun Heo
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Tejun Heo @ 2026-08-15 5:51 UTC (permalink / raw)
To: David Vernet, Andrea Righi, Changwoo Min
Cc: sched-ext, linux-kernel, Emil Tsalapatis
Hello,
Two unrelated small fixes.
0001-sched_ext-Drop-unlocked-scx_rq_clock_invalidate-from.patch
0002-sched_ext-Make-scx_bpf_events-read-the-calling-sched.patch
0001 drops the rq clock invalidation in the root disable path which was
performed without holding the rq lock and is redundant anyway. 0002 makes
scx_bpf_events() read the event counters of the scheduler associated with
the calling program instead of always reading the root scheduler's.
diffstat follows.
kernel/sched/ext/ext.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
The patches are also applied to sched_ext/for-7.3.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext.git for-7.3
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] sched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable()
2026-08-15 5:51 [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes Tejun Heo
@ 2026-08-15 5:51 ` Tejun Heo
2026-08-15 9:42 ` [PATCH v2 " Tejun Heo
2026-08-15 5:51 ` [PATCH 2/2] sched_ext: Make scx_bpf_events() read the calling scheduler's counters Tejun Heo
2026-08-15 10:03 ` [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes Tejun Heo
2 siblings, 1 reply; 5+ messages in thread
From: Tejun Heo @ 2026-08-15 5:51 UTC (permalink / raw)
To: David Vernet, Andrea Righi, Changwoo Min
Cc: sched-ext, linux-kernel, Emil Tsalapatis, Tejun Heo
scx_root_disable() invalidates each rq's clock before taking the rq lock.
scx_rq_clock_invalidate() is a plain read-modify-write of rq->scx.flags and
every other writer of the word runs under the rq lock, so the unlocked
update can race a concurrent flags update and lose one side's bits.
The invalidation is also redundant. The dl_server rebalancing right below
cycles each rq's lock and rq_unpin_lock() clears SCX_RQ_CLK_VALID on every
unlock, while __scx_enabled is turned off only later in the function, so the
clocks end up invalidated either way. Drop the call and note the
invalidation in the comment.
Fixes: 3a9910b5904d ("sched_ext: Implement scx_bpf_now()")
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Changwoo Min <changwoo@igalia.com>
---
kernel/sched/ext/ext.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 2adf2bde0cb1..d301fe757193 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -6476,12 +6476,13 @@ static void scx_root_disable(struct scx_sched *sch)
percpu_up_write(&scx_fork_rwsem);
/*
- * Invalidate all the rq clocks to prevent getting outdated
- * rq clocks from a previous scx scheduler.
+ * Re-balance the dl_server bandwidth reservations: detach ext_server
+ * (no more sched_ext tasks) and reinstate fair_server if it was
+ * previously detached because we were running in full mode.
*
- * Also re-balance the dl_server bandwidth reservations: detach
- * ext_server (no more sched_ext tasks) and reinstate fair_server if it
- * was previously detached because we were running in full mode.
+ * The rq lock cycle also invalidates each rq's clock (rq_unpin_lock()
+ * clears SCX_RQ_CLK_VALID on unlock), preventing the next enable from
+ * seeing outdated rq clocks from this scheduler.
*
* Unlike the enable path, this runs on a recovery path that cannot
* fail, so we use dl_server_swap_bw() to atomically free ext_server's
@@ -6494,8 +6495,6 @@ static void scx_root_disable(struct scx_sched *sch)
for_each_possible_cpu(cpu) {
struct rq *rq = cpu_rq(cpu);
- scx_rq_clock_invalidate(rq);
-
scoped_guard(rq_lock_irqsave, rq) {
update_rq_clock(rq);
if (was_switched_all) {
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] sched_ext: Make scx_bpf_events() read the calling scheduler's counters
2026-08-15 5:51 [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes Tejun Heo
2026-08-15 5:51 ` [PATCH 1/2] sched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable() Tejun Heo
@ 2026-08-15 5:51 ` Tejun Heo
2026-08-15 10:03 ` [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes Tejun Heo
2 siblings, 0 replies; 5+ messages in thread
From: Tejun Heo @ 2026-08-15 5:51 UTC (permalink / raw)
To: David Vernet, Andrea Righi, Changwoo Min
Cc: sched-ext, linux-kernel, Emil Tsalapatis, Tejun Heo
scx_bpf_events() always reads the root scheduler's event counters, so a
sub-scheduler program querying its own events silently gets the root's
instead and has no BPF-visible way to read its own (the per-scheduler sysfs
"events" file is the only interface). Resolve the scheduler from the calling
program with scx_prog_sched(). Unassociated programs follow the usual
scx_prog_sched() resolution: the root scheduler under a pre-sub-attach
compat root and zeroed counters otherwise.
Also fix up the malformed comment into proper kerneldoc.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
kernel/sched/ext/ext.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index d301fe757193..b9060c318c3c 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -10608,19 +10608,23 @@ static void scx_read_events(struct scx_sched *sch, struct scx_event_stats *event
}
}
-/*
- * scx_bpf_events - Get a system-wide event counter to
+/**
+ * scx_bpf_events - Read the event counters of the calling scheduler
* @events: output buffer from a BPF program
- * @events__sz: @events len, must end in '__sz'' for the verifier
+ * @events__sz: @events len, must end in '__sz' for the verifier
+ * @aux: implicit BPF argument to access bpf_prog_aux hidden from BPF progs
+ *
+ * Read the event counters of the scheduler associated with the calling program.
+ * @events is zeroed when no scheduler can be resolved.
*/
-__bpf_kfunc void scx_bpf_events(struct scx_event_stats *events,
- size_t events__sz)
+__bpf_kfunc void scx_bpf_events(struct scx_event_stats *events, size_t events__sz,
+ const struct bpf_prog_aux *aux)
{
struct scx_sched *sch;
struct scx_event_stats e_sys;
rcu_read_lock();
- sch = rcu_dereference(scx_root);
+ sch = scx_prog_sched(aux);
if (sch)
scx_read_events(sch, &e_sys);
else
@@ -10743,7 +10747,7 @@ BTF_ID_FLAGS(func, scx_bpf_cpu_curr, KF_IMPLICIT_ARGS | KF_RET_NULL | KF_RCU_PRO
BTF_ID_FLAGS(func, scx_bpf_cid_curr, KF_IMPLICIT_ARGS | KF_RET_NULL | KF_RCU_PROTECTED)
BTF_ID_FLAGS(func, scx_bpf_tid_to_task, KF_RET_NULL | KF_RCU_PROTECTED)
BTF_ID_FLAGS(func, scx_bpf_now)
-BTF_ID_FLAGS(func, scx_bpf_events)
+BTF_ID_FLAGS(func, scx_bpf_events, KF_IMPLICIT_ARGS)
#ifdef CONFIG_CGROUP_SCHED
BTF_ID_FLAGS(func, scx_bpf_task_cgroup, KF_IMPLICIT_ARGS | KF_RCU | KF_ACQUIRE)
#endif
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] sched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable()
2026-08-15 5:51 ` [PATCH 1/2] sched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable() Tejun Heo
@ 2026-08-15 9:42 ` Tejun Heo
0 siblings, 0 replies; 5+ messages in thread
From: Tejun Heo @ 2026-08-15 9:42 UTC (permalink / raw)
To: David Vernet, Andrea Righi, Changwoo Min
Cc: sched-ext, linux-kernel, Emil Tsalapatis
scx_root_disable() invalidates each rq's clock before taking the rq lock.
scx_rq_clock_invalidate() is a plain read-modify-write of rq->scx.flags and
every other writer of the word runs under the rq lock, so the unlocked
update can race a concurrent flags update and lose one side's bits.
The invalidation doesn't matter in the first place. The cached clock is read
only by scx_bpf_now() from a loaded scheduler's BPF programs, nothing can
re-validate the clock while sched_ext is disabled as scx_rq_clock_update()
is gated on scx_enabled() too, and the usual rq lock cycles under the next
scheduler refresh or invalidate it before it's practically observable. Drop
the invalidation instead of fixing the locking.
v2: Description and comment updated - the invalidation is unnecessary rather
than subsumed by the rq lock cycle below.
Fixes: 3a9910b5904d ("sched_ext: Implement scx_bpf_now()")
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Changwoo Min <changwoo@igalia.com>
---
kernel/sched/ext/ext.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -6367,12 +6367,9 @@ static void scx_root_disable(struct scx_
percpu_up_write(&scx_fork_rwsem);
/*
- * Invalidate all the rq clocks to prevent getting outdated
- * rq clocks from a previous scx scheduler.
- *
- * Also re-balance the dl_server bandwidth reservations: detach
- * ext_server (no more sched_ext tasks) and reinstate fair_server if it
- * was previously detached because we were running in full mode.
+ * Re-balance the dl_server bandwidth reservations: detach ext_server
+ * (no more sched_ext tasks) and reinstate fair_server if it was
+ * previously detached because we were running in full mode.
*
* Unlike the enable path, this runs on a recovery path that cannot
* fail, so we use dl_server_swap_bw() to atomically free ext_server's
@@ -6385,8 +6382,6 @@ static void scx_root_disable(struct scx_
for_each_possible_cpu(cpu) {
struct rq *rq = cpu_rq(cpu);
- scx_rq_clock_invalidate(rq);
-
scoped_guard(rq_lock_irqsave, rq) {
update_rq_clock(rq);
if (was_switched_all) {
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes
2026-08-15 5:51 [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes Tejun Heo
2026-08-15 5:51 ` [PATCH 1/2] sched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable() Tejun Heo
2026-08-15 5:51 ` [PATCH 2/2] sched_ext: Make scx_bpf_events() read the calling scheduler's counters Tejun Heo
@ 2026-08-15 10:03 ` Tejun Heo
2 siblings, 0 replies; 5+ messages in thread
From: Tejun Heo @ 2026-08-15 10:03 UTC (permalink / raw)
To: David Vernet, Andrea Righi, Changwoo Min
Cc: sched-ext, linux-kernel, Emil Tsalapatis
Applied to sched_ext/for-7.3 with the v2 description for the first patch.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-15 10:03 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-15 5:51 [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes Tejun Heo
2026-08-15 5:51 ` [PATCH 1/2] sched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable() Tejun Heo
2026-08-15 9:42 ` [PATCH v2 " Tejun Heo
2026-08-15 5:51 ` [PATCH 2/2] sched_ext: Make scx_bpf_events() read the calling scheduler's counters Tejun Heo
2026-08-15 10:03 ` [PATCHSET sched_ext/for-7.3] sched_ext: Misc fixes Tejun Heo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox