@@ -647,14 +647,23 @@ static void dispatch_enqueue(struct scx_dispatch_q *dsq, struct task_struct *p,
647
647
}
648
648
649
649
if (enq_flags & SCX_ENQ_DSQ_PRIQ ) {
650
+ WARN_ON_ONCE (dsq -> id & SCX_DSQ_FLAG_BUILTIN );
650
651
p -> scx .dsq_flags |= SCX_TASK_DSQ_ON_PRIQ ;
651
652
rb_add_cached (& p -> scx .dsq_node .priq , & dsq -> priq ,
652
653
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 );
653
658
} else {
654
659
if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT ))
655
660
list_add (& p -> scx .dsq_node .fifo , & dsq -> fifo );
656
661
else
657
662
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 );
658
667
}
659
668
dsq -> nr ++ ;
660
669
p -> scx .dsq = dsq ;
@@ -1772,16 +1781,9 @@ static struct task_struct *first_local_task(struct rq *rq)
1772
1781
{
1773
1782
struct rb_node * rb_node ;
1774
1783
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 ,
1777
1786
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 ;
1785
1787
}
1786
1788
1787
1789
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,
3948
3950
if (!scx_dispatch_preamble (p , enq_flags ))
3949
3951
return ;
3950
3952
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
+
3951
3964
if (slice )
3952
3965
p -> scx .slice = slice ;
3953
3966
else
0 commit comments