diff options
| author | Tejun Heo <tj@kernel.org> | 2026-07-13 22:18:43 -1000 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-07-13 22:18:43 -1000 |
| commit | 8b17523479437fadb26f649e00a0d848c624c07e (patch) | |
| tree | 15547634777de46a546eb0f1604a4aad908f1c00 /kernel | |
| parent | 75a8c8202c918f567e7a7b16add40b0be02c2113 (diff) | |
sched_ext: Add SCX_ENQ_IGNORE_CAPS for in-place restore
A SAVE/RESTORE requeue re-inserts a running task in place and is immediately
followed by set_next_task_scx(). It is not a real scheduling event: the task
is already admitted to its cid and must return to the local DSQ
unconditionally.
scx_caps_for_enq() maps an enqueue to the cap its local-DSQ insert requires.
Add SCX_ENQ_IGNORE_CAPS, set it on the RESTORE-in-place branch of
enqueue_task_scx(), and have scx_caps_for_enq() require no caps for it, so
the cid admission gate never diverts an in-place restore to the reject DSQ.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Andrea Righi <arighi@nvidia.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched/ext/ext.c | 7 | ||||
| -rw-r--r-- | kernel/sched/ext/internal.h | 1 | ||||
| -rw-r--r-- | kernel/sched/ext/sub.h | 3 |
3 files changed, 9 insertions, 2 deletions
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c index 547468af9674..2da3a5f44b4a 100644 --- a/kernel/sched/ext/ext.c +++ b/kernel/sched/ext/ext.c @@ -1878,10 +1878,13 @@ static void enqueue_task_scx(struct rq *rq, struct task_struct *p, int core_enq_ * Restoring a running task will be immediately followed by * set_next_task_scx() which expects the task to not be on the BPF * scheduler as tasks can only start running through local DSQs. Force - * direct-dispatch into the local DSQ by setting the sticky_cpu. + * direct-dispatch into the local DSQ by setting the sticky_cpu. Mark + * IGNORE_CAPS to force entry into the local DSQ. */ - if (unlikely(enq_flags & ENQUEUE_RESTORE) && task_current(rq, p)) + if (unlikely(enq_flags & ENQUEUE_RESTORE) && task_current(rq, p)) { sticky_cpu = cpu_of(rq); + enq_flags |= SCX_ENQ_IGNORE_CAPS; + } if (p->scx.flags & SCX_TASK_QUEUED) { WARN_ON_ONCE(!task_runnable(p)); diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h index a360d312702b..079ee941b343 100644 --- a/kernel/sched/ext/internal.h +++ b/kernel/sched/ext/internal.h @@ -1568,6 +1568,7 @@ enum scx_enq_flags { SCX_ENQ_DSQ_PRIQ = 1LLU << 57, SCX_ENQ_NESTED = 1LLU << 58, SCX_ENQ_GDSQ_FALLBACK = 1LLU << 59, /* fell back to global DSQ */ + SCX_ENQ_IGNORE_CAPS = 1LLU << 60, /* admit to local DSQ ignoring caps */ }; enum scx_deq_flags { diff --git a/kernel/sched/ext/sub.h b/kernel/sched/ext/sub.h index 9fc95d27f393..3c22ae40349d 100644 --- a/kernel/sched/ext/sub.h +++ b/kernel/sched/ext/sub.h @@ -112,6 +112,9 @@ static inline u64 scx_missing_caps(struct scx_sched *sch, s32 cpu, u64 needed) /* map @enq_flags to the SCX_CAP_* bit required for the local-DSQ insert */ static inline u64 scx_caps_for_enq(u64 enq_flags) { + /* a restored task must be put into the local DSQ regardless of caps */ + if (enq_flags & SCX_ENQ_IGNORE_CAPS) + return 0; return 0; } |
