From 1ae5f5dfe5adc64a90b1b0ab5bd9bd7c9d140c28 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 30 Oct 2024 15:47:46 +0100 Subject: [PATCH] sched: Cleanup sched_delayed handling for class switches Use the new sched_class::switching_from() method to dequeue delayed tasks before switching to another class. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Vincent Guittot Reviewed-by: Juri Lelli Acked-by: Tejun Heo --- kernel/sched/core.c | 12 ++++++++---- kernel/sched/ext.c | 6 ------ kernel/sched/fair.c | 7 +++++++ kernel/sched/syscalls.c | 3 --- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4dbd2068f4359..bd2c551de6d7e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -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){ diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index a408c393ff15e..b0a1e2a4c4a34 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -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; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ac881df0eebe8..6c462e4b3db9b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -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, diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c index bcef5c72d2874..6583faf66f654 100644 --- a/kernel/sched/syscalls.c +++ b/kernel/sched/syscalls.c @@ -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)) { -- 2.47.3