[v2,00/24] Simplify internal Linux syscall

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

Message

Adhemerval Zanella Nov. 13, 2020, 4:58 p.m. UTC
  Changes from previous version [1]:

  - Removed syscall_error check, instead check the value to either 0
    (success) or negative (failure).

  - Always define SYSCALL_ERROR_FUNC.

---

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 (r == 0 || r != -ENOSYS)
    return -r;
  return -INTERNAL_SYSCALL_CALL (fallback, ...);

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 (r == 0 || 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 architecture 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.

[1] https://sourceware.org/pipermail/libc-alpha/2020-November/119456.html

Adhemerval Zanella (23):
  linux: Remove INTERNAL_SYSCALL_ERRNO
  linux: Remove INTERNAL_SYSCALL_ERROR_P
  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
  linux: Make SYSCALL_ERROR_FUNC as default

 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 +-
 sysdeps/arc/Versions                          |   3 -
 sysdeps/arc/nptl/tls.h                        |   4 +-
 sysdeps/csky/nptl/tls.h                       |   8 +-
 sysdeps/ia64/nptl/Makefile                    |   5 -
 sysdeps/m68k/nptl/tls.h                       |   9 +-
 sysdeps/mips/Makefile                         |   5 -
 sysdeps/mips/nptl/Makefile                    |   5 -
 sysdeps/mips/nptl/nptl-sysdep.S               |   2 -
 sysdeps/mips/nptl/tls.h                       |   8 +-
 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/adjtime.c             |   2 +-
 sysdeps/unix/sysv/linux/alpha/Makefile        |   3 +-
 sysdeps/unix/sysv/linux/alpha/fxstat64.c      |   2 +-
 sysdeps/unix/sysv/linux/alpha/lxstat64.c      |   2 +-
 .../{arc/sysdep.c => alpha/syscall_error.h}   |  18 +--
 sysdeps/unix/sysv/linux/alpha/sysdep.h        |   4 +-
 sysdeps/unix/sysv/linux/alpha/xstat64.c       |   2 +-
 sysdeps/unix/sysv/linux/arc/sysdep.h          |  17 +--
 sysdeps/unix/sysv/linux/arm/sysdep.S          |  33 -----
 sysdeps/unix/sysv/linux/arm/tls.h             |   6 +-
 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/dl-origin.c           |   2 +-
 sysdeps/unix/sysv/linux/dl-write.c            |   5 +-
 sysdeps/unix/sysv/linux/faccessat.c           |   4 +-
 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/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/dl-origin.c   |   2 +-
 sysdeps/unix/sysv/linux/getdents.c            |   2 +-
 .../unix/sysv/linux/hppa/____longjmp_chk.c    |   2 +-
 sysdeps/unix/sysv/linux/hppa/clone.S          |   6 +-
 sysdeps/unix/sysv/linux/i386/Makefile         |  13 --
 sysdeps/unix/sysv/linux/i386/brk.c            |   2 +-
 sysdeps/unix/sysv/linux/i386/sysdep.h         |   3 -
 sysdeps/unix/sysv/linux/ia64/Makefile         |   5 -
 sysdeps/unix/sysv/linux/ia64/rt-sysdep.S      |   1 -
 sysdeps/unix/sysv/linux/ia64/syscall_error.c  |   5 +
 .../{hppa/sysdep.c => ia64/syscall_error.h}   |  22 ++--
 sysdeps/unix/sysv/linux/ia64/sysdep.S         |  58 ---------
 sysdeps/unix/sysv/linux/libc_fatal.c          |   3 +-
 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    |   9 +-
 sysdeps/unix/sysv/linux/m68k/sysdep.S         |  50 --------
 sysdeps/unix/sysv/linux/m68k/sysdep.h         |   9 +-
 sysdeps/unix/sysv/linux/microblaze/Makefile   |   6 -
 sysdeps/unix/sysv/linux/microblaze/sysdep.S   |  39 ------
 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  |   5 +
 .../{i386/sysdep.c => mips/syscall_error.h}   |  21 ++--
 sysdeps/unix/sysv/linux/mips/vfork.S          |   1 +
 sysdeps/unix/sysv/linux/mknodat.c             |   2 +-
 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 +--
 sysdeps/unix/sysv/linux/nios2/sysdep.S        |  50 --------
 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     |  13 +-
 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/prlimit.c             |   4 +-
 sysdeps/unix/sysv/linux/pthread_kill.c        |   4 +-
 sysdeps/unix/sysv/linux/pthread_sigqueue.c    |   5 +-
 sysdeps/unix/sysv/linux/riscv/syscall.c       |   2 +-
 sysdeps/unix/sysv/linux/riscv/sysdep.S        |  51 --------
 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 -----------
 .../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  |   7 ++
 sysdeps/unix/sysv/linux/setegid.c             |   2 +-
 sysdeps/unix/sysv/linux/seteuid.c             |   2 +-
 sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
 sysdeps/unix/sysv/linux/shmat.c               |   6 +-
 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/speed.c               |   4 +-
 .../{powerpc/sysdep.c => syscall_error.c}     |  16 +--
 .../linux/{sh/sysdep.S => syscall_error.h}    |  26 ++--
 sysdeps/unix/sysv/linux/sysdep-vdso.h         |  26 +---
 sysdeps/unix/sysv/linux/sysdep.h              |  62 +++++-----
 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               |   4 +-
 sysdeps/unix/sysv/linux/ustat.c               |   4 +-
 sysdeps/unix/sysv/linux/utimensat.c           |   2 +-
 .../unix/sysv/linux/x86_64/syscall_error.c    |   7 ++
 .../unix/sysv/linux/x86_64/syscall_error.h    |  25 ++++
 sysdeps/unix/sysv/linux/x86_64/sysdep.S       |  40 ------
 sysdeps/unix/sysv/linux/x86_64/x32/times.c    |   4 -
 sysdeps/unix/sysv/linux/xmknod.c              |   2 +-
 sysdeps/unix/sysv/linux/xmknodat.c            |   2 +-
 sysdeps/unix/sysv/linux/xstat.c               |   2 +-
 sysdeps/unix/sysv/linux/xstat64.c             |   2 +-
 sysdeps/unix/sysv/linux/xstatconv.c           |  12 +-
 sysdeps/unix/x86_64/sysdep.S                  |  49 --------
 164 files changed, 330 insertions(+), 1355 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
 rename sysdeps/unix/sysv/linux/{arc/sysdep.c => alpha/syscall_error.h} (70%)
 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/ia64/rt-sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/ia64/syscall_error.c
 rename sysdeps/unix/sysv/linux/{hppa/sysdep.c => ia64/syscall_error.h} (66%)
 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
 rename sysdeps/unix/sysv/linux/{i386/sysdep.c => mips/syscall_error.h} (66%)
 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/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%)
 rename sysdeps/unix/sysv/linux/{sh/sysdep.S => syscall_error.h} (55%)
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_error.c
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_error.h
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/sysdep.S
 delete mode 100644 sysdeps/unix/x86_64/sysdep.S