* [PATCH 0/2] sched: Address idle task vs pcpu kthread checks @ 2021-05-10 15:10 Valentin Schneider 2021-05-10 15:10 ` [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread Valentin Schneider ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Valentin Schneider @ 2021-05-10 15:10 UTC (permalink / raw) To: linux-kernel; +Cc: mingo, peterz, tglx, bristot, yejune.deng Commit 5ba2ffba13a1 ("sched: Fix CPU hotplug / tighten is_per_cpu_kthread()") had to special-case the idle task when checking for per-CPU kthreads. This is due to the idle task not having its own struct kthread, which is where we'd store KTHREAD_IS_PER_CPU. From staring at Yejune's recent patch [1], it turns out the idle task is also missing PF_NO_SETAFFINITY. Patch 1 cleans this up, patch 2 is Yejune's v1 which depends on it. Note: I remember seeing some patch(es) from Peter tackling this exact problem, but I couldn't find them again. [1]: http://lore.kernel.org/r/1620458722-13026-1-git-send-email-yejunedeng@gmail.com Cheers, Valentin Valentin Schneider (1): sched: Make the idle task quack like a per-CPU kthread Yejune Deng (1): lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed include/linux/kthread.h | 2 ++ kernel/kthread.c | 30 ++++++++++++++++++------------ kernel/sched/core.c | 21 +++++++++++++++------ lib/smp_processor_id.c | 6 +----- 4 files changed, 36 insertions(+), 23 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread 2021-05-10 15:10 [PATCH 0/2] sched: Address idle task vs pcpu kthread checks Valentin Schneider @ 2021-05-10 15:10 ` Valentin Schneider 2021-05-10 15:57 ` Valentin Schneider 2021-05-19 8:09 ` [tip: sched/core] " tip-bot2 for Valentin Schneider 2021-05-10 15:10 ` [PATCH 2/2] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed Valentin Schneider 2021-05-12 11:00 ` [PATCH 0/2] sched: Address idle task vs pcpu kthread checks Peter Zijlstra 2 siblings, 2 replies; 13+ messages in thread From: Valentin Schneider @ 2021-05-10 15:10 UTC (permalink / raw) To: linux-kernel; +Cc: mingo, peterz, tglx, bristot, yejune.deng For all intents and purposes, the idle task is a per-CPU kthread. It isn't created via the same route as other pcpu kthreads however, and as a result it is missing a few bells and whistles: it fails kthread_is_per_cpu() and it doesn't have PF_NO_SETAFFINITY set. Fix the former by giving the idle task a kthread struct along with the KTHREAD_IS_PER_CPU flag. This requires some extra iffery as init_idle() call be called more than once on the same idle task. Signed-off-by: Valentin Schneider <valentin.schneider@arm.com> --- include/linux/kthread.h | 2 ++ kernel/kthread.c | 30 ++++++++++++++++++------------ kernel/sched/core.c | 21 +++++++++++++++------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 2484ed97e72f..d9133d6db308 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -33,6 +33,8 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), unsigned int cpu, const char *namefmt); +void set_kthread_struct(struct task_struct *p); + void kthread_set_per_cpu(struct task_struct *k, int cpu); bool kthread_is_per_cpu(struct task_struct *k); diff --git a/kernel/kthread.c b/kernel/kthread.c index 6d3c488a0f82..77dd0ea1d35d 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -68,16 +68,6 @@ enum KTHREAD_BITS { KTHREAD_SHOULD_PARK, }; -static inline void set_kthread_struct(void *kthread) -{ - /* - * We abuse ->set_child_tid to avoid the new member and because it - * can't be wrongly copied by copy_process(). We also rely on fact - * that the caller can't exec, so PF_KTHREAD can't be cleared. - */ - current->set_child_tid = (__force void __user *)kthread; -} - static inline struct kthread *to_kthread(struct task_struct *k) { WARN_ON(!(k->flags & PF_KTHREAD)); @@ -103,6 +93,22 @@ static inline struct kthread *__to_kthread(struct task_struct *p) return kthread; } +void set_kthread_struct(struct task_struct *p) +{ + struct kthread *kthread; + + if (__to_kthread(p)) + return; + + kthread = kzalloc(sizeof(*kthread), GFP_KERNEL); + /* + * We abuse ->set_child_tid to avoid the new member and because it + * can't be wrongly copied by copy_process(). We also rely on fact + * that the caller can't exec, so PF_KTHREAD can't be cleared. + */ + p->set_child_tid = (__force void __user *)kthread; +} + void free_kthread_struct(struct task_struct *k) { struct kthread *kthread; @@ -272,8 +278,8 @@ static int kthread(void *_create) struct kthread *self; int ret; - self = kzalloc(sizeof(*self), GFP_KERNEL); - set_kthread_struct(self); + set_kthread_struct(current); + self = to_kthread(current); /* If user was SIGKILLed, I release the structure. */ done = xchg(&create->done, NULL); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4a0668acd876..5bb720829d93 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7440,12 +7440,25 @@ void init_idle(struct task_struct *idle, int cpu) __sched_fork(0, idle); + /* + * The idle task doesn't need the kthread struct to function, but it + * is dressed up as a per-CPU kthread and thus needs to play the part + * if we want to avoid special-casing it in code that deals with per-CPU + * kthreads. + */ + set_kthread_struct(idle); + raw_spin_lock_irqsave(&idle->pi_lock, flags); raw_spin_lock(&rq->lock); idle->state = TASK_RUNNING; idle->se.exec_start = sched_clock(); - idle->flags |= PF_IDLE; + /* + * PF_KTHREAD should already be set at this point; regardless, make it + * look like a proper per-CPU kthread. + */ + idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY; + kthread_set_per_cpu(idle, cpu); scs_task_reset(idle); kasan_unpoison_task_stack(idle); @@ -7662,12 +7675,8 @@ static void balance_push(struct rq *rq) /* * Both the cpu-hotplug and stop task are in this case and are * required to complete the hotplug process. - * - * XXX: the idle task does not match kthread_is_per_cpu() due to - * histerical raisins. */ - if (rq->idle == push_task || - kthread_is_per_cpu(push_task) || + if (kthread_is_per_cpu(push_task) || is_migration_disabled(push_task)) { /* -- 2.25.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread 2021-05-10 15:10 ` [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread Valentin Schneider @ 2021-05-10 15:57 ` Valentin Schneider 2021-05-11 7:32 ` Ingo Molnar 2021-05-19 8:09 ` [tip: sched/core] " tip-bot2 for Valentin Schneider 1 sibling, 1 reply; 13+ messages in thread From: Valentin Schneider @ 2021-05-10 15:57 UTC (permalink / raw) To: linux-kernel; +Cc: mingo, peterz, tglx, bristot, yejune.deng On 10/05/21 16:10, Valentin Schneider wrote: > This requires some extra iffery as init_idle() > call be called more than once on the same idle task. > While I'm at it, do we actually still need to suffer through this? AFAICT the extra calls are due to idle_thread_get() (used in cpuhp) calling init_idle(). However it looks to me that since 3bb5d2ee396a ("smp, idle: Allocate idle thread for each possible cpu during boot") we don't need to do that: we already have a for_each_possible_cpu(cpu) init_idle(cpu) issued at init. So can't we "simply" rely on that init-time creation, given it's done against the possible mask? I think the only thing that might need doing at later hotplug is making sure the preempt count is right (secondary startups seem to all prepare the idle task by issuing a preempt_disable()). ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread 2021-05-10 15:57 ` Valentin Schneider @ 2021-05-11 7:32 ` Ingo Molnar 2021-05-11 9:33 ` Valentin Schneider 0 siblings, 1 reply; 13+ messages in thread From: Ingo Molnar @ 2021-05-11 7:32 UTC (permalink / raw) To: Valentin Schneider; +Cc: linux-kernel, peterz, tglx, bristot, yejune.deng * Valentin Schneider <valentin.schneider@arm.com> wrote: > On 10/05/21 16:10, Valentin Schneider wrote: > > This requires some extra iffery as init_idle() > > call be called more than once on the same idle task. > > > > While I'm at it, do we actually still need to suffer through this? No. > AFAICT the extra calls are due to idle_thread_get() (used in cpuhp) > calling init_idle(). However it looks to me that since > > 3bb5d2ee396a ("smp, idle: Allocate idle thread for each possible cpu during boot") > > we don't need to do that: we already have a > > for_each_possible_cpu(cpu) > init_idle(cpu) > > issued at init. So can't we "simply" rely on that init-time creation, > given it's done against the possible mask? I think the only thing that > might need doing at later hotplug is making sure the preempt count is > right (secondary startups seem to all prepare the idle task by issuing a > preempt_disable()). Best-case it works, worst-case we discover an unclean assumption in the init sequence and it works after we fix that. Win-win. :-) Thanks, Ingo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread 2021-05-11 7:32 ` Ingo Molnar @ 2021-05-11 9:33 ` Valentin Schneider 0 siblings, 0 replies; 13+ messages in thread From: Valentin Schneider @ 2021-05-11 9:33 UTC (permalink / raw) To: Ingo Molnar; +Cc: linux-kernel, peterz, tglx, bristot, yejune.deng On 11/05/21 09:32, Ingo Molnar wrote: > * Valentin Schneider <valentin.schneider@arm.com> wrote: >> AFAICT the extra calls are due to idle_thread_get() (used in cpuhp) >> calling init_idle(). However it looks to me that since >> >> 3bb5d2ee396a ("smp, idle: Allocate idle thread for each possible cpu during boot") >> >> we don't need to do that: we already have a >> >> for_each_possible_cpu(cpu) >> init_idle(cpu) >> >> issued at init. So can't we "simply" rely on that init-time creation, >> given it's done against the possible mask? I think the only thing that >> might need doing at later hotplug is making sure the preempt count is >> right (secondary startups seem to all prepare the idle task by issuing a >> preempt_disable()). > > Best-case it works, worst-case we discover an unclean assumption in the > init sequence and it works after we fix that. > > Win-win. :-) > Well I got something that seems to work, let me it test it some more and convince myself it isn't completely bonkers and I'll toss it out. > Thanks, > > Ingo ^ permalink raw reply [flat|nested] 13+ messages in thread
* [tip: sched/core] sched: Make the idle task quack like a per-CPU kthread 2021-05-10 15:10 ` [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread Valentin Schneider 2021-05-10 15:57 ` Valentin Schneider @ 2021-05-19 8:09 ` tip-bot2 for Valentin Schneider 1 sibling, 0 replies; 13+ messages in thread From: tip-bot2 for Valentin Schneider @ 2021-05-19 8:09 UTC (permalink / raw) To: linux-tip-commits Cc: Valentin Schneider, Peter Zijlstra (Intel), x86, linux-kernel The following commit has been merged into the sched/core branch of tip: Commit-ID: 00b89fe0197f0c55a045775c11553c0cdb7082fe Gitweb: https://git.kernel.org/tip/00b89fe0197f0c55a045775c11553c0cdb7082fe Author: Valentin Schneider <valentin.schneider@arm.com> AuthorDate: Mon, 10 May 2021 16:10:23 +01:00 Committer: Peter Zijlstra <peterz@infradead.org> CommitterDate: Tue, 18 May 2021 12:53:53 +02:00 sched: Make the idle task quack like a per-CPU kthread For all intents and purposes, the idle task is a per-CPU kthread. It isn't created via the same route as other pcpu kthreads however, and as a result it is missing a few bells and whistles: it fails kthread_is_per_cpu() and it doesn't have PF_NO_SETAFFINITY set. Fix the former by giving the idle task a kthread struct along with the KTHREAD_IS_PER_CPU flag. This requires some extra iffery as init_idle() call be called more than once on the same idle task. Signed-off-by: Valentin Schneider <valentin.schneider@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20210510151024.2448573-2-valentin.schneider@arm.com --- include/linux/kthread.h | 2 ++ kernel/kthread.c | 30 ++++++++++++++++++------------ kernel/sched/core.c | 21 +++++++++++++++------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 2484ed9..d9133d6 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -33,6 +33,8 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), unsigned int cpu, const char *namefmt); +void set_kthread_struct(struct task_struct *p); + void kthread_set_per_cpu(struct task_struct *k, int cpu); bool kthread_is_per_cpu(struct task_struct *k); diff --git a/kernel/kthread.c b/kernel/kthread.c index fe3f2a4..3d32683 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -68,16 +68,6 @@ enum KTHREAD_BITS { KTHREAD_SHOULD_PARK, }; -static inline void set_kthread_struct(void *kthread) -{ - /* - * We abuse ->set_child_tid to avoid the new member and because it - * can't be wrongly copied by copy_process(). We also rely on fact - * that the caller can't exec, so PF_KTHREAD can't be cleared. - */ - current->set_child_tid = (__force void __user *)kthread; -} - static inline struct kthread *to_kthread(struct task_struct *k) { WARN_ON(!(k->flags & PF_KTHREAD)); @@ -103,6 +93,22 @@ static inline struct kthread *__to_kthread(struct task_struct *p) return kthread; } +void set_kthread_struct(struct task_struct *p) +{ + struct kthread *kthread; + + if (__to_kthread(p)) + return; + + kthread = kzalloc(sizeof(*kthread), GFP_KERNEL); + /* + * We abuse ->set_child_tid to avoid the new member and because it + * can't be wrongly copied by copy_process(). We also rely on fact + * that the caller can't exec, so PF_KTHREAD can't be cleared. + */ + p->set_child_tid = (__force void __user *)kthread; +} + void free_kthread_struct(struct task_struct *k) { struct kthread *kthread; @@ -272,8 +278,8 @@ static int kthread(void *_create) struct kthread *self; int ret; - self = kzalloc(sizeof(*self), GFP_KERNEL); - set_kthread_struct(self); + set_kthread_struct(current); + self = to_kthread(current); /* If user was SIGKILLed, I release the structure. */ done = xchg(&create->done, NULL); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 24fd795..6a5124c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8234,12 +8234,25 @@ void __init init_idle(struct task_struct *idle, int cpu) __sched_fork(0, idle); + /* + * The idle task doesn't need the kthread struct to function, but it + * is dressed up as a per-CPU kthread and thus needs to play the part + * if we want to avoid special-casing it in code that deals with per-CPU + * kthreads. + */ + set_kthread_struct(idle); + raw_spin_lock_irqsave(&idle->pi_lock, flags); raw_spin_rq_lock(rq); idle->state = TASK_RUNNING; idle->se.exec_start = sched_clock(); - idle->flags |= PF_IDLE; + /* + * PF_KTHREAD should already be set at this point; regardless, make it + * look like a proper per-CPU kthread. + */ + idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY; + kthread_set_per_cpu(idle, cpu); scs_task_reset(idle); kasan_unpoison_task_stack(idle); @@ -8456,12 +8469,8 @@ static void balance_push(struct rq *rq) /* * Both the cpu-hotplug and stop task are in this case and are * required to complete the hotplug process. - * - * XXX: the idle task does not match kthread_is_per_cpu() due to - * histerical raisins. */ - if (rq->idle == push_task || - kthread_is_per_cpu(push_task) || + if (kthread_is_per_cpu(push_task) || is_migration_disabled(push_task)) { /* ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/2] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed 2021-05-10 15:10 [PATCH 0/2] sched: Address idle task vs pcpu kthread checks Valentin Schneider 2021-05-10 15:10 ` [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread Valentin Schneider @ 2021-05-10 15:10 ` Valentin Schneider 2021-05-19 8:09 ` [tip: sched/core] " tip-bot2 for Yejune Deng 2021-05-19 9:02 ` tip-bot2 for Yejune Deng 2021-05-12 11:00 ` [PATCH 0/2] sched: Address idle task vs pcpu kthread checks Peter Zijlstra 2 siblings, 2 replies; 13+ messages in thread From: Valentin Schneider @ 2021-05-10 15:10 UTC (permalink / raw) To: linux-kernel; +Cc: Yejune Deng, mingo, peterz, tglx, bristot From: Yejune Deng <yejune.deng@gmail.com> is_percpu_thread() more elegantly handles SMP vs UP, and further checks the presence of PF_NO_SETAFFINITY. This lets us catch cases where check_preemption_disabled() can race with a concurrent sched_setaffinity(). Signed-off-by: Yejune Deng <yejune.deng@gmail.com> [Amended changelog] Signed-off-by: Valentin Schneider <valentin.schneider@arm.com> --- lib/smp_processor_id.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 1c1dbd300325..046ac6297c78 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -19,11 +19,7 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2) if (irqs_disabled()) goto out; - /* - * Kernel threads bound to a single CPU can safely use - * smp_processor_id(): - */ - if (current->nr_cpus_allowed == 1) + if (is_percpu_thread()) goto out; #ifdef CONFIG_SMP -- 2.25.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [tip: sched/core] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed 2021-05-10 15:10 ` [PATCH 2/2] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed Valentin Schneider @ 2021-05-19 8:09 ` tip-bot2 for Yejune Deng 2021-05-19 9:02 ` tip-bot2 for Yejune Deng 1 sibling, 0 replies; 13+ messages in thread From: tip-bot2 for Yejune Deng @ 2021-05-19 8:09 UTC (permalink / raw) To: linux-tip-commits Cc: Valentin Schneider, Yejune Deng, Peter Zijlstra (Intel), x86, linux-kernel The following commit has been merged into the sched/core branch of tip: Commit-ID: 0019699518cc026b5bd912425be8e424843d5b33 Gitweb: https://git.kernel.org/tip/0019699518cc026b5bd912425be8e424843d5b33 Author: Yejune Deng <yejune.deng@gmail.com> AuthorDate: Mon, 10 May 2021 16:10:24 +01:00 Committer: Peter Zijlstra <peterz@infradead.org> CommitterDate: Tue, 18 May 2021 12:53:54 +02:00 lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed is_percpu_thread() more elegantly handles SMP vs UP, and further checks the presence of PF_NO_SETAFFINITY. This lets us catch cases where check_preemption_disabled() can race with a concurrent sched_setaffinity(). [Amended changelog] Signed-off-by: Valentin Schneider <valentin.schneider@arm.com> Signed-off-by: Yejune Deng <yejune.deng@gmail.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20210510151024.2448573-3-valentin.schneider@arm.com --- lib/smp_processor_id.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 1c1dbd3..046ac62 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -19,11 +19,7 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2) if (irqs_disabled()) goto out; - /* - * Kernel threads bound to a single CPU can safely use - * smp_processor_id(): - */ - if (current->nr_cpus_allowed == 1) + if (is_percpu_thread()) goto out; #ifdef CONFIG_SMP ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [tip: sched/core] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed 2021-05-10 15:10 ` [PATCH 2/2] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed Valentin Schneider 2021-05-19 8:09 ` [tip: sched/core] " tip-bot2 for Yejune Deng @ 2021-05-19 9:02 ` tip-bot2 for Yejune Deng 2021-05-31 10:21 ` [PATCH] sched,init: Fix DEBUG_PREEMPT vs early boot Peter Zijlstra 1 sibling, 1 reply; 13+ messages in thread From: tip-bot2 for Yejune Deng @ 2021-05-19 9:02 UTC (permalink / raw) To: linux-tip-commits Cc: Yejune Deng, Valentin Schneider, Peter Zijlstra (Intel), x86, linux-kernel The following commit has been merged into the sched/core branch of tip: Commit-ID: 570a752b7a9bd03b50ad6420cd7f10092cc11bd3 Gitweb: https://git.kernel.org/tip/570a752b7a9bd03b50ad6420cd7f10092cc11bd3 Author: Yejune Deng <yejune.deng@gmail.com> AuthorDate: Mon, 10 May 2021 16:10:24 +01:00 Committer: Peter Zijlstra <peterz@infradead.org> CommitterDate: Wed, 19 May 2021 10:51:40 +02:00 lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed is_percpu_thread() more elegantly handles SMP vs UP, and further checks the presence of PF_NO_SETAFFINITY. This lets us catch cases where check_preemption_disabled() can race with a concurrent sched_setaffinity(). Signed-off-by: Yejune Deng <yejune.deng@gmail.com> [Amended changelog] Signed-off-by: Valentin Schneider <valentin.schneider@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20210510151024.2448573-3-valentin.schneider@arm.com --- lib/smp_processor_id.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 1c1dbd3..046ac62 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -19,11 +19,7 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2) if (irqs_disabled()) goto out; - /* - * Kernel threads bound to a single CPU can safely use - * smp_processor_id(): - */ - if (current->nr_cpus_allowed == 1) + if (is_percpu_thread()) goto out; #ifdef CONFIG_SMP ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH] sched,init: Fix DEBUG_PREEMPT vs early boot 2021-05-19 9:02 ` tip-bot2 for Yejune Deng @ 2021-05-31 10:21 ` Peter Zijlstra 2021-06-01 11:54 ` Valentin Schneider 2021-06-01 14:04 ` [tip: sched/core] " tip-bot2 for Peter Zijlstra 0 siblings, 2 replies; 13+ messages in thread From: Peter Zijlstra @ 2021-05-31 10:21 UTC (permalink / raw) To: linux-kernel; +Cc: linux-tip-commits, Yejune Deng, Valentin Schneider, x86 On Wed, May 19, 2021 at 09:02:34AM -0000, tip-bot2 for Yejune Deng wrote: > The following commit has been merged into the sched/core branch of tip: > > Commit-ID: 570a752b7a9bd03b50ad6420cd7f10092cc11bd3 > Gitweb: https://git.kernel.org/tip/570a752b7a9bd03b50ad6420cd7f10092cc11bd3 > Author: Yejune Deng <yejune.deng@gmail.com> > AuthorDate: Mon, 10 May 2021 16:10:24 +01:00 > Committer: Peter Zijlstra <peterz@infradead.org> > CommitterDate: Wed, 19 May 2021 10:51:40 +02:00 > > lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed > > is_percpu_thread() more elegantly handles SMP vs UP, and further checks the > presence of PF_NO_SETAFFINITY. This lets us catch cases where > check_preemption_disabled() can race with a concurrent sched_setaffinity(). > > Signed-off-by: Yejune Deng <yejune.deng@gmail.com> > [Amended changelog] > Signed-off-by: Valentin Schneider <valentin.schneider@arm.com> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > Link: https://lkml.kernel.org/r/20210510151024.2448573-3-valentin.schneider@arm.com > --- > lib/smp_processor_id.c | 6 +----- > 1 file changed, 1 insertion(+), 5 deletions(-) > > diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c > index 1c1dbd3..046ac62 100644 > --- a/lib/smp_processor_id.c > +++ b/lib/smp_processor_id.c > @@ -19,11 +19,7 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2) > if (irqs_disabled()) > goto out; > > - /* > - * Kernel threads bound to a single CPU can safely use > - * smp_processor_id(): > - */ > - if (current->nr_cpus_allowed == 1) > + if (is_percpu_thread()) > goto out; So my test box was unhappy with all this and started spewing lots of DEBUG_PREEMPT warns on boot. This extends 8fb12156b8db6 to cover the new requirement. --- Subject: sched,init: Fix DEBUG_PREEMPT vs early boot Extend 8fb12156b8db ("init: Pin init task to the boot CPU, initially") to cover the new PF_NO_SETAFFINITY requirement. While there, move wait_for_completion(&kthreadd_done) into kernel_init() to make it absolutely clear it is the very first thing done by the init thread. Fixes: 570a752b7a9b ("lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed") Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- init/main.c | 11 ++++++----- kernel/sched/core.c | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/init/main.c b/init/main.c index 7b027d9c5c89..e945ec82b8a5 100644 --- a/init/main.c +++ b/init/main.c @@ -692,6 +692,7 @@ noinline void __ref rest_init(void) */ rcu_read_lock(); tsk = find_task_by_pid_ns(pid, &init_pid_ns); + tsk->flags |= PF_NO_SETAFFINITY; set_cpus_allowed_ptr(tsk, cpumask_of(smp_processor_id())); rcu_read_unlock(); @@ -1440,6 +1441,11 @@ static int __ref kernel_init(void *unused) { int ret; + /* + * Wait until kthreadd is all set-up. + */ + wait_for_completion(&kthreadd_done); + kernel_init_freeable(); /* need to finish all async __init code before freeing the memory */ async_synchronize_full(); @@ -1520,11 +1526,6 @@ void __init console_on_rootfs(void) static noinline void __init kernel_init_freeable(void) { - /* - * Wait until kthreadd is all set-up. - */ - wait_for_completion(&kthreadd_done); - /* Now the scheduler is fully set up and can do blocking allocations */ gfp_allowed_mask = __GFP_BITS_MASK; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index adea0b1e8036..ae7737e6c2b2 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8867,6 +8867,7 @@ void __init sched_init_smp(void) /* Move init over to a non-isolated CPU */ if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_FLAG_DOMAIN)) < 0) BUG(); + current->flags &= ~PF_NO_SETAFFINITY; sched_init_granularity(); init_sched_rt_class(); ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] sched,init: Fix DEBUG_PREEMPT vs early boot 2021-05-31 10:21 ` [PATCH] sched,init: Fix DEBUG_PREEMPT vs early boot Peter Zijlstra @ 2021-06-01 11:54 ` Valentin Schneider 2021-06-01 14:04 ` [tip: sched/core] " tip-bot2 for Peter Zijlstra 1 sibling, 0 replies; 13+ messages in thread From: Valentin Schneider @ 2021-06-01 11:54 UTC (permalink / raw) To: Peter Zijlstra, linux-kernel; +Cc: linux-tip-commits, Yejune Deng, x86 On 31/05/21 12:21, Peter Zijlstra wrote: > On Wed, May 19, 2021 at 09:02:34AM -0000, tip-bot2 for Yejune Deng wrote: >> @@ -19,11 +19,7 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2) >> if (irqs_disabled()) >> goto out; >> >> - /* >> - * Kernel threads bound to a single CPU can safely use >> - * smp_processor_id(): >> - */ >> - if (current->nr_cpus_allowed == 1) >> + if (is_percpu_thread()) >> goto out; > > So my test box was unhappy with all this and started spewing lots of > DEBUG_PREEMPT warns on boot. > I get these too, though can't recall getting them when testing the above. I think it's tied with what Frederic found out with copy_process() copying PF_NO_SETAFFINITY, which it now no longer does. > This extends 8fb12156b8db6 to cover the new requirement. > > --- > Subject: sched,init: Fix DEBUG_PREEMPT vs early boot > > Extend 8fb12156b8db ("init: Pin init task to the boot CPU, initially") > to cover the new PF_NO_SETAFFINITY requirement. > > While there, move wait_for_completion(&kthreadd_done) into kernel_init() > to make it absolutely clear it is the very first thing done by the init > thread. > > Fixes: 570a752b7a9b ("lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed") > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Valentin Schneider <valentin.schneider@arm.com> Reviewed-by: Valentin Schneider <valentin.schneider@arm.com> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [tip: sched/core] sched,init: Fix DEBUG_PREEMPT vs early boot 2021-05-31 10:21 ` [PATCH] sched,init: Fix DEBUG_PREEMPT vs early boot Peter Zijlstra 2021-06-01 11:54 ` Valentin Schneider @ 2021-06-01 14:04 ` tip-bot2 for Peter Zijlstra 1 sibling, 0 replies; 13+ messages in thread From: tip-bot2 for Peter Zijlstra @ 2021-06-01 14:04 UTC (permalink / raw) To: linux-tip-commits Cc: Peter Zijlstra (Intel), Valentin Schneider, Borislav Petkov, x86, linux-kernel The following commit has been merged into the sched/core branch of tip: Commit-ID: 15faafc6b449777a85c0cf82dd8286c293fed4eb Gitweb: https://git.kernel.org/tip/15faafc6b449777a85c0cf82dd8286c293fed4eb Author: Peter Zijlstra <peterz@infradead.org> AuthorDate: Mon, 31 May 2021 12:21:13 +02:00 Committer: Peter Zijlstra <peterz@infradead.org> CommitterDate: Tue, 01 Jun 2021 16:00:11 +02:00 sched,init: Fix DEBUG_PREEMPT vs early boot Extend 8fb12156b8db ("init: Pin init task to the boot CPU, initially") to cover the new PF_NO_SETAFFINITY requirement. While there, move wait_for_completion(&kthreadd_done) into kernel_init() to make it absolutely clear it is the very first thing done by the init thread. Fixes: 570a752b7a9b ("lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed") Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Borislav Petkov <bp@alien8.de> Link: https://lkml.kernel.org/r/YLS4mbKUrA3Gnb4t@hirez.programming.kicks-ass.net --- init/main.c | 11 ++++++----- kernel/sched/core.c | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/init/main.c b/init/main.c index 7b027d9..e945ec8 100644 --- a/init/main.c +++ b/init/main.c @@ -692,6 +692,7 @@ noinline void __ref rest_init(void) */ rcu_read_lock(); tsk = find_task_by_pid_ns(pid, &init_pid_ns); + tsk->flags |= PF_NO_SETAFFINITY; set_cpus_allowed_ptr(tsk, cpumask_of(smp_processor_id())); rcu_read_unlock(); @@ -1440,6 +1441,11 @@ static int __ref kernel_init(void *unused) { int ret; + /* + * Wait until kthreadd is all set-up. + */ + wait_for_completion(&kthreadd_done); + kernel_init_freeable(); /* need to finish all async __init code before freeing the memory */ async_synchronize_full(); @@ -1520,11 +1526,6 @@ void __init console_on_rootfs(void) static noinline void __init kernel_init_freeable(void) { - /* - * Wait until kthreadd is all set-up. - */ - wait_for_completion(&kthreadd_done); - /* Now the scheduler is fully set up and can do blocking allocations */ gfp_allowed_mask = __GFP_BITS_MASK; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 3d25272..e205c19 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8862,6 +8862,7 @@ void __init sched_init_smp(void) /* Move init over to a non-isolated CPU */ if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_FLAG_DOMAIN)) < 0) BUG(); + current->flags &= ~PF_NO_SETAFFINITY; sched_init_granularity(); init_sched_rt_class(); ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 0/2] sched: Address idle task vs pcpu kthread checks 2021-05-10 15:10 [PATCH 0/2] sched: Address idle task vs pcpu kthread checks Valentin Schneider 2021-05-10 15:10 ` [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread Valentin Schneider 2021-05-10 15:10 ` [PATCH 2/2] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed Valentin Schneider @ 2021-05-12 11:00 ` Peter Zijlstra 2 siblings, 0 replies; 13+ messages in thread From: Peter Zijlstra @ 2021-05-12 11:00 UTC (permalink / raw) To: Valentin Schneider; +Cc: linux-kernel, mingo, tglx, bristot, yejune.deng On Mon, May 10, 2021 at 04:10:22PM +0100, Valentin Schneider wrote: > Note: I remember seeing some patch(es) from Peter tackling this exact > problem, but I couldn't find them again. Found it (by accident), yours is nicer though :-) > Valentin Schneider (1): > sched: Make the idle task quack like a per-CPU kthread > > Yejune Deng (1): > lib/smp_processor_id: Use is_percpu_thread() instead of > nr_cpus_allowed > > include/linux/kthread.h | 2 ++ > kernel/kthread.c | 30 ++++++++++++++++++------------ > kernel/sched/core.c | 21 +++++++++++++++------ > lib/smp_processor_id.c | 6 +----- > 4 files changed, 36 insertions(+), 23 deletions(-) Thanks! ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2021-06-01 14:05 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-05-10 15:10 [PATCH 0/2] sched: Address idle task vs pcpu kthread checks Valentin Schneider 2021-05-10 15:10 ` [PATCH 1/2] sched: Make the idle task quack like a per-CPU kthread Valentin Schneider 2021-05-10 15:57 ` Valentin Schneider 2021-05-11 7:32 ` Ingo Molnar 2021-05-11 9:33 ` Valentin Schneider 2021-05-19 8:09 ` [tip: sched/core] " tip-bot2 for Valentin Schneider 2021-05-10 15:10 ` [PATCH 2/2] lib/smp_processor_id: Use is_percpu_thread() instead of nr_cpus_allowed Valentin Schneider 2021-05-19 8:09 ` [tip: sched/core] " tip-bot2 for Yejune Deng 2021-05-19 9:02 ` tip-bot2 for Yejune Deng 2021-05-31 10:21 ` [PATCH] sched,init: Fix DEBUG_PREEMPT vs early boot Peter Zijlstra 2021-06-01 11:54 ` Valentin Schneider 2021-06-01 14:04 ` [tip: sched/core] " tip-bot2 for Peter Zijlstra 2021-05-12 11:00 ` [PATCH 0/2] sched: Address idle task vs pcpu kthread checks Peter Zijlstra
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.