summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/ext/inlines.h15
-rw-r--r--kernel/sched/ext/sub.c6
2 files changed, 18 insertions, 3 deletions
diff --git a/kernel/sched/ext/inlines.h b/kernel/sched/ext/inlines.h
index 8de9d8fb4b25..1e39d12678c4 100644
--- a/kernel/sched/ext/inlines.h
+++ b/kernel/sched/ext/inlines.h
@@ -39,10 +39,18 @@ scx_dispatch_sched(struct scx_sched *sch, struct rq *rq,
if (scx_consume_global_dsq(sch, rq))
return SCX_DSP_LOCAL;
+ /*
+ * A bypass consume puts a task on the cpu being dispatched for, to run
+ * right away. That is an IMMED insert and needs only
+ * %SCX_CAP_ENQ_IMMED, the base cap. Dispatch descends into @sch only on
+ * a cpu where @sch holds the base cap, so @sch holds it here. The same
+ * holds for the consume at the end of this function.
+ */
if (scx_bypass_dsp_enabled(sch)) {
/* if @sch is bypassing, only the bypass DSQs are active */
if (scx_bypassing(sch, cpu)) {
- if (scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu), 0))
+ if (scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu),
+ SCX_ENQ_IMMED))
return SCX_DSP_LOCAL;
return SCX_DSP_NONE;
}
@@ -63,7 +71,8 @@ scx_dispatch_sched(struct scx_sched *sch, struct rq *rq,
struct scx_sched_pcpu *pcpu = per_cpu_ptr(sch->pcpu, cpu);
if (!(pcpu->bypass_host_seq++ % SCX_BYPASS_HOST_NTH) &&
- scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu), 0)) {
+ scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu),
+ SCX_ENQ_IMMED)) {
__scx_add_event(sch, SCX_EV_SUB_BYPASS_DISPATCH, 1);
return SCX_DSP_LOCAL;
}
@@ -135,7 +144,7 @@ scx_dispatch_sched(struct scx_sched *sch, struct rq *rq,
* scheduler's ops.dispatch() doesn't yield any tasks.
*/
if (scx_bypass_dsp_enabled(sch) &&
- scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu), 0)) {
+ scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu), SCX_ENQ_IMMED)) {
__scx_add_event(sch, SCX_EV_SUB_BYPASS_DISPATCH, 1);
return SCX_DSP_LOCAL;
}
diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c
index f7f33fd0c5e9..a7b14ea16822 100644
--- a/kernel/sched/ext/sub.c
+++ b/kernel/sched/ext/sub.c
@@ -2722,6 +2722,12 @@ __bpf_kfunc_start_defs();
* child schedulers. The child scheduler runs its dispatch operation to
* move tasks from dispatch queues to the local runqueue.
*
+ * Dispatch into a child while the local DSQ is empty, when the cpu needs a
+ * task. A child holding only %SCX_CAP_ENQ_IMMED can insert only IMMED tasks,
+ * and the consume of its bypassing descendants' bypass DSQs is one such insert.
+ * With a task already queued on the local DSQ, such an insert fails and the
+ * task is reenqueued.
+ *
* Returns: true on success, false if cgroup_id is invalid, not a direct
* child, or caller lacks dispatch permission.
*/