Skip to content

Commit 4d61801

Browse files
authored
Merge pull request raspberrypi#92 from sched-ext/internal_priq
Change semantics of FIFO/PRIQ dispatching
2 parents 61ce4fe + 346fd9d commit 4d61801

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

Documentation/scheduler/sched-ext.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,11 @@ a task is never queued on the BPF scheduler and both the local and global
194194
DSQs are consumed automatically.
195195

196196
``scx_bpf_dispatch()`` queues the task on the FIFO of the target DSQ. Use
197-
``scx_bpf_dispatch_vtime()`` for the priority queue. See the function
198-
documentation and usage in ``tools/sched_ext/scx_simple.bpf.c`` for more
199-
information.
197+
``scx_bpf_dispatch_vtime()`` for the priority queue. Internal DSQs such as
198+
``SCX_DSQ_LOCAL`` and ``SCX_DSQ_GLOBAL`` do not support priority-queue
199+
dispatching, and must be dispatched to with ``scx_bpf_dispatch()``. See the
200+
function documentation and usage in ``tools/sched_ext/scx_simple.bpf.c`` for
201+
more information.
200202

201203
Where to Look
202204
=============

kernel/sched/ext.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -647,14 +647,23 @@ static void dispatch_enqueue(struct scx_dispatch_q *dsq, struct task_struct *p,
647647
}
648648

649649
if (enq_flags & SCX_ENQ_DSQ_PRIQ) {
650+
WARN_ON_ONCE(dsq->id & SCX_DSQ_FLAG_BUILTIN);
650651
p->scx.dsq_flags |= SCX_TASK_DSQ_ON_PRIQ;
651652
rb_add_cached(&p->scx.dsq_node.priq, &dsq->priq,
652653
scx_dsq_priq_less);
654+
/* A DSQ should only be using either FIFO or PRIQ enqueuing. */
655+
if (unlikely(!list_empty(&dsq->fifo)))
656+
scx_ops_error("DSQ ID 0x%016llx already had FIFO-enqueued tasks",
657+
dsq->id);
653658
} else {
654659
if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT))
655660
list_add(&p->scx.dsq_node.fifo, &dsq->fifo);
656661
else
657662
list_add_tail(&p->scx.dsq_node.fifo, &dsq->fifo);
663+
/* A DSQ should only be using either FIFO or PRIQ enqueuing. */
664+
if (unlikely(rb_first_cached(&dsq->priq)))
665+
scx_ops_error("DSQ ID 0x%016llx already had PRIQ-enqueued tasks",
666+
dsq->id);
658667
}
659668
dsq->nr++;
660669
p->scx.dsq = dsq;
@@ -1772,16 +1781,9 @@ static struct task_struct *first_local_task(struct rq *rq)
17721781
{
17731782
struct rb_node *rb_node;
17741783

1775-
if (!list_empty(&rq->scx.local_dsq.fifo))
1776-
return list_first_entry(&rq->scx.local_dsq.fifo,
1784+
WARN_ON_ONCE(rb_first_cached(&rq->scx.local_dsq.priq));
1785+
return list_first_entry_or_null(&rq->scx.local_dsq.fifo,
17771786
struct task_struct, scx.dsq_node.fifo);
1778-
1779-
rb_node = rb_first_cached(&rq->scx.local_dsq.priq);
1780-
if (rb_node)
1781-
return container_of(rb_node,
1782-
struct task_struct, scx.dsq_node.priq);
1783-
1784-
return NULL;
17851787
}
17861788

17871789
static struct task_struct *pick_next_task_scx(struct rq *rq)
@@ -3948,6 +3950,17 @@ void scx_bpf_dispatch_vtime(struct task_struct *p, u64 dsq_id, u64 slice,
39483950
if (!scx_dispatch_preamble(p, enq_flags))
39493951
return;
39503952

3953+
/*
3954+
* SCX_DSQ_LOCAL and SCX_DSQ_GLOBAL DSQs always consume from their FIFO
3955+
* queues. To avoid confusion and accidentally starving
3956+
* vtime-dispatched tasks by FIFO-dispatched tasks, we disallow any
3957+
* internal DSQ from doing vtime ordering of tasks.
3958+
*/
3959+
if (dsq_id & SCX_DSQ_FLAG_BUILTIN) {
3960+
scx_ops_error("Cannot use vtime ordering for built-in DSQs");
3961+
return;
3962+
}
3963+
39513964
if (slice)
39523965
p->scx.slice = slice;
39533966
else

0 commit comments

Comments
 (0)