]> Git Repo - linux.git/commitdiff
sched/rt: Make rt_rq->pushable_tasks updates drive rto_mask
authorValentin Schneider <[email protected]>
Fri, 11 Aug 2023 11:20:44 +0000 (12:20 +0100)
committerIngo Molnar <[email protected]>
Mon, 25 Sep 2023 08:25:29 +0000 (10:25 +0200)
Sebastian noted that the rto_push_work IRQ work can be queued for a CPU
that has an empty pushable_tasks list, which means nothing useful will be
done in the IPI other than queue the work for the next CPU on the rto_mask.

rto_push_irq_work_func() only operates on tasks in the pushable_tasks list,
but the conditions for that irq_work to be queued (and for a CPU to be
added to the rto_mask) rely on rq_rt->nr_migratory instead.

nr_migratory is increased whenever an RT task entity is enqueued and it has
nr_cpus_allowed > 1. Unlike the pushable_tasks list, nr_migratory includes a
rt_rq's current task. This means a rt_rq can have a migratible current, N
non-migratible queued tasks, and be flagged as overloaded / have its CPU
set in the rto_mask, despite having an empty pushable_tasks list.

Make an rt_rq's overload logic be driven by {enqueue,dequeue}_pushable_task().
Since rt_rq->{rt_nr_migratory,rt_nr_total} become unused, remove them.

Note that the case where the current task is pushed away to make way for a
migration-disabled task remains unchanged: the migration-disabled task has
to be in the pushable_tasks list in the first place, which means it has
nr_cpus_allowed > 1.

Reported-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Valentin Schneider <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Tested-by: Sebastian Andrzej Siewior <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
kernel/sched/debug.c
kernel/sched/rt.c
kernel/sched/sched.h

index 5e34a8cb2c76143bb564f268deb1f5741ed033fc..c4253bd2dfb01fbf0ab0340c25ae7b78ab6b39e2 100644 (file)
@@ -724,9 +724,6 @@ void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq)
        SEQ_printf(m, "  .%-30s: %Ld.%06ld\n", #x, SPLIT_NS(rt_rq->x))
 
        PU(rt_nr_running);
-#ifdef CONFIG_SMP
-       PU(rt_nr_migratory);
-#endif
        P(rt_throttled);
        PN(rt_time);
        PN(rt_runtime);
index 3e442fa3f6bcedef0f8270614755711a0506edc3..3b627ab586fb8dbc41cd5072306070458211ea11 100644 (file)
@@ -143,7 +143,6 @@ void init_rt_rq(struct rt_rq *rt_rq)
 #if defined CONFIG_SMP
        rt_rq->highest_prio.curr = MAX_RT_PRIO-1;
        rt_rq->highest_prio.next = MAX_RT_PRIO-1;
-       rt_rq->rt_nr_migratory = 0;
        rt_rq->overloaded = 0;
        plist_head_init(&rt_rq->pushable_tasks);
 #endif /* CONFIG_SMP */
@@ -358,53 +357,6 @@ static inline void rt_clear_overload(struct rq *rq)
        cpumask_clear_cpu(rq->cpu, rq->rd->rto_mask);
 }
 
-static void update_rt_migration(struct rt_rq *rt_rq)
-{
-       if (rt_rq->rt_nr_migratory && rt_rq->rt_nr_total > 1) {
-               if (!rt_rq->overloaded) {
-                       rt_set_overload(rq_of_rt_rq(rt_rq));
-                       rt_rq->overloaded = 1;
-               }
-       } else if (rt_rq->overloaded) {
-               rt_clear_overload(rq_of_rt_rq(rt_rq));
-               rt_rq->overloaded = 0;
-       }
-}
-
-static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
-{
-       struct task_struct *p;
-
-       if (!rt_entity_is_task(rt_se))
-               return;
-
-       p = rt_task_of(rt_se);
-       rt_rq = &rq_of_rt_rq(rt_rq)->rt;
-
-       rt_rq->rt_nr_total++;
-       if (p->nr_cpus_allowed > 1)
-               rt_rq->rt_nr_migratory++;
-
-       update_rt_migration(rt_rq);
-}
-
-static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
-{
-       struct task_struct *p;
-
-       if (!rt_entity_is_task(rt_se))
-               return;
-
-       p = rt_task_of(rt_se);
-       rt_rq = &rq_of_rt_rq(rt_rq)->rt;
-
-       rt_rq->rt_nr_total--;
-       if (p->nr_cpus_allowed > 1)
-               rt_rq->rt_nr_migratory--;
-
-       update_rt_migration(rt_rq);
-}
-
 static inline int has_pushable_tasks(struct rq *rq)
 {
        return !plist_head_empty(&rq->rt.pushable_tasks);
@@ -438,6 +390,11 @@ static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
        /* Update the highest prio pushable task */
        if (p->prio < rq->rt.highest_prio.next)
                rq->rt.highest_prio.next = p->prio;
+
+       if (!rq->rt.overloaded) {
+               rt_set_overload(rq);
+               rq->rt.overloaded = 1;
+       }
 }
 
 static void dequeue_pushable_task(struct rq *rq, struct task_struct *p)
@@ -451,6 +408,11 @@ static void dequeue_pushable_task(struct rq *rq, struct task_struct *p)
                rq->rt.highest_prio.next = p->prio;
        } else {
                rq->rt.highest_prio.next = MAX_RT_PRIO-1;
+
+               if (rq->rt.overloaded) {
+                       rt_clear_overload(rq);
+                       rq->rt.overloaded = 0;
+               }
        }
 }
 
@@ -464,16 +426,6 @@ static inline void dequeue_pushable_task(struct rq *rq, struct task_struct *p)
 {
 }
 
-static inline
-void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
-{
-}
-
-static inline
-void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
-{
-}
-
 static inline void rt_queue_push_tasks(struct rq *rq)
 {
 }
@@ -1281,7 +1233,6 @@ void inc_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
        rt_rq->rr_nr_running += rt_se_rr_nr_running(rt_se);
 
        inc_rt_prio(rt_rq, prio);
-       inc_rt_migration(rt_se, rt_rq);
        inc_rt_group(rt_se, rt_rq);
 }
 
@@ -1294,7 +1245,6 @@ void dec_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
        rt_rq->rr_nr_running -= rt_se_rr_nr_running(rt_se);
 
        dec_rt_prio(rt_rq, rt_se_prio(rt_se));
-       dec_rt_migration(rt_se, rt_rq);
        dec_rt_group(rt_se, rt_rq);
 }
 
index 96f8ab7a070219a2c7ac7f7fa8054ee88c70bd6c..41d760df458f7a42fe7650e51296bf976c121544 100644 (file)
@@ -663,8 +663,6 @@ struct rt_rq {
        } highest_prio;
 #endif
 #ifdef CONFIG_SMP
-       unsigned int            rt_nr_migratory;
-       unsigned int            rt_nr_total;
        int                     overloaded;
        struct plist_head       pushable_tasks;
 
This page took 0.065756 seconds and 4 git commands to generate.