]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
sched: Cleanup sched_delayed handling for class switches
authorPeter Zijlstra <peterz@infradead.org>
Wed, 30 Oct 2024 14:47:46 +0000 (15:47 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 16 Oct 2025 09:13:51 +0000 (11:13 +0200)
Use the new sched_class::switching_from() method to dequeue delayed
tasks before switching to another class.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
Reviewed-by: Juri Lelli <juri.lelli@redhat.com>
Acked-by: Tejun Heo <tj@kernel.org>
kernel/sched/core.c
kernel/sched/ext.c
kernel/sched/fair.c
kernel/sched/syscalls.c

index 4dbd2068f43596c607060734f0fdb8d8b870d2cb..bd2c551de6d7e0baacfc8ac8c44c178f5b0cc7b6 100644 (file)
@@ -7366,9 +7366,6 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
        if (prev_class != next_class)
                queue_flag |= DEQUEUE_CLASS;
 
-       if (prev_class != next_class && p->se.sched_delayed)
-               dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
-
        scoped_guard (sched_change, p, queue_flag) {
                /*
                 * Boosting condition are:
@@ -10840,8 +10837,15 @@ struct sched_change_ctx *sched_change_begin(struct task_struct *p, unsigned int
        lockdep_assert_rq_held(rq);
 
        if (flags & DEQUEUE_CLASS) {
-               if (p->sched_class->switching_from)
+               if (p->sched_class->switching_from) {
+                       /*
+                        * switching_from_fair() assumes CLASS implies NOCLOCK;
+                        * fixing this assumption would mean switching_from()
+                        * would need to be able to change flags.
+                        */
+                       WARN_ON(!(flags & DEQUEUE_NOCLOCK));
                        p->sched_class->switching_from(rq, p);
+               }
        }
 
        *ctx = (struct sched_change_ctx){
index a408c393ff15e0adff8d88af25995058a07f224f..b0a1e2a4c4a343de90be84fc521ec5ed1f5d46b2 100644 (file)
@@ -3922,9 +3922,6 @@ static void scx_disable_workfn(struct kthread_work *work)
                if (old_class != new_class)
                        queue_flags |= DEQUEUE_CLASS;
 
-               if (old_class != new_class && p->se.sched_delayed)
-                       dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
-
                scoped_guard (sched_change, p, queue_flags) {
                        p->sched_class = new_class;
                }
@@ -4673,9 +4670,6 @@ static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link)
                if (old_class != new_class)
                        queue_flags |= DEQUEUE_CLASS;
 
-               if (old_class != new_class && p->se.sched_delayed)
-                       dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
-
                scoped_guard (sched_change, p, queue_flags) {
                        p->scx.slice = SCX_SLICE_DFL;
                        p->sched_class = new_class;
index ac881df0eebe8c24565554b3327fa159aec207f3..6c462e4b3db9b96490746ee80792e5ea15a57495 100644 (file)
@@ -13249,6 +13249,12 @@ static void attach_task_cfs_rq(struct task_struct *p)
        attach_entity_cfs_rq(se);
 }
 
+static void switching_from_fair(struct rq *rq, struct task_struct *p)
+{
+       if (p->se.sched_delayed)
+               dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
+}
+
 static void switched_from_fair(struct rq *rq, struct task_struct *p)
 {
        detach_task_cfs_rq(p);
@@ -13650,6 +13656,7 @@ DEFINE_SCHED_CLASS(fair) = {
 
        .reweight_task          = reweight_task_fair,
        .prio_changed           = prio_changed_fair,
+       .switching_from         = switching_from_fair,
        .switched_from          = switched_from_fair,
        .switched_to            = switched_to_fair,
 
index bcef5c72d2874f4204bac50ed5baa2171489f024..6583faf66f6545ce30a75aa43ecb81168bad9194 100644 (file)
@@ -687,9 +687,6 @@ change:
        if (prev_class != next_class)
                queue_flags |= DEQUEUE_CLASS;
 
-       if (prev_class != next_class && p->se.sched_delayed)
-               dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
-
        scoped_guard (sched_change, p, queue_flags) {
 
                if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {