commit:     2fcc7a615b8b2de79d0b1b3ce13cb5430b8c80d4
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Dec  5 20:05:18 2024 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Dec  5 20:05:18 2024 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=2fcc7a61

sched: Initialize idle tasks only once

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README                                |  4 ++
 1800_sched-init-idle-tasks-only-once.patch | 80 ++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/0000_README b/0000_README
index ac1104a1..f7334645 100644
--- a/0000_README
+++ b/0000_README
@@ -63,6 +63,10 @@ Patch:  1730_parisc-Disable-prctl.patch
 From:   https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
 Desc:   prctl: Temporarily disable prctl(PR_SET_MDWE) on parisc
 
+Patch:  1800_sched-init-idle-tasks-only-once.patch
+From:   https://git.kernel.org/
+Desc:   sched: Initialize idle tasks only once
+
 Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   
https://lore.kernel.org/linux-bluetooth/[email protected]/raw
 Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. 
See bug #686758

diff --git a/1800_sched-init-idle-tasks-only-once.patch 
b/1800_sched-init-idle-tasks-only-once.patch
new file mode 100644
index 00000000..013a45fc
--- /dev/null
+++ b/1800_sched-init-idle-tasks-only-once.patch
@@ -0,0 +1,80 @@
+From b23decf8ac9102fc52c4de5196f4dc0a5f3eb80b Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <[email protected]>
+Date: Mon, 28 Oct 2024 11:43:42 +0100
+Subject: sched: Initialize idle tasks only once
+
+Idle tasks are initialized via __sched_fork() twice:
+
+     fork_idle()
+        copy_process()
+         sched_fork()
+             __sched_fork()
+       init_idle()
+          __sched_fork()
+
+Instead of cleaning this up, sched_ext hacked around it. Even when analyis
+and solution were provided in a discussion, nobody cared to clean this up.
+
+init_idle() is also invoked from sched_init() to initialize the boot CPU's
+idle task, which requires the __sched_fork() invocation. But this can be
+trivially solved by invoking __sched_fork() before init_idle() in
+sched_init() and removing the __sched_fork() invocation from init_idle().
+
+Do so and clean up the comments explaining this historical leftover.
+
+Signed-off-by: Thomas Gleixner <[email protected]>
+Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+---
+ kernel/sched/core.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+(limited to 'kernel/sched/core.c')
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index c57a79e3491103..aad48850c1ef0d 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -4423,7 +4423,8 @@ int wake_up_state(struct task_struct *p, unsigned int 
state)
+  * Perform scheduler related setup for a newly forked process p.
+  * p is forked by current.
+  *
+- * __sched_fork() is basic setup used by init_idle() too:
++ * __sched_fork() is basic setup which is also used by sched_init() to
++ * initialize the boot CPU's idle task.
+  */
+ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
+ {
+@@ -7697,8 +7698,6 @@ void __init init_idle(struct task_struct *idle, int cpu)
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+ 
+-      __sched_fork(0, idle);
+-
+       raw_spin_lock_irqsave(&idle->pi_lock, flags);
+       raw_spin_rq_lock(rq);
+ 
+@@ -7713,10 +7712,8 @@ void __init init_idle(struct task_struct *idle, int cpu)
+ 
+ #ifdef CONFIG_SMP
+       /*
+-       * It's possible that init_idle() gets called multiple times on a task,
+-       * in that case do_set_cpus_allowed() will not do the right thing.
+-       *
+-       * And since this is boot we can forgo the serialization.
++       * No validation and serialization required at boot time and for
++       * setting up the idle tasks of not yet online CPUs.
+        */
+       set_cpus_allowed_common(idle, &ac);
+ #endif
+@@ -8561,6 +8558,7 @@ void __init sched_init(void)
+        * but because we are the idle thread, we just pick up running again
+        * when this runqueue becomes "idle".
+        */
++      __sched_fork(0, current);
+       init_idle(current, smp_processor_id());
+ 
+       calc_load_update = jiffies + LOAD_FREQ;
+-- 
+cgit 1.2.3-korg
+

Reply via email to