]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sched: Fix sched_delayed vs cfs_bandwidth
authorMike Galbraith <efault@gmx.de>
Tue, 1 Oct 2024 01:34:01 +0000 (03:34 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Wed, 2 Oct 2024 09:27:54 +0000 (11:27 +0200)
Meeting an unfinished DELAY_DEQUEUE treated entity in unthrottle_cfs_rq()
leads to a couple terminal scenarios.  Finish it first, so ENQUEUE_WAKEUP
can proceed as it would have sans DELAY_DEQUEUE treatment.

Fixes: 152e11f6df29 ("sched/fair: Implement delayed dequeue")
Reported-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
Signed-off-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
Link: https://lore.kernel.org/r/7515d2e64c989b9e3b828a9e21bcd959b99df06a.camel@gmx.de
kernel/sched/fair.c

index 225b31aaee558a5bd6cfbc85eac9647d84c1a762..b63a7ac3116207eb3dc48762a3ff02accad93d9d 100644 (file)
@@ -6058,10 +6058,13 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq)
        for_each_sched_entity(se) {
                struct cfs_rq *qcfs_rq = cfs_rq_of(se);
 
-               if (se->on_rq) {
-                       SCHED_WARN_ON(se->sched_delayed);
+               /* Handle any unfinished DELAY_DEQUEUE business first. */
+               if (se->sched_delayed) {
+                       int flags = DEQUEUE_SLEEP | DEQUEUE_DELAYED;
+
+                       dequeue_entity(qcfs_rq, se, flags);
+               } else if (se->on_rq)
                        break;
-               }
                enqueue_entity(qcfs_rq, se, ENQUEUE_WAKEUP);
 
                if (cfs_rq_is_idle(group_cfs_rq(se)))