[PATCH 00/17] arch: remove do_fork() and HAVE_COPY_THREAD_TLS
From: Christian Brauner
Date: Mon Jun 22 2020 - 19:46:15 EST
Hey,
This is a series I had announced some time back (cf. [2]) when we
reworked a chunk of the process creation paths in the kernel and
switched to struct {kernel_}clone_args. I've been sitting on this for a
while due to lack of time and because testing on all architectures that
are non-trivially impacted proved to be interesting. So first, I have to
give a big thank you to Arnd (Bergmann) and Adrian (Glaubitz).
Arnd for the gcc crosstools builds which made it possible to compile for
nearly all supported arches with gcc 10. Adrian for providing me with a
ia64 rack server (that sure made summer in my workspace come a little
earlier) to test the ia64 specific changes, alpha, and other stuff.
This patch series switches all remaining architectures to select
HAVE_COPY_THREAD_TLS and thus to the copy_thread_tls() calling
convention. This split makes the process creation codepaths a bit
convoluted to read. Each architecture has their own copy_thread()
function unless it selects HAVE_COPY_THREAD_TLS then it has a
copy_thread_tls() function. Removing this split cleans up the process
creation codepaths and paves the way for implementing clone3() on those
architectures since it requires the copy_thread_tls() calling
convention. After having made each architectures support
copy_thread_tls() this series simply renames that function back to
copy_thread(). It also switches all architectures that call do_fork()
directly over to _do_fork() and the struct kernel_clone_args calling
convention. This is a corollary of switching the architectures that did
not yet support it over to copy_thread_tls() since do_fork() is
conditional on not supporting copy_thread_tls() (since it lacks an
argument for tls). But the do_fork() removal is in itself already
useful as it allows to to remove the export of both do_fork() and
_do_fork() we currently have in favor of only _do_fork(). This has
already been discussed back when we added clone3(). The legacy clone()
calling convention is - as most know - somewhat odd or as arch/Kconfig
(cf. [1]) phrases it:
#
# ABI hall of shame
#
config CLONE_BACKWARDS
config CLONE_BACKWARDS2
config CLONE_BACKWARDS3
that is aggravated by the fact that some architectures such as sparc
follow the CLONE_BACKWARDSx calling convention but don't really select
the corresponding config option since thy call do_fork() directly. So
do_fork() enforces a somewhat arbitrary ordering in the first place that
doesn't really help the individual architectures that deviate from it.
They can thus simply be switched to _do_fork() enforcing a single
calling convention. Most architectures have made a similar switch
already (m68k comes to mind). Removing do_fork() is also a corollary of
switching all architectures over to the copy_thread_tls() calling
convention.
Overall this series removes more code then it adds even with a chunk of
added comments (268(+)/274(-)). It simplifies a chunk of arch specific
assembly either by moving the code into C or by simply rewriting the
assembly.
I've done my best to test this. Architectures that have been touched in
non-trivial ways have all been actually boot and stress tested: sparc
and ia64 have been tested with Debian 9 images. nios2 with a custom
build buildroot image. h8300 I couldn't get something bootable but the
changes have been fairly automatic and I'm sure we'll hear people yell
if I broke something there. All other architectures that have been
touched in trivial ways have been compile tested for each single patch
of the series via git rebase -x "make ..." v5.8-rc2. arm and x86 have
been boot tested even though they have just been trivially touched
(removal of the HAVE_COPY_THREAD_TLS macro from their Kconfig) because
well they are basically "core architectures" and since it is trivial to
get your hands on a useable image.
The series is available at:
https://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git/log/?h=do_fork_removal
https://gitlab.com/brauner/linux/-/tree/do_fork_removal
https://github.com/brauner/linux/tree/do_fork_removal
if anyone with access to weirder architectures wants to test them.
Thanks!
Christian
[1]: d2125043aebf ("generic sys_fork / sys_vfork / sys_clone")
[2]: 606e9ad20094
Christian Brauner (17):
fork: fold legacy_clone_args_valid() into _do_fork()
sparc64: enable HAVE_COPY_THREAD_TLS
sparc: share process creation helpers between sparc and sparc64
sparc: unconditionally enable HAVE_COPY_THREAD_TLS
ia64: enable HAVE_COPY_THREAD_TLS, switch to kernel_clone_args
nios2: enable HAVE_COPY_THREAD_TLS, switch to kernel_clone_args
h8300: select HAVE_COPY_THREAD_TLS, switch to kernel_clone_args
fork: remove do_fork()
alpha: switch to copy_thread_tls()
c6x: switch to copy_thread_tls()
hexagon: switch to copy_thread_tls()
microblaze: switch to copy_thread_tls()
nds32: switch to copy_thread_tls()
sh: switch to copy_thread_tls()
unicore: switch to copy_thread_tls()
arch: remove HAVE_COPY_THREAD_TLS
arch: rename copy_thread_tls() back to copy_thread()
arch/Kconfig | 7 --
arch/alpha/kernel/process.c | 9 ++-
arch/arc/Kconfig | 1 -
arch/arc/kernel/process.c | 2 +-
arch/arm/Kconfig | 1 -
arch/arm/kernel/process.c | 2 +-
arch/arm64/Kconfig | 1 -
arch/arm64/kernel/process.c | 2 +-
arch/c6x/kernel/process.c | 4 +-
arch/csky/Kconfig | 1 -
arch/csky/kernel/process.c | 2 +-
arch/h8300/kernel/process.c | 18 +++--
arch/hexagon/kernel/process.c | 4 +-
arch/ia64/kernel/entry.S | 32 ++++-----
arch/ia64/kernel/process.c | 30 ++++++--
arch/m68k/Kconfig | 1 -
arch/m68k/kernel/process.c | 5 +-
arch/microblaze/kernel/process.c | 4 +-
arch/mips/Kconfig | 1 -
arch/mips/kernel/process.c | 2 +-
arch/nds32/kernel/process.c | 5 +-
arch/nios2/kernel/entry.S | 7 +-
arch/nios2/kernel/process.c | 23 ++++++-
arch/openrisc/Kconfig | 1 -
arch/openrisc/kernel/process.c | 4 +-
arch/parisc/Kconfig | 1 -
arch/parisc/kernel/process.c | 2 +-
arch/powerpc/Kconfig | 1 -
arch/powerpc/kernel/process.c | 2 +-
arch/riscv/Kconfig | 1 -
arch/riscv/kernel/process.c | 2 +-
arch/s390/Kconfig | 1 -
arch/s390/kernel/process.c | 2 +-
arch/sh/kernel/process_32.c | 4 +-
arch/sparc/include/asm/syscalls.h | 7 +-
arch/sparc/kernel/Makefile | 1 +
arch/sparc/kernel/entry.S | 29 ++------
arch/sparc/kernel/kernel.h | 11 ++-
arch/sparc/kernel/process.c | 110 ++++++++++++++++++++++++++++++
arch/sparc/kernel/process_32.c | 32 +--------
arch/sparc/kernel/process_64.c | 39 +----------
arch/sparc/kernel/syscalls.S | 23 ++++---
arch/um/Kconfig | 1 -
arch/um/kernel/process.c | 2 +-
arch/unicore32/kernel/process.c | 8 +--
arch/x86/Kconfig | 1 -
arch/x86/kernel/process.c | 2 +-
arch/x86/kernel/sys_ia32.c | 3 -
arch/x86/kernel/unwind_frame.c | 2 +-
arch/xtensa/Kconfig | 1 -
arch/xtensa/kernel/process.c | 2 +-
include/linux/sched/task.h | 17 +----
kernel/fork.c | 66 +++++-------------
53 files changed, 268 insertions(+), 274 deletions(-)
create mode 100644 arch/sparc/kernel/process.c
base-commit: 48778464bb7d346b47157d21ffde2af6b2d39110
--
2.27.0