>From 05d8efe2f3ae3abafd4bf94a0579d378dba63bb6 Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Fri, 23 Jun 2023 11:02:03 +0530 Subject: [PATCH 1/2] swqueue: Control if a task should be queued on swq in select_idle_sibling() If select_idle_sibling() fails to find an idle CPU to wakeup the task on, then update the newly defined sched_add_to_swq field in its task struct. Use the value in this field to later on to determine if the task should also be queued on the shared-wakequeue of the LLC of the target CPU. This extends the use of shared-wakequeue to cases when the target of a wakeup is the current CPU instead of the task's previous CPU. Signed-off-by: Gautham R. Shenoy --- include/linux/sched.h | 6 ++++++ kernel/sched/fair.c | 15 ++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index b64fec55a381..38005262a7fe 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -910,6 +910,12 @@ struct task_struct { */ unsigned sched_remote_wakeup:1; + /* + * Bit used by select_idle_sibling() to signal enqueuing the + * task on a shared wakequeue when it failed find an idle CPU. + */ + unsigned sched_add_to_swq:1; + /* Bit to tell LSMs we're in execve(): */ unsigned in_execve:1; unsigned in_iowait:1; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e311d1c3b992..fe33f6b13299 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -215,21 +215,17 @@ static void swqueue_enqueue(struct rq *rq, struct task_struct *p, int enq_flags) { unsigned long flags; struct swqueue *swqueue; - bool task_migrated = enq_flags & ENQUEUE_MIGRATED; - bool task_wakeup = enq_flags & ENQUEUE_WAKEUP; /* * Only enqueue the task in the shared wakequeue if: * * - SWQUEUE is enabled - * - The task is on the wakeup path - * - The task wasn't purposefully migrated to the current rq by - * select_task_rq() - * - The task isn't pinned to a specific CPU + * - select_idle_sibling() didn't find an idle CPU to enqueue this wakee task. */ - if (!task_wakeup || task_migrated || p->nr_cpus_allowed == 1) + if (!p->sched_add_to_swq) return; + p->sched_add_to_swq = 0; swqueue = rq_swqueue(rq); spin_lock_irqsave(&swqueue->lock, flags); list_add_tail(&p->swqueue_node, &swqueue->list); @@ -7361,6 +7357,11 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) if ((unsigned)i < nr_cpumask_bits) return i; + /* + * No idle sibling was found. Ok to queue this task on the + * shared wakequeue of the target. + */ + p->sched_add_to_swq = 1; return target; } -- 2.25.1