mbox series

[00/23] Simplify internal Linux syscall

Message ID 20201109201826.120534-1-adhemerval.zanella@linaro.org
Headers show
Series Simplify internal Linux syscall | expand

Message

Adhemerval Zanella Nov. 9, 2020, 8:18 p.m. UTC
This refactor aims to remove and simplify the Linux internal syscall
mechanism by using inline functions instead of macros and by removing
the possible requirement to each architecture to define a
__syscall_error routine to handle errno setting.

Instead of issuing the following for syscalls that don't set the
errno:

  int r = INTERNAL_SYSCALL_CALL (syscall, ...);
  if (! INTERNAL_SYSCALL_ERROR_P (r)
      || INTERNAL_SYSCALL_ERRNO (r) != ENOSYS)
    return INTERNAL_SYSCALL_ERRNO (r);
  r = INTERNAL_SYSCALL_CALL (fallback, ...);
  return INTERNAL_SYSCALL_ERRNO (r) ? -r : 0;

It would be written as:

  int r = INTERNAL_SYSCALL_CALL (syscall, ...);
  if (! syscall_error (r) || -r != ENOSYS)
    return -r;
  return -INTERNAL_SYSCALL_CALL (fallback, ...);

The error check can be even simplified to 'if -r != ENOSYS' now that
INTERNAL_SYSCALL_CALL will return a value between [-4096UL, 0UL) in
the case of failure.

For syscall which sets the errno, instead of:

  int r = INTERNAL_SYSCALL_CALL (syscall, ...);
  if (! INTERNAL_SYSCALL_ERROR_P (r)
      || INTERNAL_SYSCALL_ERRNO (r) != ENOSYS)
    return INLINE_SYSCALL_ERROR_RETURN_VALUE (r);
  r = INTERNAL_SYSCALL_CALL (fallback, ...);
  [...]
  __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (sc_ret))
    ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (sc_ret))
    : sc_ret;

It would be written as:

  int r = INTERNAL_SYSCALL_CALL (syscall, ...);
  if (! syscall_error (r) || -r != ENOSYS)
    return syscall_ret (r);
  r = INTERNAL_SYSCALL_CALL (fallback, ...);
  [...]
  return syscall_ret (r);

The compiler should easily optimize the first syscall_ret to just call
__syscall_error in first case.

Another optimization is to avoid require each archicture to define an
arch-specific __syscall_error for the case where calling an external
symbols yields faster or more compact code (for instance on i386).  Each
architecture might define SYSCALL_ERROR_FUNC, which in turn will build
and link to each library that issues syscall a local __syscall_error
routine.

I checked each architecture whether inline or outline __syscall_error
results or not in a better code size and enable it accordingly.  Some
ABIs only enables for static case (x86_64), even when the gain is
minimal.

This is a first step to move the syscall to proper inline implementation
instead of the macro hell and to move the auto-generation to use C
generated instead of the assembly ones.


