The patch titled Subject: kill do_each_thread() has been added to the -mm mm-nonmm-unstable branch. Its filename is kill-do_each_thread.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/kill-do_each_thread.patch This patch will later appear in the mm-nonmm-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Oleg Nesterov <oleg@xxxxxxxxxx> Subject: kill do_each_thread() Date: Thu, 17 Aug 2023 18:37:08 +0200 Eric has pointed out that we still have 3 users of do_each_thread(). Change them to use for_each_process_thread() and kill this helper. There is a subtle change, after do_each_thread/while_each_thread g == t == &init_task, while after for_each_process_thread() they both point to nowhere, but this doesn't matter. > Why is for_each_process_thread() better than do_each_thread()? Say, for_each_process_thread() is rcu safe, do_each_thread() is not. And certainly for_each_process_thread(p, t) { do_something(p, t); } looks better than do_each_thread(p, t) { do_something(p, t); } while_each_thread(p, t); And again, there are only 3 users of this awkward helper left. It should have been killed years ago and in fact I thought it had already been killed. It uses while_each_thread() which needs some changes. Link: https://lkml.kernel.org/r/20230817163708.GA8248@xxxxxxxxxx Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx> Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> Cc: "Christian Brauner (Microsoft)" <brauner@xxxxxxxxxx> Cc: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> Cc: Jiri Slaby <jirislaby@xxxxxxxxxx> # tty/serial Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- arch/ia64/kernel/mca.c | 4 ++-- drivers/tty/tty_io.c | 4 ++-- fs/fs_struct.c | 4 ++-- include/linux/sched/signal.h | 7 ------- 4 files changed, 6 insertions(+), 13 deletions(-) --- a/arch/ia64/kernel/mca.c~kill-do_each_thread +++ a/arch/ia64/kernel/mca.c @@ -1630,10 +1630,10 @@ default_monarch_init_process(struct noti } printk("\n\n"); if (read_trylock(&tasklist_lock)) { - do_each_thread (g, t) { + for_each_process_thread(g, t) { printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); show_stack(t, NULL, KERN_DEFAULT); - } while_each_thread (g, t); + } read_unlock(&tasklist_lock); } /* FIXME: This will not restore zapped printk locks. */ --- a/drivers/tty/tty_io.c~kill-do_each_thread +++ a/drivers/tty/tty_io.c @@ -3031,7 +3031,7 @@ void __do_SAK(struct tty_struct *tty) } while_each_pid_task(session, PIDTYPE_SID, p); /* Now kill any processes that happen to have the tty open */ - do_each_thread(g, p) { + for_each_process_thread(g, p) { if (p->signal->tty == tty) { tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n", task_pid_nr(p), p->comm); @@ -3048,7 +3048,7 @@ void __do_SAK(struct tty_struct *tty) PIDTYPE_SID); } task_unlock(p); - } while_each_thread(g, p); + } read_unlock(&tasklist_lock); put_pid(session); } --- a/fs/fs_struct.c~kill-do_each_thread +++ a/fs/fs_struct.c @@ -62,7 +62,7 @@ void chroot_fs_refs(const struct path *o int count = 0; read_lock(&tasklist_lock); - do_each_thread(g, p) { + for_each_process_thread(g, p) { task_lock(p); fs = p->fs; if (fs) { @@ -79,7 +79,7 @@ void chroot_fs_refs(const struct path *o spin_unlock(&fs->lock); } task_unlock(p); - } while_each_thread(g, p); + } read_unlock(&tasklist_lock); while (count--) path_put(old_root); --- a/include/linux/sched/signal.h~kill-do_each_thread +++ a/include/linux/sched/signal.h @@ -648,13 +648,6 @@ extern void flush_itimer_signals(void); extern bool current_is_single_threaded(void); -/* - * Careful: do_each_thread/while_each_thread is a double loop so - * 'break' will not work as expected - use goto instead. - */ -#define do_each_thread(g, t) \ - for (g = t = &init_task ; (g = t = next_task(g)) != &init_task ; ) do - #define while_each_thread(g, t) \ while ((t = next_thread(t)) != g) _ Patches currently in -mm which might be from oleg@xxxxxxxxxx are kill-do_each_thread.patch