Re: [PATCH] sched/rt: Push RT tasks when preempted by a deadline task

From: yangsonghua

Date: Wed Jun 24 2026 - 23:13:19 EST


Hi Prateek,

Sorry, my previous reply had formatting issues. Please ignore that email.

You are absolutely right. put_prev_task() can reach put_prev_task_rt()
with next == NULL via sched_change_begin(), so dl_task(next) would indeed
be unsafe. I'll fix this with a NULL guard:

if (next && dl_task(next))
rt_queue_push_tasks(rq);

Your concern about short-lived DL tasks causing an unnecessary push/pull
cycle is also valid. My understanding is that this is the same trade-off
already accepted in __schedule() when a DL task preempts an RT task there,
but I agree this should be made explicit in the commit message. I'll update
that in v2.

Thanks again for the careful review.

Best regards,
Yangsonghua

K Prateek Nayak <kprateek.nayak@xxxxxxx> 于2026年6月24日周三 11:53写道:
>
> Hello Yangsonghua,
>
> On 6/24/2026 8:34 AM, yangsonghua wrote:
> > @@ -1736,14 +1737,24 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p, struct task_s
> >
> > update_rt_rq_load_avg(rq_clock_pelt(rq), rq, 1);
> >
> > - if (task_is_blocked(p))
> > - return;
> > /*
> > * The previous task needs to be made eligible for pushing
> > - * if it is still active
> > + * if it is still active and migratable.
> > */
> > - if (on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1)
> > + if (!task_is_blocked(p) && on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1)
> > enqueue_pushable_task(rq, p);
> > +
> > + /*
> > + * When a deadline task takes over this CPU, try to push any queued
> > + * RT tasks to CPUs running lower-priority work. This is independent
> > + * of whether p itself is pushable: even if p is pinned or blocked,
> > + * there may be other migratable RT tasks already in pushable_tasks.
> > + *
> > + * rt_queue_push_tasks() guards on has_pushable_tasks() internally,
> > + * so this is a no-op if nothing is queued.
> > + */
> > + if (dl_task(next))
> > + rt_queue_push_tasks(rq);
>
> next can be NULL if we are are coming here from sched_change_begin()
> for the current task:
>
> sched_change_begin()
> put_prev_task()
> put_prev_task_rt(rq, prev, next = NULL)
> dl_task(next)
> dl_prio(next->prio) !!! NULL pointer dereference !!!
>
> Do we avoid this in some way?
>
> I don't know if this push was intentionally avoided or not. If there
> are short running deadline task, we'll unnecessarily push a task and
> pull it back later. Is that not a concern?
>
> --
> Thanks and Regards,
> Prateek
>