Adhemerval Zanella (23):
  linux: Remove INTERNAL_SYSCALL_ERRNO
  linux: Replace INTERNAL_SYSCALL_ERROR_P macro with a inline function
  Remove tls.h inclusion from internal errno.h
  linux: Add syscall_ret and use it on INLINE_SYSCALL
  linux: Replace INLINE_SYSCALL_ERROR_RETURN_VALUE with __syscall_error
  linux: Use generic __syscall_error for aarch64
  linux: Use generic __syscall_error for i386
  linux: Use generic __syscall_error for arc
  linux: Use generic __syscall_error for powerpc
  linux: Use generic __syscall_error for sparc
  linux: Use generic __syscall_error for hppa
  linux: Use generic __syscall_error for arm
  linux: Use generic __syscall_error for x86_64
  linux: Use generic __syscall_error for s390
  linux: Use generic __syscall_error for sh
  linux: Use generic __syscall_error for microblaze
  linux: Use generic __syscall_error for ia64
  linux: Use generic __syscall_error for m68k
  linux: Use generic __syscall_error for csky
  linux: Use generic __syscall_error for riscv
  linux: Use generic __syscall_error for nios2
  linux: Use generic __syscall_error for alpha
  linux: Use generic __syscall_error for mips

 include/errno.h                               |   2 -
 io/lchmod.c                                   |   4 +-
 malloc/reallocarray.c                         |   1 +
 misc/ustat.c                                  |   1 +
 nptl/allocatestack.c                          |   6 +-
 nptl/nptl-init.c                              |   6 +-
 nptl/pthread_cancel.c                         |   4 +-
 nptl/pthread_getaffinity.c                    |   4 +-
 nptl/pthread_mutex_trylock.c                  |   3 +-
 nptl/pthread_setaffinity.c                    |   9 +-
 nptl/pthread_sigmask.c                        |   8 +-
 nss/nss_fgetent_r.c                           |   1 +
 posix/execl.c                                 |   1 +
 posix/execle.c                                |   1 +
 posix/execlp.c                                |   1 +
 posix/spawn_faction_addchdir.c                |   2 +-
 pwd/putpwent.c                                |   1 +
 signal/sigempty.c                             |   1 +
 signal/sigismem.c                             |   1 +
 sysdeps/arc/Versions                          |   3 -
 sysdeps/arc/nptl/tls.h                        |   2 +-
 sysdeps/csky/nptl/tls.h                       |   2 +-
 sysdeps/generic/internal-signals.h            |   1 +
 sysdeps/ia64/nptl/Makefile                    |   5 -
 sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c        |   3 -
 sysdeps/m68k/nptl/tls.h                       |   2 +-
 sysdeps/mach/hurd/mmap64.c                    |   1 +
 sysdeps/mach/hurd/waitid.c                    |   1 +
 sysdeps/microblaze/backtrace.c                |   1 +
 sysdeps/mips/Makefile                         |   5 -
 sysdeps/mips/nptl/Makefile                    |   5 -
 sysdeps/mips/nptl/nptl-sysdep.S               |   2 -
 sysdeps/mips/nptl/tls.h                       |   2 +-
 sysdeps/nptl/futex-internal.h                 |   1 +
 sysdeps/nptl/lowlevellock-futex.h             |   7 +-
 sysdeps/powerpc/nofpu/sfp-machine.h           |   2 +-
 sysdeps/powerpc/powerpc32/sysdep.h            |   1 +
 sysdeps/powerpc/powerpc64/sysdep.h            |   7 +-
 sysdeps/riscv/nptl/Makefile                   |   5 -
 sysdeps/riscv/nptl/nptl-sysdep.S              |   2 -
 sysdeps/s390/nptl/Makefile                    |   5 -
 sysdeps/unix/alpha/Makefile                   |   8 +-
 sysdeps/unix/alpha/rt-sysdep.S                |   1 -
 .../alpha/{sysdep.S => syscall_error_asm.S}   |   8 +-
 sysdeps/unix/arm/sysdep.S                     |  62 ----------
 sysdeps/unix/mips/mips32/sysdep.h             |   5 +-
 sysdeps/unix/mips/mips64/sysdep.h             |   3 +-
 sysdeps/unix/mips/rt-sysdep.S                 |   1 -
 sysdeps/unix/mips/sysdep.S                    |  99 ---------------
 sysdeps/unix/sh/sysdep.S                      | 115 ------------------
 sysdeps/unix/sysv/linux/Makefile              |   9 +-
 sysdeps/unix/sysv/linux/aarch64/sysdep.c      |  33 -----
 sysdeps/unix/sysv/linux/aarch64/sysdep.h      |   2 +
 sysdeps/unix/sysv/linux/adjtime.c             |   3 +-
 sysdeps/unix/sysv/linux/alpha/Makefile        |   3 +-
 sysdeps/unix/sysv/linux/alpha/fxstat64.c      |   2 +-
 sysdeps/unix/sysv/linux/alpha/lxstat64.c      |   2 +-
 sysdeps/unix/sysv/linux/alpha/sysdep.h        |   4 +-
 sysdeps/unix/sysv/linux/alpha/xstat64.c       |   2 +-
 sysdeps/unix/sysv/linux/arc/sysdep.c          |  33 -----
 sysdeps/unix/sysv/linux/arc/sysdep.h          |  19 +--
 sysdeps/unix/sysv/linux/arm/sysdep.S          |  33 -----
 sysdeps/unix/sysv/linux/arm/sysdep.h          |   2 +
 sysdeps/unix/sysv/linux/arm/tls.h             |   2 +-
 sysdeps/unix/sysv/linux/clock_getcpuclockid.c |   1 +
 sysdeps/unix/sysv/linux/clock_nanosleep.c     |   2 +-
 sysdeps/unix/sysv/linux/createthread.c        |   6 +-
 sysdeps/unix/sysv/linux/csky/abiv2/sysdep.S   |  65 ----------
 sysdeps/unix/sysv/linux/csky/sysdep.h         |   2 +
 sysdeps/unix/sysv/linux/dl-origin.c           |   2 +-
 sysdeps/unix/sysv/linux/dl-write.c            |   5 +-
 sysdeps/unix/sysv/linux/faccessat.c           |  10 +-
 sysdeps/unix/sysv/linux/fchmodat.c            |   2 +-
 sysdeps/unix/sysv/linux/fcntl_nocancel.c      |   5 +-
 sysdeps/unix/sysv/linux/fstatat.c             |   8 +-
 sysdeps/unix/sysv/linux/fstatat64.c           |   6 +-
 sysdeps/unix/sysv/linux/ftime.c               |   1 +
 sysdeps/unix/sysv/linux/ftruncate64.c         |   1 -
 sysdeps/unix/sysv/linux/futimens.c            |   2 +-
 sysdeps/unix/sysv/linux/fxstat.c              |   2 +-
 sysdeps/unix/sysv/linux/fxstat64.c            |   2 +-
 sysdeps/unix/sysv/linux/fxstatat.c            |   2 +-
 sysdeps/unix/sysv/linux/fxstatat64.c          |   2 +-
 sysdeps/unix/sysv/linux/generic/chmod.c       |   4 +-
 sysdeps/unix/sysv/linux/generic/chown.c       |   4 +-
 sysdeps/unix/sysv/linux/generic/dl-origin.c   |   2 +-
 sysdeps/unix/sysv/linux/generic/dup2.c        |   3 +-
 .../unix/sysv/linux/generic/epoll_create.c    |   5 +-
 .../unix/sysv/linux/generic/inotify_init.c    |   5 +-
 sysdeps/unix/sysv/linux/generic/lchown.c      |   4 +-
 sysdeps/unix/sysv/linux/generic/link.c        |   3 +-
 sysdeps/unix/sysv/linux/generic/pipe.c        |   3 +-
 sysdeps/unix/sysv/linux/generic/readlink.c    |   2 +-
 sysdeps/unix/sysv/linux/generic/rmdir.c       |   4 +-
 sysdeps/unix/sysv/linux/generic/symlink.c     |   3 +-
 sysdeps/unix/sysv/linux/generic/unlink.c      |   4 +-
 .../sysv/linux/generic/wordsize-32/fstatfs.c  |   2 +-
 .../sysv/linux/generic/wordsize-32/overflow.h |   1 +
 .../sysv/linux/generic/wordsize-32/sendfile.c |   2 +
 .../sysv/linux/generic/wordsize-32/statfs.c   |   2 +-
 sysdeps/unix/sysv/linux/getdents.c            |   2 +-
 sysdeps/unix/sysv/linux/getentropy.c          |   1 +
 sysdeps/unix/sysv/linux/getrlimit.c           |   3 +-
 sysdeps/unix/sysv/linux/getrlimit64.c         |   1 +
 sysdeps/unix/sysv/linux/gettimeofday.c        |   7 +-
 .../unix/sysv/linux/hppa/____longjmp_chk.c    |   2 +-
 sysdeps/unix/sysv/linux/hppa/clone.S          |   6 +-
 sysdeps/unix/sysv/linux/hppa/sysdep.c         |  29 -----
 sysdeps/unix/sysv/linux/hppa/sysdep.h         |   4 +
 sysdeps/unix/sysv/linux/i386/Makefile         |  13 --
 sysdeps/unix/sysv/linux/i386/brk.c            |   2 +-
 sysdeps/unix/sysv/linux/i386/sysdep.c         |  30 -----
 sysdeps/unix/sysv/linux/i386/sysdep.h         |   6 +-
 sysdeps/unix/sysv/linux/ia64/Makefile         |   5 -
 sysdeps/unix/sysv/linux/ia64/rt-sysdep.S      |   1 -
 sysdeps/unix/sysv/linux/ia64/syscall_error.c  |   3 +
 sysdeps/unix/sysv/linux/ia64/sysdep.S         |  58 ---------
 sysdeps/unix/sysv/linux/internal-signals.h    |   1 +
 sysdeps/unix/sysv/linux/libc_fatal.c          |   5 +-
 sysdeps/unix/sysv/linux/lxstat.c              |   2 +-
 sysdeps/unix/sysv/linux/lxstat64.c            |   2 +-
 .../unix/sysv/linux/m68k/____longjmp_chk.c    |   2 +-
 sysdeps/unix/sysv/linux/m68k/getpagesize.c    |   2 +-
 sysdeps/unix/sysv/linux/m68k/sysdep.S         |  50 --------
 sysdeps/unix/sysv/linux/m68k/sysdep.h         |  11 +-
 sysdeps/unix/sysv/linux/microblaze/Makefile   |   6 -
 sysdeps/unix/sysv/linux/microblaze/sysdep.S   |  39 ------
 sysdeps/unix/sysv/linux/microblaze/sysdep.h   |   4 +
 sysdeps/unix/sysv/linux/mips/clone.S          |   1 +
 sysdeps/unix/sysv/linux/mips/getcontext.S     |   1 +
 .../unix/sysv/linux/mips/mips64/fxstatat64.c  |   2 +-
 .../unix/sysv/linux/mips/mips64/n64/ioctl.S   |   3 +-
 sysdeps/unix/sysv/linux/mips/mips64/syscall.S |   3 +-
 sysdeps/unix/sysv/linux/mips/setcontext.S     |   1 +
 sysdeps/unix/sysv/linux/mips/swapcontext.S    |   1 +
 sysdeps/unix/sysv/linux/mips/syscall_error.c  |   3 +
 sysdeps/unix/sysv/linux/mips/vfork.S          |   1 +
 sysdeps/unix/sysv/linux/mknodat.c             |   3 +-
 sysdeps/unix/sysv/linux/mmap.c                |   2 +-
 sysdeps/unix/sysv/linux/mmap64.c              |   2 +-
 sysdeps/unix/sysv/linux/mq_open.c             |   2 +-
 sysdeps/unix/sysv/linux/mq_unlink.c           |  14 +--
 .../unix/sysv/linux/netlink_assert_response.c |   1 +
 sysdeps/unix/sysv/linux/nios2/sysdep.S        |  50 --------
 sysdeps/unix/sysv/linux/nios2/sysdep.h        |   2 +
 sysdeps/unix/sysv/linux/not-errno.h           |  14 +--
 sysdeps/unix/sysv/linux/nscd_setup_thread.c   |   2 +-
 sysdeps/unix/sysv/linux/personality.c         |  10 +-
 sysdeps/unix/sysv/linux/posix_fadvise.c       |  19 ++-
 sysdeps/unix/sysv/linux/posix_fadvise64.c     |  14 +--
 sysdeps/unix/sysv/linux/posix_fallocate.c     |   6 +-
 sysdeps/unix/sysv/linux/posix_fallocate64.c   |   6 +-
 sysdeps/unix/sysv/linux/posix_madvise.c       |   3 +-
 sysdeps/unix/sysv/linux/powerpc/Makefile      |   7 --
 .../unix/sysv/linux/powerpc/powerpc32/brk.S   |   1 +
 .../unix/sysv/linux/powerpc/powerpc32/clone.S |   3 +-
 .../sysv/linux/powerpc/powerpc32/getcontext.S |   2 +
 .../linux/powerpc/powerpc32/makecontext.S     |   2 +-
 .../powerpc/powerpc32/nofpu/getcontext.S      |   2 +-
 .../powerpc/powerpc32/nofpu/setcontext.S      |   2 +-
 .../powerpc/powerpc32/nofpu/swapcontext.S     |   2 +-
 .../sysv/linux/powerpc/powerpc32/setcontext.S |   3 +-
 .../linux/powerpc/powerpc32/swapcontext.S     |   3 +-
 sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c   |   1 -
 sysdeps/unix/sysv/linux/powerpc/sysdep.h      |   2 +
 sysdeps/unix/sysv/linux/prlimit.c             |   8 +-
 sysdeps/unix/sysv/linux/pthread_kill.c        |   4 +-
 sysdeps/unix/sysv/linux/pthread_sigqueue.c    |   5 +-
 sysdeps/unix/sysv/linux/readahead.c           |   2 +-
 sysdeps/unix/sysv/linux/riscv/syscall.c       |   2 +-
 sysdeps/unix/sysv/linux/riscv/sysdep.S        |  51 --------
 sysdeps/unix/sysv/linux/riscv/sysdep.h        |   2 +
 sysdeps/unix/sysv/linux/s390/Makefile         |   5 -
 sysdeps/unix/sysv/linux/s390/rt-sysdep.S      |   1 -
 .../sysv/linux/s390/s390-32/____longjmp_chk.c |   2 +-
 .../sysv/linux/s390/s390-32/posix_fadvise64.c |   5 +-
 sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S |  74 -----------
 sysdeps/unix/sysv/linux/s390/s390-32/utmp32.c |   2 +-
 .../unix/sysv/linux/s390/s390-32/utmpx32.c    |   2 +-
 .../sysv/linux/s390/s390-64/____longjmp_chk.c |   2 +-
 sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S |  75 ------------
 sysdeps/unix/sysv/linux/s390/syscall_error.c  |   5 +
 sysdeps/unix/sysv/linux/semop.c               |   2 +-
 sysdeps/unix/sysv/linux/setegid.c             |   2 +-
 sysdeps/unix/sysv/linux/seteuid.c             |   2 +-
 sysdeps/unix/sysv/linux/setrlimit.c           |   3 +-
 sysdeps/unix/sysv/linux/setrlimit64.c         |   1 +
 sysdeps/unix/sysv/linux/settimezone.c         |   1 +
 sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
 sysdeps/unix/sysv/linux/sh/sysdep.S           |  32 -----
 sysdeps/unix/sysv/linux/sh/sysdep.h           |   2 +
 sysdeps/unix/sysv/linux/shmat.c               |   4 +-
 sysdeps/unix/sysv/linux/shmget.c              |   3 +-
 sysdeps/unix/sysv/linux/socketcall.h          |   2 +
 sysdeps/unix/sysv/linux/sparc/Makefile        |   9 +-
 sysdeps/unix/sysv/linux/sparc/rt-sysdep.c     |   1 -
 sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S  |   1 +
 .../unix/sysv/linux/sparc/sparc32/syscall.S   |   1 +
 .../unix/sysv/linux/sparc/sparc32/sysdep.h    |   1 +
 sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S |   1 +
 sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S  |   1 +
 .../unix/sysv/linux/sparc/sparc64/syscall.S   |   1 +
 .../unix/sysv/linux/sparc/sparc64/sysdep.h    |   1 +
 sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S |   1 +
 sysdeps/unix/sysv/linux/sparc/sysdep.c        |   1 -
 sysdeps/unix/sysv/linux/sparc/sysdep.h        |   2 +
 sysdeps/unix/sysv/linux/speed.c               |   6 +-
 sysdeps/unix/sysv/linux/statx.c               |   2 +-
 .../{powerpc/sysdep.c => syscall_error.c}     |  16 +--
 sysdeps/unix/sysv/linux/sysctl.c              |   1 +
 sysdeps/unix/sysv/linux/sysdep-vdso.h         |  26 +---
 sysdeps/unix/sysv/linux/sysdep.h              |  77 +++++++-----
 sysdeps/unix/sysv/linux/tcsendbrk.c           |   2 +-
 sysdeps/unix/sysv/linux/tcsetattr.c           |   2 +-
 sysdeps/unix/sysv/linux/timer_create.c        |   4 +-
 sysdeps/unix/sysv/linux/times.c               |   7 +-
 sysdeps/unix/sysv/linux/truncate64.c          |   1 -
 sysdeps/unix/sysv/linux/ustat.c               |   6 +-
 sysdeps/unix/sysv/linux/utimensat.c           |   2 +-
 .../unix/sysv/linux/x86_64/syscall_error.c    |   5 +
 sysdeps/unix/sysv/linux/x86_64/sysdep.S       |  40 ------
 sysdeps/unix/sysv/linux/x86_64/x32/times.c    |   9 +-
 sysdeps/unix/sysv/linux/xmknod.c              |   3 +-
 sysdeps/unix/sysv/linux/xmknodat.c            |   3 +-
 sysdeps/unix/sysv/linux/xstat.c               |   2 +-
 sysdeps/unix/sysv/linux/xstat64.c             |   2 +-
 sysdeps/unix/sysv/linux/xstatconv.c           |  13 +-
 sysdeps/unix/x86_64/sysdep.S                  |  49 --------
 sysdeps/x86_64/stackinfo.h                    |  10 +-
 229 files changed, 388 insertions(+), 1468 deletions(-)
 delete mode 100644 sysdeps/mips/nptl/nptl-sysdep.S
 delete mode 100644 sysdeps/riscv/nptl/nptl-sysdep.S
 delete mode 100644 sysdeps/unix/alpha/rt-sysdep.S
 rename sysdeps/unix/alpha/{sysdep.S => syscall_error_asm.S} (94%)
 delete mode 100644 sysdeps/unix/arm/sysdep.S
 delete mode 100644 sysdeps/unix/mips/rt-sysdep.S
 delete mode 100644 sysdeps/unix/mips/sysdep.S
 delete mode 100644 sysdeps/unix/sh/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/aarch64/sysdep.c
 delete mode 100644 sysdeps/unix/sysv/linux/arc/sysdep.c
 delete mode 100644 sysdeps/unix/sysv/linux/arm/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/csky/abiv2/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/hppa/sysdep.c
 delete mode 100644 sysdeps/unix/sysv/linux/i386/sysdep.c
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/rt-sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/ia64/syscall_error.c
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/m68k/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/microblaze/sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/mips/syscall_error.c
 delete mode 100644 sysdeps/unix/sysv/linux/nios2/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c
 delete mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/s390/rt-sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/s390/syscall_error.c
 delete mode 100644 sysdeps/unix/sysv/linux/sh/sysdep.S
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/rt-sysdep.c
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sysdep.c
 rename sysdeps/unix/sysv/linux/{powerpc/sysdep.c => syscall_error.c} (77%)
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_error.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/sysdep.S
 delete mode 100644 sysdeps/unix/x86_64/sysdep.S