[PATCH 12/20 v3] sched/fair: Support not wakeup case in select_idle_sibling
From: Vincent Guittot
Date: Fri Nov 06 2026 - 10:26:21 EST
With push callback mecanism, select_task_rq_fair() can be called for a
task that is already enqueued. Task into account this case when choosing
an idle CPU.
Signed-off-by: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
---
kernel/sched/fair.c | 31 +++++++++++++++++++++++--------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index f2a0d2c2bb63..980eda9c935a 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -8187,10 +8187,27 @@ static int choose_sched_idle_rq(struct rq *rq, struct task_struct *p)
return sched_idle_rq(rq) && !task_has_idle_policy(p);
}
+static int idle_rq_without(struct rq *rq, struct task_struct *p);
+static unsigned int task_running_on_cpu(int cpu, struct task_struct *p);
+
+static int choose_idle_rq_without(struct rq *rq, struct task_struct *p)
+{
+ if (rq->nr_running != 1)
+ return 0;
+
+ if (!task_running_on_cpu(cpu_of(rq), p))
+ return 0;
+
+ return idle_rq_without(rq, p);
+}
+
static int choose_idle_cpu(int cpu, struct task_struct *p)
{
+ struct rq *rq = cpu_rq(cpu);
+
return available_idle_cpu(cpu) ||
- choose_sched_idle_rq(cpu_rq(cpu), p);
+ choose_sched_idle_rq(rq, p) ||
+ choose_idle_rq_without(rq, p);
}
static void
@@ -12968,23 +12985,21 @@ static unsigned int task_running_on_cpu(int cpu, struct task_struct *p)
}
/**
- * idle_cpu_without - would a given CPU be idle without p ?
+ * idle_rq_without - would a given CPU be idle without p ?
* @cpu: the processor on which idleness is tested.
* @p: task which should be ignored.
*
* Return: 1 if the CPU would be idle. 0 otherwise.
*/
-static int idle_cpu_without(int cpu, struct task_struct *p)
+static int idle_rq_without(struct rq *rq, struct task_struct *p)
{
- struct rq *rq = cpu_rq(cpu);
-
if (rq->curr != rq->idle && rq->curr != p)
return 0;
/*
* rq->nr_running can't be used but an updated version without the
* impact of p on cpu must be used instead. The updated nr_running
- * be computed and tested before calling idle_cpu_without().
+ * be computed and tested before calling idle_rq_without().
*/
if (rq->ttwu_pending)
@@ -13027,9 +13042,9 @@ static inline void update_sg_wakeup_stats(struct sched_domain *sd,
sgs->sum_nr_running += nr_running;
/*
- * No need to call idle_cpu_without() if nr_running is not 0
+ * No need to call idle_rq_without() if nr_running is not 0
*/
- if (!nr_running && idle_cpu_without(i, p))
+ if (!nr_running && idle_rq_without(rq, p))
sgs->idle_cpus++;
/* Check if task fits in the CPU */
--
2.53.0