[00/23] Simplify internal Linux syscall

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

Message

Michael Hudson-Doyle via Libc-alpha Nov. 9, 2020, 8:18 p.m.
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

-- 
2.25.1