From: Andrea Righi <arighi@nvidia.com>
To: Tejun Heo <tj@kernel.org>, David Vernet <void@manifault.com>,
Changwoo Min <changwoo@igalia.com>,
John Stultz <jstultz@google.com>
Cc: Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Juri Lelli <juri.lelli@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Steven Rostedt <rostedt@goodmis.org>,
Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
Valentin Schneider <vschneid@redhat.com>,
K Prateek Nayak <kprateek.nayak@amd.com>,
Christian Loehle <christian.loehle@arm.com>,
David Dai <david.dai@linux.dev>, Koba Ko <kobak@nvidia.com>,
Aiqun Yu <aiqun.yu@oss.qualcomm.com>,
Shuah Khan <shuah@kernel.org>,
sched-ext@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [PATCH 11/14] sched_ext: Delegate proxy donor admission to BPF schedulers
Date: Sat, 25 Jul 2026 18:04:17 +0200 [thread overview]
Message-ID: <20260725160513.57477-12-arighi@nvidia.com> (raw)
In-Reply-To: <20260725160513.57477-1-arighi@nvidia.com>
Proxy execution keeps a mutex-blocked donor runnable so that its
scheduling context can execute the mutex owner.
Define SCX_OPS_ENQ_BLOCKED as both an admission contract and an
ownership rule for retained donors. Schedulers without the flag block
EXT donors normally. Schedulers with the flag continue to own blocked
donors and receive them through ops.enqueue() with SCX_ENQ_BLOCKED,
allowing BPF to choose their DSQ, CPU and ordering.
Once BPF dispatches a donor, proxy execution may move its scheduling
context to the mutex owner's rq. This move is distinct from BPF
placement: wake_cpu continues to identify the donor's callback CPU,
while task_cpu() identifies the proxy CPU. When the donor wakes, the
normal wakeup path uses wake_cpu as prev_cpu when returning the task to
the BPF scheduler, which can then choose its next placement normally.
Apply the same admission contract across scheduler ownership changes: a
retained donor moving into a scheduler without SCX_OPS_ENQ_BLOCKED is
fully deactivated and remains on the mutex wait path; a donor moving
into an opted-in scheduler remains queued and is handed to that
scheduler. Tasks without an assigned scheduler retain the generic
proxy-execution fallback during the transition.
Blocked-donor enqueueing takes precedence over the exiting and
migration-disabled local-DSQ fallbacks, so that an opted-in scheduler
sees every eligible donor request.
Putting these rules together, the donor admission flow is the following:
D ------ blocked on -----> M ------ owned by -----> O
[donor] [mutex] [owner]
|
v
+--------------------------+
| SCX_OPS_ENQ_BLOCKED set? |
+------------+-------------+
no | yes
+------+-------+
| |
v v
block normally D runnable
|
v
ops.enqueue(D, SCX_ENQ_BLOCKED)
|
v
BPF admission policy
|
D selected
|
v
proxy-exec resolves
D -> M -> O
|
v
rq->donor = D
rq->curr = O
|
O releases M
|
v
D returns through
the wakeup path
|
v
BPF handles D as
an unblocked task
Co-developed-by: John Stultz <jstultz@google.com>
Signed-off-by: John Stultz <jstultz@google.com>
Signed-off-by: Andrea Righi <arighi@nvidia.com>
---
include/linux/sched/ext.h | 1 +
kernel/sched/ext/ext.c | 155 ++++++++++++++++--
kernel/sched/ext/internal.h | 23 ++-
kernel/sched/ext/sub.c | 6 +-
tools/sched_ext/include/scx/compat.h | 1 +
.../sched_ext/include/scx/enum_defs.autogen.h | 1 +
.../sched_ext/include/scx/enums.autogen.bpf.h | 3 +
tools/sched_ext/include/scx/enums.autogen.h | 1 +
8 files changed, 171 insertions(+), 20 deletions(-)
diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h
index 4d16c225e9af1..c0fe88c2a9010 100644
--- a/include/linux/sched/ext.h
+++ b/include/linux/sched/ext.h
@@ -103,6 +103,7 @@ enum scx_ent_flags {
SCX_TASK_SUB_INIT = 1 << 4, /* task being initialized for a sub sched */
SCX_TASK_IMMED = 1 << 5, /* task is on local DSQ with %SCX_ENQ_IMMED */
SCX_TASK_RUN_TRACKED = 1 << 6, /* task is in an ops.running()/stopping() session */
+ SCX_TASK_ENQ_WAKEUP = 1 << 7, /* wakeup enqueue awaiting wakeup_preempt() */
/*
* Bits 8 to 10 are used to carry task state:
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index c6720e5c78dad..7bd1b801448da 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -26,15 +26,51 @@ DEFINE_RAW_SPINLOCK(scx_sched_lock);
bool scx_allow_proxy_exec(const struct task_struct *p)
{
- return p->sched_class != &ext_sched_class;
+ struct scx_sched *sch;
+
+ if (p->sched_class != &ext_sched_class)
+ return true;
+
+ /*
+ * scx_enabled() may change while __schedule() holds only @p's rq lock.
+ * Once @p is associated with a scheduler, use that scheduler's policy
+ * even while the global enable state is transitioning.
+ */
+ sch = scx_task_sched(p);
+ return !sch || (sch->ops.flags & SCX_OPS_ENQ_BLOCKED);
}
static void prepare_switch_scx(struct rq *rq, struct task_struct *p)
{
+ struct scx_sched *sch;
+
lockdep_assert_held(&p->pi_lock);
lockdep_assert_rq_held(rq);
- sched_proxy_block_task(task_rq(p), p);
+ sch = scx_task_sched(p);
+ if (WARN_ON_ONCE(!sch))
+ return;
+
+ /* Block retained donors that the incoming scheduler cannot manage. */
+ if (!(sch->ops.flags & SCX_OPS_ENQ_BLOCKED))
+ sched_proxy_block_task(rq, p);
+}
+
+/*
+ * Called with @p's pi and rq locks held immediately before
+ * sched_change_begin(). The caller must pass DEQUEUE_NOCLOCK so the rq clock
+ * is updated only once.
+ */
+void scx_prepare_task_sched_change(struct task_struct *p, struct scx_sched *sch)
+{
+ lockdep_assert_held(&p->pi_lock);
+ lockdep_assert_rq_held(task_rq(p));
+
+ update_rq_clock(task_rq(p));
+
+ /* Block retained donors that the incoming scheduler cannot manage. */
+ if (!(sch->ops.flags & SCX_OPS_ENQ_BLOCKED))
+ sched_proxy_block_task(task_rq(p), p);
}
/*
@@ -1916,6 +1952,7 @@ void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags,
struct scx_sched *sch = scx_task_sched(p);
struct task_struct **ddsp_taskp;
struct scx_dispatch_q *dsq;
+ bool enq_blocked;
unsigned long qseq;
WARN_ON_ONCE(!(p->scx.flags & SCX_TASK_QUEUED));
@@ -1948,18 +1985,24 @@ void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags,
if (p->scx.ddsp_dsq_id != SCX_DSQ_INVALID)
goto direct;
- /* see %SCX_OPS_ENQ_EXITING */
- if (!(sch->ops.flags & SCX_OPS_ENQ_EXITING) &&
- unlikely(p->flags & PF_EXITING)) {
- __scx_add_event(sch, SCX_EV_ENQ_SKIP_EXITING, 1);
- goto local;
- }
+ enq_blocked = (sch->ops.flags & SCX_OPS_ENQ_BLOCKED) &&
+ p->is_blocked && !(enq_flags & SCX_ENQ_WAKEUP);
+ if (enq_blocked) {
+ enq_flags |= SCX_ENQ_BLOCKED;
+ } else {
+ /* see %SCX_OPS_ENQ_EXITING */
+ if (!(sch->ops.flags & SCX_OPS_ENQ_EXITING) &&
+ unlikely(p->flags & PF_EXITING)) {
+ __scx_add_event(sch, SCX_EV_ENQ_SKIP_EXITING, 1);
+ goto local;
+ }
- /* see %SCX_OPS_ENQ_MIGRATION_DISABLED */
- if (!(sch->ops.flags & SCX_OPS_ENQ_MIGRATION_DISABLED) &&
- is_migration_disabled(p)) {
- __scx_add_event(sch, SCX_EV_ENQ_SKIP_MIGRATION_DISABLED, 1);
- goto local;
+ /* see %SCX_OPS_ENQ_MIGRATION_DISABLED */
+ if (!(sch->ops.flags & SCX_OPS_ENQ_MIGRATION_DISABLED) &&
+ is_migration_disabled(p)) {
+ __scx_add_event(sch, SCX_EV_ENQ_SKIP_MIGRATION_DISABLED, 1);
+ goto local;
+ }
}
if (unlikely(!SCX_HAS_OP(sch, enqueue)))
@@ -2064,8 +2107,17 @@ static void enqueue_task_scx(struct rq *rq, struct task_struct *p, int core_enq_
int sticky_cpu = p->scx.sticky_cpu;
u64 enq_flags = core_enq_flags | rq->scx.remote_activate_enq_flags;
- if (enq_flags & ENQUEUE_WAKEUP)
+ /*
+ * p->is_blocked is cleared after wakeup_preempt(), so remember whether
+ * this is a full wakeup activation. If wakeup_preempt_scx() isn't called,
+ * set_next_task_scx() or a subsequent non-wakeup enqueue clears the flag.
+ */
+ if (enq_flags & ENQUEUE_WAKEUP) {
rq->scx.flags |= SCX_RQ_IN_WAKEUP;
+ p->scx.flags |= SCX_TASK_ENQ_WAKEUP;
+ } else {
+ p->scx.flags &= ~SCX_TASK_ENQ_WAKEUP;
+ }
/*
* Restoring the current scheduling context will be immediately followed
@@ -2270,11 +2322,24 @@ static void wakeup_preempt_scx(struct rq *rq, struct task_struct *p, int wake_fl
{
/*
* Preemption between SCX tasks is implemented by resetting the victim
- * task's slice to 0 and triggering reschedule on the target CPU.
- * Nothing to do.
+ * task's slice to 0 and triggering reschedule on the target CPU. A
+ * mutex-blocked task is kept queued for proxy execution, so its wakeup
+ * doesn't go through enqueue_task_scx(). If the BPF scheduler manages
+ * blocked donors, reschedule explicitly so that it can reconsider a
+ * donor it declined to dispatch while blocked.
*/
- if (p->sched_class == &ext_sched_class)
+ if (p->sched_class == &ext_sched_class) {
+ bool enq_wakeup = p->scx.flags & SCX_TASK_ENQ_WAKEUP;
+
+ p->scx.flags &= ~SCX_TASK_ENQ_WAKEUP;
+ if (!enq_wakeup && p->is_blocked) {
+ struct scx_sched *sch = scx_task_sched(p);
+
+ if (sch && (sch->ops.flags & SCX_OPS_ENQ_BLOCKED))
+ resched_curr(rq);
+ }
return;
+ }
/*
* Getting preempted by a higher-priority class. Reenqueue IMMED tasks.
@@ -2389,6 +2454,20 @@ static bool task_can_run_on_remote_rq(struct scx_sched *sch,
WARN_ON_ONCE(task_cpu(p) == cpu);
+ /*
+ * A blocked donor may be moved normally to select a new callback rq.
+ * set_task_cpu() updates wake_cpu and makes the destination rq its new
+ * callback home.
+ *
+ * proxy_set_task_cpu() instead preserves wake_cpu when moving a donor to
+ * its lock owner's CPU. Keep such a donor on the proxy rq until it wakes;
+ * otherwise normal BPF placement may repeatedly pull it back to its
+ * callback rq only for proxy execution to move it to the owner again.
+ */
+ if (sched_proxy_exec() && p->is_blocked &&
+ task_cpu(p) != p->wake_cpu)
+ return false;
+
/*
* If @p has migration disabled, @p->cpus_ptr is updated to contain only
* the pinned CPU in migrate_disable_switch() while @p is being switched
@@ -3018,6 +3097,8 @@ static void set_next_task_scx(struct rq *rq, struct task_struct *p, bool first)
{
bool can_stop_tick;
+ p->scx.flags &= ~SCX_TASK_ENQ_WAKEUP;
+
if (p->scx.flags & SCX_TASK_QUEUED) {
/*
* Core-sched might decide to execute @p before it is
@@ -3169,6 +3250,37 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,
if (p->scx.flags & SCX_TASK_QUEUED) {
set_task_runnable(rq, p);
+ /*
+ * The rq lock has remained held since scx_allow_proxy_exec(), so
+ * @p's scheduler association cannot have changed. An associated
+ * donor stays queued only when its BPF scheduler enables
+ * %SCX_OPS_ENQ_BLOCKED; delegate its admission to that scheduler.
+ *
+ * If @sch is NULL, @p is transitioning into the root scheduler. The
+ * root is published before tasks enter EXT and cannot be cleared while
+ * this rq is locked. Preserve generic proxy execution by placing the
+ * donor directly on the local DSQ.
+ */
+ if (p->is_blocked) {
+ /*
+ * If the donor is the same and only the mutex owner
+ * changes, avoid triggering another ops.enqueue(): the
+ * BPF scheduler has already admitted the donor, so it
+ * can continue running.
+ */
+ if (next == p)
+ goto switch_class;
+
+ if (sch) {
+ WARN_ON_ONCE(!(sch->ops.flags & SCX_OPS_ENQ_BLOCKED));
+ scx_do_enqueue_task(rq, p, 0, -1);
+ } else {
+ scx_dispatch_enqueue(scx_root, rq, &rq->scx.local_dsq,
+ p, 0);
+ }
+ goto switch_class;
+ }
+
/*
* If @p has slice left and is being put, @p is getting
* preempted by a higher priority scheduler class or core-sched
@@ -7337,6 +7449,11 @@ int scx_validate_ops(struct scx_sched *sch, const struct sched_ext_ops *ops)
return -EINVAL;
}
+ if ((ops->flags & SCX_OPS_ENQ_BLOCKED) && !ops->enqueue) {
+ scx_error(sch, "SCX_OPS_ENQ_BLOCKED requires ops.enqueue() to be implemented");
+ return -EINVAL;
+ }
+
/*
* SCX_OPS_TID_TO_TASK is enabled by the root scheduler. A sub-sched
* may set it to declare a dependency; reject if the root hasn't
@@ -7723,6 +7840,10 @@ static void scx_root_enable_workfn(struct kthread_work *work)
if (old_class != new_class)
queue_flags |= DEQUEUE_CLASS;
+ if (old_class == new_class && new_class == &ext_sched_class) {
+ scx_prepare_task_sched_change(p, sch);
+ queue_flags |= DEQUEUE_NOCLOCK;
+ }
scoped_guard (sched_change, p, new_class, queue_flags) {
set_task_slice(p, READ_ONCE(sch->slice_dfl));
diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
index 351ffd1e02fb8..800a29ca6069a 100644
--- a/kernel/sched/ext/internal.h
+++ b/kernel/sched/ext/internal.h
@@ -213,6 +213,19 @@ enum scx_ops_flags {
*/
SCX_OPS_TID_TO_TASK = 1LLU << 8,
+ /*
+ * If set, mutex-blocked tasks remain runnable as proxy donors and are
+ * passed to ops.enqueue() with %SCX_ENQ_BLOCKED. The BPF scheduler controls
+ * when donors are dispatched and whether they should preempt other work.
+ *
+ * If clear, mutex-blocked tasks are removed from the runqueue normally
+ * and cannot donate their scheduling context through proxy execution.
+ *
+ * For blocked donors, this flag takes precedence over
+ * %SCX_OPS_ENQ_EXITING and %SCX_OPS_ENQ_MIGRATION_DISABLED.
+ */
+ SCX_OPS_ENQ_BLOCKED = 1LLU << 9,
+
SCX_OPS_ALL_FLAGS = SCX_OPS_KEEP_BUILTIN_IDLE |
SCX_OPS_ENQ_LAST |
SCX_OPS_ENQ_EXITING |
@@ -221,7 +234,8 @@ enum scx_ops_flags {
SCX_OPS_SWITCH_PARTIAL |
SCX_OPS_BUILTIN_IDLE_PER_NODE |
SCX_OPS_ALWAYS_ENQ_IMMED |
- SCX_OPS_TID_TO_TASK,
+ SCX_OPS_TID_TO_TASK |
+ SCX_OPS_ENQ_BLOCKED,
/* high 8 bits are internal, don't include in SCX_OPS_ALL_FLAGS */
__SCX_OPS_INTERNAL_MASK = 0xffLLU << 56,
@@ -1651,6 +1665,12 @@ enum scx_enq_flags {
*/
SCX_ENQ_LAST = 1LLU << 41,
+ /*
+ * The task is blocked on a mutex and is being kept runnable as a proxy
+ * donor. Only passed to ops.enqueue() when %SCX_OPS_ENQ_BLOCKED is set.
+ */
+ SCX_ENQ_BLOCKED = 1LLU << 42,
+
/* high 8 bits are internal */
__SCX_ENQ_INTERNAL_MASK = 0xffLLU << 56,
@@ -1947,6 +1967,7 @@ void scx_task_iter_start(struct scx_task_iter *iter, struct cgroup *cgrp);
void scx_task_iter_unlock(struct scx_task_iter *iter);
void scx_task_iter_stop(struct scx_task_iter *iter);
struct task_struct *scx_task_iter_next_locked(struct scx_task_iter *iter);
+void scx_prepare_task_sched_change(struct task_struct *p, struct scx_sched *sch);
void scx_dispatch_dequeue(struct rq *rq, struct task_struct *p);
void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags,
int sticky_cpu);
diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c
index f4ce5b74b7bfc..b4055a1044537 100644
--- a/kernel/sched/ext/sub.c
+++ b/kernel/sched/ext/sub.c
@@ -748,8 +748,9 @@ static void scx_rehome_task(struct scx_sched *to, struct task_struct *p)
lockdep_assert_held(&p->pi_lock);
lockdep_assert_rq_held(task_rq(p));
+ scx_prepare_task_sched_change(p, to);
scoped_guard (sched_change, p, p->sched_class,
- DEQUEUE_SAVE | DEQUEUE_MOVE) {
+ DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK) {
scx_disable_and_exit_task(scx_task_sched(p), p);
scx_set_task_state(p, SCX_TASK_INIT_BEGIN);
scx_set_task_state(p, SCX_TASK_INIT);
@@ -779,8 +780,9 @@ static void scx_punt_task(struct scx_sched *to, struct task_struct *p)
lockdep_assert_rq_held(task_rq(p));
WARN_ON_ONCE(!READ_ONCE(to->bypass_depth));
+ scx_prepare_task_sched_change(p, to);
scoped_guard (sched_change, p, p->sched_class,
- DEQUEUE_SAVE | DEQUEUE_MOVE) {
+ DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK) {
scx_disable_and_exit_task(scx_task_sched(p), p);
scx_set_task_sched(p, to);
}
diff --git a/tools/sched_ext/include/scx/compat.h b/tools/sched_ext/include/scx/compat.h
index 7757252d52e21..0e83ebfbee2b5 100644
--- a/tools/sched_ext/include/scx/compat.h
+++ b/tools/sched_ext/include/scx/compat.h
@@ -117,6 +117,7 @@ static inline bool __COMPAT_struct_has_field(const char *type, const char *field
#define SCX_OPS_ALLOW_QUEUED_WAKEUP SCX_OPS_FLAG(SCX_OPS_ALLOW_QUEUED_WAKEUP)
#define SCX_OPS_BUILTIN_IDLE_PER_NODE SCX_OPS_FLAG(SCX_OPS_BUILTIN_IDLE_PER_NODE)
#define SCX_OPS_ALWAYS_ENQ_IMMED SCX_OPS_FLAG(SCX_OPS_ALWAYS_ENQ_IMMED)
+#define SCX_OPS_ENQ_BLOCKED SCX_OPS_FLAG(SCX_OPS_ENQ_BLOCKED)
#define SCX_PICK_IDLE_FLAG(name) __COMPAT_ENUM_OR_ZERO("scx_pick_idle_cpu_flags", #name)
diff --git a/tools/sched_ext/include/scx/enum_defs.autogen.h b/tools/sched_ext/include/scx/enum_defs.autogen.h
index da4b459820fdd..79b31eb7db7cb 100644
--- a/tools/sched_ext/include/scx/enum_defs.autogen.h
+++ b/tools/sched_ext/include/scx/enum_defs.autogen.h
@@ -55,6 +55,7 @@
#define HAVE_SCX_ENQ_IMMED
#define HAVE_SCX_ENQ_REENQ
#define HAVE_SCX_ENQ_LAST
+#define HAVE_SCX_ENQ_BLOCKED
#define HAVE___SCX_ENQ_INTERNAL_MASK
#define HAVE_SCX_ENQ_CLEAR_OPSS
#define HAVE_SCX_ENQ_DSQ_PRIQ
diff --git a/tools/sched_ext/include/scx/enums.autogen.bpf.h b/tools/sched_ext/include/scx/enums.autogen.bpf.h
index dafccbb6b69d2..7efe7b9346b49 100644
--- a/tools/sched_ext/include/scx/enums.autogen.bpf.h
+++ b/tools/sched_ext/include/scx/enums.autogen.bpf.h
@@ -130,6 +130,9 @@ const volatile u64 __SCX_ENQ_REENQ __weak;
const volatile u64 __SCX_ENQ_LAST __weak;
#define SCX_ENQ_LAST __SCX_ENQ_LAST
+const volatile u64 __SCX_ENQ_BLOCKED __weak;
+#define SCX_ENQ_BLOCKED __SCX_ENQ_BLOCKED
+
const volatile u64 __SCX_ENQ_CLEAR_OPSS __weak;
#define SCX_ENQ_CLEAR_OPSS __SCX_ENQ_CLEAR_OPSS
diff --git a/tools/sched_ext/include/scx/enums.autogen.h b/tools/sched_ext/include/scx/enums.autogen.h
index bbd4901f4fce3..f8fbeb7fbf95b 100644
--- a/tools/sched_ext/include/scx/enums.autogen.h
+++ b/tools/sched_ext/include/scx/enums.autogen.h
@@ -47,6 +47,7 @@
SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_IMMED); \
SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_REENQ); \
SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_LAST); \
+ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_BLOCKED); \
SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_CLEAR_OPSS); \
SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_DSQ_PRIQ); \
SCX_ENUM_SET(skel, scx_deq_flags, SCX_DEQ_SCHED_CHANGE); \
--
2.55.0
next prev parent reply other threads:[~2026-07-25 16:06 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-25 16:04 [PATCHSET v9 sched_ext/for-7.3] sched: Make proxy execution compatible with sched_ext Andrea Righi
2026-07-25 16:04 ` [PATCH 01/14] sched/core: Avoid false migration warning for proxy donors Andrea Righi
2026-07-25 16:04 ` [PATCH 02/14] sched: Make NOHZ CFS bandwidth checks follow proxy donor Andrea Righi
2026-07-25 16:26 ` sashiko-bot
2026-07-25 16:04 ` [PATCH 03/14] sched: Add helper to block retained proxy donors Andrea Righi
2026-07-25 16:04 ` [PATCH 04/14] sched: Add prepare_switch() class callback Andrea Righi
2026-07-25 16:25 ` sashiko-bot
2026-07-25 16:04 ` [PATCH 05/14] sched: Add sched_ext hooks for proxy execution Andrea Righi
2026-07-25 16:14 ` sashiko-bot
2026-07-25 16:04 ` [PATCH 06/14] sched_ext: Block proxy donors across scheduler transitions Andrea Righi
2026-07-25 16:04 ` [PATCH 07/14] sched_ext: Fix ops.running/stopping() pairing for proxy-exec donors Andrea Righi
2026-07-25 16:04 ` [PATCH 08/14] sched_ext: Generalize the reject DSQ reenqueue path Andrea Righi
2026-07-25 16:04 ` [PATCH 09/14] sched_ext: Handle proxy-exec races in remote DSQ transfers Andrea Righi
2026-07-25 16:04 ` [PATCH 10/14] sched_ext: Split curr|donor references properly Andrea Righi
2026-07-25 16:04 ` Andrea Righi [this message]
2026-07-25 16:04 ` [PATCH 12/14] sched_ext: Add selftest for blocked donor admission Andrea Righi
2026-07-25 16:04 ` [PATCH 13/14] sched_ext: scx_qmap: Add proxy execution support Andrea Righi
2026-07-25 16:04 ` [PATCH 14/14] sched: Allow enabling proxy exec with sched_ext Andrea Righi
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=20260725160513.57477-12-arighi@nvidia.com \
--to=arighi@nvidia.com \
--cc=aiqun.yu@oss.qualcomm.com \
--cc=bsegall@google.com \
--cc=changwoo@igalia.com \
--cc=christian.loehle@arm.com \
--cc=david.dai@linux.dev \
--cc=dietmar.eggemann@arm.com \
--cc=jstultz@google.com \
--cc=juri.lelli@redhat.com \
--cc=kobak@nvidia.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=sched-ext@lists.linux.dev \
--cc=shuah@kernel.org \
--cc=tj@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=void@manifault.com \
--cc=vschneid@redhat.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.