public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 01/14] linux: Simplify clock_getres
@ 2020-09-08 14:57 Adhemerval Zanella
  2020-09-08 14:57 ` [PATCH v2 02/14] linux: Add ppoll time64 optimization Adhemerval Zanella
                   ` (13 more replies)
  0 siblings, 14 replies; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

With arch-syscall.h it can now assumes the existance of either
__NR_clock_getres or __NR_clock_getres_time64.  The 32-bit time_t
support is now only build for !__ASSUME_TIME64_SYSCALLS.

It also uses the time64-support functions to simplify it further.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_getres.c | 38 ++++++++++----------------
 1 file changed, 15 insertions(+), 23 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 5f6955ab10..6be73c94de 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -21,6 +21,7 @@
 #include <time.h>
 
 #include <sysdep-vdso.h>
+#include <time64-support.h>
 #include <shlib-compat.h>
 #include <kernel-features.h>
 
@@ -28,36 +29,26 @@
 int
 __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-  /* 64 bit ABIs or Newer 32-bit ABIs that only support 64-bit time_t.  */
-# ifndef __NR_clock_getres_time64
-#  define __NR_clock_getres_time64 __NR_clock_getres
-# endif
-# ifdef HAVE_CLOCK_GETRES64_VSYSCALL
-  return INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
-# else
-  return INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
-# endif
-#else
   int r;
-  /* Old 32-bit ABI with possible 64-bit time_t support.  */
-# ifdef __NR_clock_getres_time64
-  /* Avoid issue a __NR_clock_getres_time64 syscall on kernels that do not
-     support 64-bit time_t.  */
-  static int time64_support = 1;
-  if (atomic_load_relaxed (&time64_support) != 0)
+
+#ifndef __NR_clock_getres_time64
+# define __NR_clock_getres_time64 __NR_clock_getres
+#endif
+  if (supports_time64 ())
     {
-#  ifdef HAVE_CLOCK_GETRES64_VSYSCALL
+#ifdef HAVE_CLOCK_GETRES64_VSYSCALL
       r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
-#  else
+#else
       r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
-#  endif
+#endif
+
       if (r == 0 || errno != ENOSYS)
 	return r;
 
-      atomic_store_relaxed (&time64_support, 0);
+      mark_time64_unsupported ();
     }
-# endif
+
+#ifndef __ASSUME_TIME64_SYSCALLS
   /* Fallback code that uses 32-bit support.  */
   struct timespec ts32;
 # ifdef HAVE_CLOCK_GETRES_VSYSCALL
@@ -67,8 +58,9 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
 # endif
   if (r == 0)
     *res = valid_timespec_to_timespec64 (ts32);
-  return r;
 #endif
+
+  return r;
 }
 
 #if __TIMESIZE != 64
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 02/14] linux: Add ppoll time64 optimization
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-10 19:21   ` Alistair Francis
  2020-09-08 14:57 ` [PATCH v2 03/14] linux: Add time64 semtimedop support Adhemerval Zanella
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

It avoid continuing issue the __NR_ppoll_time64 syscall once the kernel
advertise it does not support it.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/ppoll.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index dd2167fc55..e68a153427 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -22,6 +22,7 @@
 #include <sys/poll.h>
 #include <sysdep-cancel.h>
 #include <kernel-features.h>
+#include <time64-support.h>
 
 
 int
@@ -37,16 +38,23 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
       timeout = &tval;
     }
 
+  int ret;
+
+  if (supports_time64 ())
+    {
 #ifndef __NR_ppoll_time64
 # define __NR_ppoll_time64 __NR_ppoll
 #endif
-  int ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
-                            __NSIG_BYTES);
+      ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
+			    __NSIG_BYTES);
 
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (ret >= 0 || errno != ENOSYS)
-    return ret;
+      if (ret == 0 || errno != ENOSYS)
+	return ret;
 
+      mark_time64_unsupported ();
+    }
+
+#ifndef __ASSUME_TIME64_SYSCALLS
   struct timespec ts32;
   if (timeout)
     {
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 03/14] linux: Add time64 semtimedop support
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
  2020-09-08 14:57 ` [PATCH v2 02/14] linux: Add ppoll time64 optimization Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-10 19:23   ` Alistair Francis
  2020-09-08 14:57 ` [PATCH v2 04/14] linux: Add time64 pselect support Adhemerval Zanella
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

Either the __NR_semtimedop_time64 (for 32-bit) or the __NR_semtimedop
(for 64-bit) syscall is used as default.  The 32-bit fallback is used
iff __ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel
ABI provides either __NR_ipc or __NR_semtimeop (for 32-bit time_t).

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/include/sys/sem.h |  6 +++
 sysdeps/unix/sysv/linux/semtimedop.c      | 57 +++++++++++++++++++----
 2 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/include/sys/sem.h b/sysdeps/unix/sysv/linux/include/sys/sem.h
index a9151e057d..f369c6b6d3 100644
--- a/sysdeps/unix/sysv/linux/include/sys/sem.h
+++ b/sysdeps/unix/sysv/linux/include/sys/sem.h
@@ -7,9 +7,15 @@ __typeof__ (semtimedop) __semtimedop attribute_hidden;
 
 #if __TIMESIZE == 64
 # define __semctl64 __semctl
+# define __semtimedop64 __semtimedop
 #else
+# include <struct___timespec64.h>
+
 extern int __semctl64 (int semid, int semnum, int cmd, ...);
 libc_hidden_proto (__semctl64);
+extern int __semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
+			   const struct __timespec64 *tmo);
+libc_hidden_proto (__semtimedop64);
 #endif
 
 # endif
diff --git a/sysdeps/unix/sysv/linux/semtimedop.c b/sysdeps/unix/sysv/linux/semtimedop.c
index 6fdde09bad..56121fb0bf 100644
--- a/sysdeps/unix/sysv/linux/semtimedop.c
+++ b/sysdeps/unix/sysv/linux/semtimedop.c
@@ -22,18 +22,59 @@
 #include <errno.h>
 
 /* Perform user-defined atomical operation of array of semaphores.  */
+int
+__semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
+		const struct __timespec64 *timeout)
+{
+#if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+# ifndef __NR_semtimedop_time64
+#  define __NR_semtimedop_time64 __NR_semtimedop
+# endif
+  int r = INLINE_SYSCALL_CALL (semtimedop_time64, semid, sops, nsops,
+			       timeout);
+#else
+  int r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
+			       SEMTIMEDOP_IPC_ARGS (nsops, sops, timeout));
+#endif
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r == 0 || errno != ENOSYS)
+    return r;
+
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      ts32 = valid_timespec64_to_timespec (*timeout);
+      pts32 = &ts32;
+    }
+# if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+  r = INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, pts32);
+# else
+  r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
+			   SEMTIMEDOP_IPC_ARGS (nsops, sops, pts32));
+# endif
+#endif /* __ASSUME_TIME64_SYSCALLS  */
+  return r;
+}
+#if __TIMESIZE != 64
+libc_hidden_def (__semtimedop64)
 
 int
 __semtimedop (int semid, struct sembuf *sops, size_t nsops,
 	      const struct timespec *timeout)
 {
-  /* semtimedop wire-up syscall is not exported for 32-bit ABIs (they have
-     semtimedop_time64 instead with uses a 64-bit time_t).  */
-#if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS && defined __NR_semtimedop
-  return INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, timeout);
-#else
-  return INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
-			      SEMTIMEDOP_IPC_ARGS (nsops, sops, timeout));
-#endif
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  return __semtimedop64 (semid, sops, nsops, pts64);
 }
+#endif
 weak_alias (__semtimedop, semtimedop)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 04/14] linux: Add time64 pselect support
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
  2020-09-08 14:57 ` [PATCH v2 02/14] linux: Add ppoll time64 optimization Adhemerval Zanella
  2020-09-08 14:57 ` [PATCH v2 03/14] linux: Add time64 semtimedop support Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-10 19:35   ` Alistair Francis
  2020-09-12  1:22   ` H.J. Lu
  2020-09-08 14:57 ` [PATCH v2 05/14] linux: Add time64 select support Adhemerval Zanella
                   ` (10 subsequent siblings)
  13 siblings, 2 replies; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

Changes from previous version:

  * Move the 32-bit fallback implementation to pselect32.c.  It simplifies
    the required microblaze override.

---

The syscall __NR_pselect6_time64 (32-bit) or __NR_pselect6 (64-bit)
is used as default.  For architectures with __ASSUME_TIME64_SYSCALLS
the 32-bit fallback uses __NR_pselec6.

To accomodate microblaze missing pselect6 support on kernel older
than 3.15 the fallback is moved to its own function to the microblaze
specific implementation can override it.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/sys/select.h                          | 16 ++++++
 sysdeps/unix/sysv/linux/Makefile              |  2 +-
 .../microblaze/{pselect.c => pselect32.c}     | 34 ++++--------
 sysdeps/unix/sysv/linux/pselect.c             | 53 ++++++++++++++-----
 sysdeps/unix/sysv/linux/pselect32.c           | 47 ++++++++++++++++
 5 files changed, 116 insertions(+), 36 deletions(-)
 rename sysdeps/unix/sysv/linux/microblaze/{pselect.c => pselect32.c} (66%)
 create mode 100644 sysdeps/unix/sysv/linux/pselect32.c

diff --git a/include/sys/select.h b/include/sys/select.h
index 07bb49b994..b5ae9af861 100644
--- a/include/sys/select.h
+++ b/include/sys/select.h
@@ -3,6 +3,22 @@
 
 #ifndef _ISOMAC
 /* Now define the internal interfaces.  */
+# if __TIMESIZE == 64
+#  define __pselect64 __pselect
+#else
+# include <struct___timespec64.h>
+extern int __pselect64 (int __nfds, fd_set *__readfds,
+			fd_set *__writefds, fd_set *__exceptfds,
+			const struct __timespec64 *__timeout,
+			const __sigset_t *__sigmask);
+libc_hidden_proto (__pselect64)
+
+extern int __pselect32 (int __nfds, fd_set *__readfds,
+			fd_set *__writefds, fd_set *__exceptfds,
+			const struct __timespec64 *__timeout,
+			const __sigset_t *__sigmask)
+  attribute_hidden;
+#endif
 extern int __pselect (int __nfds, fd_set *__readfds,
 		      fd_set *__writefds, fd_set *__exceptfds,
 		      const struct timespec *__timeout,
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 5079f33655..03cb6e790d 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -61,7 +61,7 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
 		   open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \
 		   timerfd_gettime timerfd_settime prctl \
 		   process_vm_readv process_vm_writev clock_adjtime \
-		   time64-support
+		   time64-support pselect32
 
 CFLAGS-gethostid.c = -fexceptions
 CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
diff --git a/sysdeps/unix/sysv/linux/microblaze/pselect.c b/sysdeps/unix/sysv/linux/microblaze/pselect32.c
similarity index 66%
rename from sysdeps/unix/sysv/linux/microblaze/pselect.c
rename to sysdeps/unix/sysv/linux/microblaze/pselect32.c
index 1dfc3b8fc9..d7cfeaa0e9 100644
--- a/sysdeps/unix/sysv/linux/microblaze/pselect.c
+++ b/sysdeps/unix/sysv/linux/microblaze/pselect32.c
@@ -23,38 +23,27 @@
 #include <sysdep-cancel.h>
 
 #ifndef __ASSUME_PSELECT
-# define __pselect __pselect_syscall
-#endif
-
-/* If pselect is supported, just use the Linux generic implementation.  */
-#include <sysdeps/unix/sysv/linux/pselect.c>
-
-#ifndef __ASSUME_PSELECT
-# undef __pselect
 int
-__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-	   const struct timespec *timeout, const sigset_t *sigmask)
+__pselect32 (int nfds, fd_set *readfds, fd_set *writefds,
+	     fd_set *exceptfds, const struct __timespec64 *timeout,
+	     const sigset_t *sigmask)
 {
-  int ret = __pselect_syscall (nfds, readfds, writefds, exceptfds, timeout,
-			       sigmask);
-  if (ret >= 0 || errno != ENOSYS)
-    return ret;
-
   /* The fallback uses 'select' which shows the race condition regarding
      signal mask set/restore, requires two additional syscalls, and has
      a worse timeout precision (microseconds instead of nanoseconds).  */
 
-  struct timeval tval, *ptval = NULL;
+  struct timeval tv32, *ptv32 = NULL;
   if (timeout != NULL)
     {
-      if (! valid_nanoseconds (timeout->tv_nsec))
+      if (! in_time_t_range (timeout->tv_sec)
+	  || ! valid_nanoseconds (timeout->tv_nsec))
 	{
 	  __set_errno (EINVAL);
 	  return -1;
 	}
 
-      TIMESPEC_TO_TIMEVAL (&tval, timeout);
-      ptval = &tval;
+      tv32 = valid_timespec64_to_timeval (*timeout);
+      ptv32 = &tv32;
     }
 
   sigset_t savemask;
@@ -62,12 +51,11 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
     __sigprocmask (SIG_SETMASK, sigmask, &savemask);
 
   /* select itself is a cancellation entrypoint.  */
-  ret = __select (nfds, readfds, writefds, exceptfds, ptval);
+  int r = __select (nfds, readfds, writefds, exceptfds, ptv32);
 
   if (sigmask != NULL)
     __sigprocmask (SIG_SETMASK, &savemask, NULL);
 
-  return ret;
+  return r;
 }
-weak_alias (__pselect, pselect)
-#endif
+#endif /* __ASSUME_PSELECT  */
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index 304db03338..ed36121023 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -18,14 +18,15 @@
 
 #include <sys/select.h>
 #include <sysdep-cancel.h>
+#include <time64-support.h>
 
 int
-__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-	   const struct timespec *timeout, const sigset_t *sigmask)
+__pselect64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+	     const struct __timespec64 *timeout, const sigset_t *sigmask)
 {
   /* The Linux kernel can in some situations update the timeout value.
      We do not want that so use a local variable.  */
-  struct timespec tval;
+  struct __timespec64 tval;
   if (timeout != NULL)
     {
       tval = *timeout;
@@ -36,18 +37,46 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
      we can only pass in 6 directly.  If there is an architecture with
      support for more parameters a new version of this file needs to
      be created.  */
-  struct
-  {
-    __syscall_ulong_t ss;
-    __syscall_ulong_t ss_len;
-  } data;
 
-  data.ss = (__syscall_ulong_t) (uintptr_t) sigmask;
-  data.ss_len = __NSIG_BYTES;
+#ifndef __NR_pselect6_time64
+# define __NR_pselect6_time64 __NR_pselect6
+#endif
+  int r;
+  if (supports_time64 ())
+    {
+      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
+			  timeout,
+			  ((__syscall_ulong_t[]){ (uintptr_t) sigmask,
+						  __NSIG_BYTES }));
+      if (r == 0 || errno != ENOSYS)
+	return r;
+
+      mark_time64_unsupported ();
+    }
 
-  return SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds,
-                         timeout, &data);
+#ifndef __ASSUME_TIME64_SYSCALLS
+  r = __pselect32 (nfds, readfds, writefds, exceptfds, timeout, sigmask);
+#endif
+  return r;
 }
+
+#if __TIMESIZE != 64
+libc_hidden_def (__pselect64)
+
+int
+__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+	   const struct timespec *timeout, const sigset_t *sigmask)
+{
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  return __pselect64 (nfds, readfds, writefds, exceptfds, pts64, sigmask);
+}
+#endif
+
 #ifndef __pselect
 weak_alias (__pselect, pselect)
 #endif
diff --git a/sysdeps/unix/sysv/linux/pselect32.c b/sysdeps/unix/sysv/linux/pselect32.c
new file mode 100644
index 0000000000..0a2a7ac752
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/pselect32.c
@@ -0,0 +1,47 @@
+/* Synchronous I/O multiplexing.  Linux 32-bit time fallback.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sys/select.h>
+#include <sysdep-cancel.h>
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+
+int
+__pselect32 (int nfds, fd_set *readfds, fd_set *writefds,
+	     fd_set *exceptfds, const struct __timespec64 *timeout,
+	     const sigset_t *sigmask)
+{
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+
+      ts32 = valid_timespec64_to_timespec (*timeout);
+      pts32 = &ts32;
+    }
+
+  return SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds,
+			 pts32,
+			 ((__syscall_ulong_t[]){ (uintptr_t) sigmask,
+						 __NSIG_BYTES }));
+}
+#endif
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 05/14] linux: Add time64 select support
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 04/14] linux: Add time64 pselect support Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-11 20:44   ` Alistair Francis
  2020-09-08 14:57 ` [PATCH v2 06/14] linux: Add time64 sigtimedwait support Adhemerval Zanella
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The syscall __NR_pselect6_time64 (32-bit) or __NR_pselect6 (64-bit)
is used as default.  For architectures with __ASSUME_TIME64_SYSCALLS
the 32-bit fallback uses __NR_select/__NR__newselect or __NR_pselect6
(it should cover the microblaze case where older kernels do not
provide __NR_pselect6).

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/sys/select.h             |  8 +++
 include/time.h                   |  6 +++
 sysdeps/unix/sysv/linux/select.c | 92 ++++++++++++++++++++++++--------
 3 files changed, 83 insertions(+), 23 deletions(-)

diff --git a/include/sys/select.h b/include/sys/select.h
index b5ae9af861..ec073deeba 100644
--- a/include/sys/select.h
+++ b/include/sys/select.h
@@ -5,8 +5,11 @@
 /* Now define the internal interfaces.  */
 # if __TIMESIZE == 64
 #  define __pselect64 __pselect
+#  define __select64  __select
 #else
 # include <struct___timespec64.h>
+# include <struct___timeval64.h>
+
 extern int __pselect64 (int __nfds, fd_set *__readfds,
 			fd_set *__writefds, fd_set *__exceptfds,
 			const struct __timespec64 *__timeout,
@@ -18,6 +21,11 @@ extern int __pselect32 (int __nfds, fd_set *__readfds,
 			const struct __timespec64 *__timeout,
 			const __sigset_t *__sigmask)
   attribute_hidden;
+
+extern int __select64 (int __nfds, fd_set *__readfds,
+		       fd_set *__writefds, fd_set *__exceptfds,
+		       struct __timeval64 *__timeout);
+libc_hidden_proto (__select64)
 #endif
 extern int __pselect (int __nfds, fd_set *__readfds,
 		      fd_set *__writefds, fd_set *__exceptfds,
diff --git a/include/time.h b/include/time.h
index fe4da9ca10..936486e206 100644
--- a/include/time.h
+++ b/include/time.h
@@ -464,6 +464,12 @@ valid_timespec_to_timeval32 (const struct timespec ts)
   return (struct __timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
 }
 
+static inline struct __timeval64
+valid_timespec_to_timeval64 (const struct timespec ts)
+{
+  return (struct __timeval64) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
+}
+
 /* Check if a value is in the valid nanoseconds range. Return true if
    it is, false otherwise.  */
 static inline bool
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index 54c50edba2..bed52fbda2 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -21,6 +21,7 @@
 #include <sys/select.h>
 #include <errno.h>
 #include <sysdep-cancel.h>
+#include <time64-support.h>
 
 /* Check the first NFDS descriptors each in READFDS (if not NULL) for read
    readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
@@ -28,43 +29,88 @@
    after waiting the interval specified therein.  Returns the number of ready
    descriptors, or -1 for errors.  */
 
-#ifdef __NR__newselect
-# undef __NR_select
-# define __NR_select __NR__newselect
-#endif
-
 int
-__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-	  struct timeval *timeout)
+__select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+	    struct __timeval64 *timeout)
 {
-#ifdef __NR_select
-  return SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds,
-			 timeout);
-#else
-  int result;
-  struct timespec ts, *tsp = NULL;
-
-  if (timeout)
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
     {
-      TIMEVAL_TO_TIMESPEC (timeout, &ts);
-      tsp = &ts;
+      ts64 = timeval64_to_timespec64 (*timeout);
+      pts64 = &ts64;
     }
 
-  result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp,
-			   NULL);
-
-  if (timeout)
+#ifndef __NR_pselect6_time64
+# define __NR_pselect6_time64 __NR_pselect6
+#endif
+  int r;
+  if (supports_time64 ())
     {
+      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
+			  pts64, NULL);
       /* Linux by default will update the timeout after a pselect6 syscall
          (though the pselect() glibc call suppresses this behavior).
          Since select() on Linux has the same behavior as the pselect6
          syscall, we update the timeout here.  */
-      TIMESPEC_TO_TIMEVAL (timeout, &ts);
+      if (r == 0 || errno != ENOSYS)
+	{
+	  if (timeout != NULL)
+	    TIMEVAL_TO_TIMESPEC (timeout, &ts64);
+	  return r;
+	}
+
+      mark_time64_unsupported ();
     }
 
-  return result;
+#ifndef __ASSUME_TIME64_SYSCALLS
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      ts32 = valid_timespec64_to_timespec (ts64);
+      pts32 = &ts32;
+    }
+# ifndef __ASSUME_PSELECT
+#  ifdef __NR__newselect
+#   undef __NR_select
+#   define __NR_select __NR__newselect
+#  endif
+  r = SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, pts32);
+# else
+  r = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, pts32,
+		      NULL);
+# endif
+  if (r >= 0 && timeout != NULL)
+    *timeout = valid_timespec_to_timeval64 (ts32);
 #endif
+
+  return r;
 }
+
+#if __TIMESIZE != 64
+libc_hidden_def (__select64)
+
+int
+__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+	  struct timeval *timeout)
+{
+  struct __timeval64 tv64, *ptv64 = NULL;
+  if (timeout != NULL)
+    {
+      tv64 = valid_timeval_to_timeval64 (*timeout);
+      ptv64 = &tv64;
+    }
+  int r = __select64 (nfds, readfds, writefds, exceptfds, ptv64);
+  if (r >= 0 && timeout != NULL)
+    /* The remanining timeout will be always less the input TIMEOUT.  */
+    *timeout = valid_timeval64_to_timeval (tv64);
+  return r;
+}
+#endif
 libc_hidden_def (__select)
 
 weak_alias (__select, select)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 06/14] linux: Add time64 sigtimedwait support
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 05/14] linux: Add time64 select support Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-11 20:56   ` Alistair Francis
  2020-09-08 14:57 ` [PATCH v2 07/14] linux: Use 64-bit time_t syscall on clock_getcputclockid Adhemerval Zanella
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The syscall __NR_sigtimedwait_time64 (for 32-bit) or __NR_sigtimedwait
(for 64-bit) is used as default.  The 32-bit fallback is used iff
__ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel ABI
provides either __NR_rt_sigtimedwait (32-bit time_t).

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 include/signal.h                       |  8 +++++
 sysdeps/unix/sysv/linux/sigtimedwait.c | 50 +++++++++++++++++++++-----
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/include/signal.h b/include/signal.h
index b4ee02d153..544d701bce 100644
--- a/include/signal.h
+++ b/include/signal.h
@@ -38,6 +38,14 @@ extern int __sigwait (const sigset_t *__set, int *__sig);
 libc_hidden_proto (__sigwait)
 extern int __sigwaitinfo (const sigset_t *__set, siginfo_t *__info);
 libc_hidden_proto (__sigwaitinfo)
+#if __TIMESIZE == 64
+# define __sigtimedwait64 __sigtimedwait
+#else
+# include <struct___timespec64.h>
+extern int __sigtimedwait64 (const sigset_t *__set, siginfo_t *__info,
+			     const struct __timespec64 *__timeout);
+libc_hidden_proto (__sigtimedwait64)
+#endif
 extern int __sigtimedwait (const sigset_t *__set, siginfo_t *__info,
 			   const struct timespec *__timeout);
 libc_hidden_proto (__sigtimedwait)
diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
index f2ef3aad45..4405606571 100644
--- a/sysdeps/unix/sysv/linux/sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -15,20 +15,38 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <signal.h>
-#include <string.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 int
-__sigtimedwait (const sigset_t *set, siginfo_t *info,
-		const struct timespec *timeout)
+__sigtimedwait64 (const sigset_t *set, siginfo_t *info,
+		  const struct __timespec64 *timeout)
 {
-  /* XXX The size argument hopefully will have to be changed to the
-     real size of the user-level sigset_t.  */
-  int result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, timeout,
+#ifndef __NR_rt_sigtimedwait_time64
+# define __NR_rt_sigtimedwait_time64 __NR_rt_sigtimedwait
+#endif
+  int result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
 			       __NSIG_BYTES);
 
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (result != 0 && errno == ENOSYS)
+    {
+      struct timespec ts32, *pts32 = NULL;
+      if (timeout != NULL)
+	{
+	  if (! in_time_t_range (timeout->tv_sec))
+	    {
+	      __set_errno (EINVAL);
+	      return -1;
+	    }
+	  ts32 = valid_timespec64_to_timespec (*timeout);
+	  pts32 = &ts32;
+	}
+      result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, pts32,
+			       __NSIG_BYTES);
+    }
+#endif
+
   /* The kernel generates a SI_TKILL code in si_code in case tkill is
      used.  tkill is transparently used in raise().  Since having
      SI_TKILL as a code is useful in general we fold the results
@@ -38,5 +56,21 @@ __sigtimedwait (const sigset_t *set, siginfo_t *info,
 
   return result;
 }
+#if __TIMESIZE != 64
+libc_hidden_def (__sigtimedwait64)
+
+int
+__sigtimedwait (const sigset_t *set, siginfo_t *info,
+		const struct timespec *timeout)
+{
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  return __sigtimedwait64 (set, info, pts64);
+}
+#endif
 libc_hidden_def (__sigtimedwait)
 weak_alias (__sigtimedwait, sigtimedwait)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 07/14] linux: Use 64-bit time_t syscall on clock_getcputclockid
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 06/14] linux: Add time64 sigtimedwait support Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-16 15:26   ` Alistair Francis
  2020-09-08 14:57 ` [PATCH v2 08/14] linux: Consolidate utimes Adhemerval Zanella
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The syscall __NR_clock_getres_time64 (for 32-bit) or __NR_clock_getres
(for 64-bit) is used as default.  The 32-bit fallback is used iff
__ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel ABI
provides either __NR_rt_sigtimedwait (32-bit time_t).

Since the symbol does not use any type which might be affected by the
time_t, there is no need to add a 64-bit variant.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_getcpuclockid.c | 25 +++++++++++--------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
index be1f477187..7d2e6d6bfe 100644
--- a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
+++ b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
@@ -30,20 +30,25 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
 
   const clockid_t pidclock = MAKE_PROCESS_CPUCLOCK (pid, CPUCLOCK_SCHED);
 
-  int r = INTERNAL_SYSCALL_CALL (clock_getres, pidclock, NULL);
-  if (!INTERNAL_SYSCALL_ERROR_P (r))
+#ifndef __NR_clock_getres_time64
+# define __NR_clock_getres_time64 __NR_clock_getres
+#endif
+  int r = INTERNAL_SYSCALL_CALL (clock_getres_time64, pidclock, NULL);
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r != 0 && r == -ENOSYS)
+    r = INTERNAL_SYSCALL_CALL (clock_getres, pidclock, NULL);
+#endif
+
+  if (r == 0)
     {
       *clock_id = pidclock;
       return 0;
     }
-
-  if (INTERNAL_SYSCALL_ERRNO (r) == EINVAL)
-    {
-      /* The clock_getres system call checked the PID for us.  */
-      return ESRCH;
-    }
-  else
-    return INTERNAL_SYSCALL_ERRNO (r);
+  if (r == -EINVAL)
+    /* The clock_getres system call checked the PID for us.  */
+    return ESRCH;
+  return -r;
 }
 
 versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 08/14] linux: Consolidate utimes
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (5 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 07/14] linux: Use 64-bit time_t syscall on clock_getcputclockid Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-16 15:30   ` Alistair Francis
  2020-09-08 14:57 ` [PATCH v2 09/14] linux: Fix time64 support for futimesat Adhemerval Zanella
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The generic version does not have time64 support and Linux default
uses utimensat.  With hppa version gone, __ASSUME_UTIMES is not used
anymore.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/generic/utimes.c      | 46 -------------------
 .../unix/sysv/linux/hppa/kernel-features.h    |  5 --
 sysdeps/unix/sysv/linux/hppa/utimes.c         | 30 ------------
 3 files changed, 81 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/generic/utimes.c
 delete mode 100644 sysdeps/unix/sysv/linux/hppa/utimes.c

diff --git a/sysdeps/unix/sysv/linux/generic/utimes.c b/sysdeps/unix/sysv/linux/generic/utimes.c
deleted file mode 100644
index 0a8100e1b8..0000000000
--- a/sysdeps/unix/sysv/linux/generic/utimes.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* utimes -- Change access and modification times of file.  Linux version.
-   Copyright (C) 2011-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <stddef.h>
-#include <utime.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sysdep.h>
-
-
-/* Change the access time of FILE to TVP[0] and
-   the modification time of FILE to TVP[1].  */
-int
-__utimes (const char *file, const struct timeval tvp[2])
-{
-  struct timespec ts[2];
-  struct timespec *tsp = NULL;
-
-  if (tvp)
-    {
-      TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]);
-      TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]);
-      tsp = &ts[0];
-    }
-
-  return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, tsp, 0);
-}
-
-weak_alias (__utimes, utimes)
diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
index 8548b5c258..80eec02314 100644
--- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
@@ -18,11 +18,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 
-/* Support for the utimes syscall was added in 3.14.  */
-#if __LINUX_KERNEL_VERSION >= 0x030e00
-# define __ASSUME_UTIMES		1
-#endif
-
 #include_next <kernel-features.h>
 
 #define __ASSUME_RECV_SYSCALL   1
diff --git a/sysdeps/unix/sysv/linux/hppa/utimes.c b/sysdeps/unix/sysv/linux/hppa/utimes.c
deleted file mode 100644
index a9c4a7ff45..0000000000
--- a/sysdeps/unix/sysv/linux/hppa/utimes.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Implement utimes for hppa.
-   Copyright (C) 2014-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-/* hppa has the utimensat syscall in all supported kernel versions but
-   gained the utimes syscall later, so use the linux-generic
-   implementation of utimes in terms of the utimensat syscall unless
-   the utimes syscall is known to be available.  */
-
-#include <kernel-features.h>
-
-#ifdef __ASSUME_UTIMES
-# include <sysdeps/unix/sysv/linux/utimes.c>
-#else
-# include <sysdeps/unix/sysv/linux/generic/utimes.c>
-#endif
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 09/14] linux: Fix time64 support for futimesat
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (6 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 08/14] linux: Consolidate utimes Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-08 14:57 ` [PATCH v2 10/14] linux: Add time64 support for nanosleep Adhemerval Zanella
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The generic implementation does not support time64 and the default
one return overflow for invalid tv_sec with UTIME_NOW / UTIME_OMIT
(which is valid since tv_sec in such cases is ignored by the
kernel).

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/generic/futimesat.c | 52 ---------------------
 sysdeps/unix/sysv/linux/utimensat.c         |  8 +++-
 2 files changed, 6 insertions(+), 54 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/generic/futimesat.c

diff --git a/sysdeps/unix/sysv/linux/generic/futimesat.c b/sysdeps/unix/sysv/linux/generic/futimesat.c
deleted file mode 100644
index 7be1fbc252..0000000000
--- a/sysdeps/unix/sysv/linux/generic/futimesat.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* futimesat -- Change access and modification times of file.  Linux version.
-   Copyright (C) 2005-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <utime.h>
-#include <sys/time.h>
-#include <sysdep.h>
-
-
-/* Change the access time of FILE relative to FD to TVP[0] and
-   the modification time of FILE to TVP[1].  */
-int
-futimesat (int fd, const char *file, const struct timeval tvp[2])
-{
-  struct timespec tsp[2];
-  int result;
-
-  if (tvp)
-    {
-      if (tvp[0].tv_usec >= 1000000 || tvp[0].tv_usec < 0
-          || tvp[1].tv_usec >= 1000000 || tvp[1].tv_usec < 0)
-        {
-          __set_errno (EINVAL);
-          return -1;
-        }
-      TIMEVAL_TO_TIMESPEC (&tvp[0], &tsp[0]);
-      TIMEVAL_TO_TIMESPEC (&tvp[1], &tsp[1]);
-    }
-
-  result = INLINE_SYSCALL (utimensat, 4, fd, file, tvp ? tsp : NULL, 0);
-  return result;
-}
diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index ea23c2f051..72784d824a 100644
--- a/sysdeps/unix/sysv/linux/utimensat.c
+++ b/sysdeps/unix/sysv/linux/utimensat.c
@@ -36,9 +36,13 @@ __utimensat64_helper (int fd, const char *file,
   if (ret == 0 || errno != ENOSYS)
     return ret;
 
+  /* For UTIME_NOW and UTIME_OMIT the value of tv_sec field is ignored.  */
+# define NS_VALID(ns) \
+  ((((ns).tv_nsec == UTIME_NOW || (ns).tv_nsec == UTIME_OMIT) \
+   || in_time_t_range ((ns).tv_sec)))
+
   if (tsp64 != NULL
-      && (! in_time_t_range (tsp64[0].tv_sec)
-          || ! in_time_t_range (tsp64[1].tv_sec)))
+      && (!NS_VALID (tsp64[0]) || !NS_VALID (tsp64[1])))
     {
       __set_errno (EOVERFLOW);
       return -1;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 10/14] linux: Add time64 support for nanosleep
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (7 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 09/14] linux: Fix time64 support for futimesat Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-16 17:16   ` Alistair Francis
  2020-09-08 14:57 ` [PATCH v2 11/14] linux: Add time64 recvmmsg support Adhemerval Zanella
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

It uses __clock_nanosleep64 and adds the __nanosleep64 symbol.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/time.h                      |  9 ++++++
 sysdeps/unix/sysv/linux/nanosleep.c | 50 +++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/nanosleep.c

diff --git a/include/time.h b/include/time.h
index 936486e206..edf6cdf829 100644
--- a/include/time.h
+++ b/include/time.h
@@ -271,6 +271,15 @@ extern struct tm *__tz_convert (__time64_t timer, int use_localtime,
 extern int __nanosleep (const struct timespec *__requested_time,
 			struct timespec *__remaining);
 hidden_proto (__nanosleep)
+#if __TIMESIZE == 64
+# define __nanosleep64 __nanosleep
+#else
+extern int __nanosleep64 (const struct __timespec64 *__requested_time,
+			  struct __timespec64 *__remaining);
+hidden_proto (__nanosleep64)
+#endif
+
+
 extern int __getdate_r (const char *__string, struct tm *__resbufp)
   attribute_hidden;
 
diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c
new file mode 100644
index 0000000000..8f4ee0f744
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/nanosleep.c
@@ -0,0 +1,50 @@
+/* High-resolution sleep.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <time.h>
+#include <errno.h>
+
+int
+__nanosleep64 (const struct __timespec64 *req, struct __timespec64 *rem)
+{
+  int ret = __clock_nanosleep_time64 (CLOCK_REALTIME, 0, req, rem);
+  if (ret != 0)
+    {
+      __set_errno (ret);
+      return -1;
+    }
+  return 0;
+}
+#if __TIMESIZE != 64
+libc_hidden_def (__nanosleep64)
+
+int
+__nanosleep (const struct timespec *req, struct timespec *rem)
+{
+  struct __timespec64 treq64, trem64;
+
+  treq64 = valid_timespec_to_timespec64 (*req);
+  int ret = __nanosleep64 (&treq64, &trem64);
+
+  if (ret != 0 && errno == EINTR && rem != NULL)
+    *rem = valid_timespec64_to_timespec (trem64);
+  return ret;
+}
+#endif
+libc_hidden_def (__nanosleep)
+weak_alias (__nanosleep, nanosleep)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 11/14] linux: Add time64 recvmmsg support
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (8 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 10/14] linux: Add time64 support for nanosleep Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-25 21:18   ` Alistair Francis
  2020-09-08 14:57 ` [RFC 12/14] linux: Add fallback for 64-bit time_t SO_{RCV,SND}TIMEO Adhemerval Zanella
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The wire-up syscall __NR_recvmmsg_time64 (for 32-bit) or
__NR_recvmmsg (for 64-bit) is used as default.  The 32-bit fallback
is used iff __ASSUME_TIME64_SYSCALLS is not defined, which assumes the
kernel ABI provides either __NR_socketcall or __NR_recvmmsg
(32-bit time_t).

It does not handle the timestamps on ancillary data (SCM_TIMESTAMPING
records).

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 include/sys/socket.h               |  8 ++++
 sysdeps/unix/sysv/linux/recvmmsg.c | 63 ++++++++++++++++++++++++------
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/include/sys/socket.h b/include/sys/socket.h
index 26db0e0d77..0e39dd2a3a 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -104,6 +104,14 @@ extern ssize_t __libc_recvmsg (int __fd, struct msghdr *__message,
 			       int __flags);
 extern ssize_t __recvmsg (int __fd, struct msghdr *__message,
 			  int __flags) attribute_hidden;
+#if __TIMESIZE == 64
+# define __recvmmsg64 __recvmmsg
+#else
+extern int __recvmmsg64 (int __fd, struct mmsghdr *vmessages,
+			 unsigned int vlen, int flags,
+			 struct __timespec64 *timeout);
+libc_hidden_proto (__recvmmsg64)
+#endif
 
 /* Set socket FD's option OPTNAME at protocol level LEVEL
    to *OPTVAL (which is OPTLEN bytes long).
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
index 42c80c59c3..a29c91fb76 100644
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
@@ -16,21 +16,62 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <sys/socket.h>
-
-#include <sysdep-cancel.h>
-#include <sys/syscall.h>
+#include <sysdep.h>
 #include <socketcall.h>
-#include <kernel-features.h>
 
 int
-recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
-	  struct timespec *tmo)
+__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
+	      struct __timespec64 *timeout)
 {
-#ifdef __ASSUME_RECVMMSG_SYSCALL
-  return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
-#else
-  return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
+#ifndef __NR_recvmmsg_time64
+# define __NR_recvmmsg_time64 __NR_recvmmsg
 #endif
+  int r = SYSCALL_CANCEL (recvmmsg_time64, fd, vmessages, vlen, flags,
+			  timeout);
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r >= 0 || errno != ENOSYS)
+    return r;
+
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      ts32 = valid_timespec64_to_timespec (*timeout);
+      pts32 = &ts32;
+    }
+# ifdef __ASSUME_RECVMMSG_SYSCALL
+  r = SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
+# else
+  r = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
+# endif
+  if (r >= 0 && timeout != NULL)
+    *timeout = valid_timespec_to_timespec64 (ts32);
+#endif /* __ASSUME_TIME64_SYSCALLS  */
+  return r;
 }
+#if __TIMESIZE != 64
+libc_hidden_def (__recvmmsg64)
+
+int
+__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
+	    struct timespec *timeout)
+{
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  int r = __recvmmsg64 (fd, vmessages, vlen, flags, pts64);
+  if (r >= 0)
+    /* The remanining timeout will be always less the input TIMEOUT.  */
+    *timeout = valid_timespec64_to_timespec (ts64);
+  return r;
+}
+#endif
+weak_alias (__recvmmsg, recvmmsg)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 12/14] linux: Add fallback for 64-bit time_t SO_{RCV,SND}TIMEO
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (9 preceding siblings ...)
  2020-09-08 14:57 ` [PATCH v2 11/14] linux: Add time64 recvmmsg support Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-08 14:57 ` [RFC 13/14] linux: Add fallback for 64-bit time_t SO_TIMESTAMP{NS} Adhemerval Zanella
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The constant value will be changed for __TIMESIZE=64, so binaries built
with 64-bit time support might fail to work properly on old kernels.
Both {get,set}sockopt will retry the syscall with the old constant
values and the timeout value adjusted when kernel returns ENOTPROTOPT.

It also changes to SO_{RCV,SND}TIMEO to follow the uapi kernel values
where SO_{RCV,SND}TIMEO_OLD indicates pre 64-bit time support and
SO_{RCV,SND}TIMEO_NEW indicate time64 support.  It allows to refer to
constant independently of the time_t abi used (since kernel defines
SO_{RCV,SND}TIMEO depending of the time_t size).

The hppa, mips, powerpc, and sparc provides its own socket-constant.h,
which are also updated the the SO_{RCV,SND}TIMEO constants (they are
missed on 019d828669df966 patch).

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 .../unix/sysv/linux/bits/socket-constants.h   | 19 ++---
 sysdeps/unix/sysv/linux/getsockopt.c          | 72 ++++++++++++++++--
 .../sysv/linux/hppa/bits/socket-constants.h   | 15 +++-
 .../sysv/linux/mips/bits/socket-constants.h   | 17 ++++-
 .../linux/powerpc/bits/socket-constants.h     | 19 ++++-
 sysdeps/unix/sysv/linux/setsockopt.c          | 76 +++++++++++++++++--
 .../sysv/linux/sparc/bits/socket-constants.h  | 17 ++++-
 7 files changed, 202 insertions(+), 33 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/bits/socket-constants.h b/sysdeps/unix/sysv/linux/bits/socket-constants.h
index d02e1cbc7c..c7478651fb 100644
--- a/sysdeps/unix/sysv/linux/bits/socket-constants.h
+++ b/sysdeps/unix/sysv/linux/bits/socket-constants.h
@@ -32,19 +32,20 @@
 #define SO_OOBINLINE 10
 #define SO_RCVBUF 8
 #define SO_RCVLOWAT 18
-#if (__TIMESIZE == 64 && __WORDSIZE == 32 \
-     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
-# define SO_RCVTIMEO 66
-#else
-# define SO_RCVTIMEO 20
-#endif
 #define SO_REUSEADDR 2
 #define SO_SNDBUF 7
 #define SO_SNDLOWAT 19
+#define SO_TYPE 3
+
+#define SO_RCVTIMEO_OLD 20
+#define SO_SNDTIMEO_OLD 21
+#define SO_RCVTIMEO_NEW 66
+#define SO_SNDTIMEO_NEW 67
 #if (__TIMESIZE == 64 && __WORDSIZE == 32 \
      && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
-# define SO_SNDTIMEO 67
+# define SO_RCVTIMEO SO_RCVTIMEO_NEW
+# define SO_SNDTIMEO SO_SNDTIMEO_NEW
 #else
-# define SO_SNDTIMEO 21
+# define SO_RCVTIMEO SO_RCVTIMEO_OLD
+# define SO_SNDTIMEO SO_SNDTIMEO_OLD
 #endif
-#define SO_TYPE 3
diff --git a/sysdeps/unix/sysv/linux/getsockopt.c b/sysdeps/unix/sysv/linux/getsockopt.c
index 11939660c1..5dce0e29ee 100644
--- a/sysdeps/unix/sysv/linux/getsockopt.c
+++ b/sysdeps/unix/sysv/linux/getsockopt.c
@@ -15,16 +15,20 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <signal.h>
 #include <sys/socket.h>
-
+/* The kernel header with SO_* constants is used as default for _GNU_SOURCE,
+   however the new constants that describe 64-bit time support were added
+   only on v5.1.  */
+#if !defined(SO_RCVTIMEO_NEW) || !defined(SO_RCVTIMEO_OLD)
+# include <bits/socket-constants.h>
+#endif
+#include <time.h>
+#include <sysdep.h>
 #include <socketcall.h>
-#include <kernel-features.h>
-#include <sys/syscall.h>
 
-int
-__getsockopt (int fd, int level, int optname, void *optval, socklen_t *len)
+static int
+getsockopt_syscall (int fd, int level, int optname, void *optval,
+		    socklen_t *len)
 {
 #ifdef __ASSUME_GETSOCKOPT_SYSCALL
   return INLINE_SYSCALL (getsockopt, 5, fd, level, optname, optval, len);
@@ -32,4 +36,58 @@ __getsockopt (int fd, int level, int optname, void *optval, socklen_t *len)
   return SOCKETCALL (getsockopt, fd, level, optname, optval, len);
 #endif
 }
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+static int
+getsockopt32 (int fd, int level, int optname, void *optval,
+	      socklen_t *len)
+{
+  int r = -1;
+
+  if (level != SOL_SOCKET)
+    return r;
+
+  switch (optname)
+    {
+    case SO_RCVTIMEO_NEW:
+    case SO_SNDTIMEO_NEW:
+      {
+        if (*len < sizeof (struct __timeval64))
+	  {
+	    __set_errno (EINVAL);
+	    break;
+	  }
+
+	if (optname == SO_RCVTIMEO_NEW)
+	  optname = SO_RCVTIMEO_OLD;
+	if (optname == SO_SNDTIMEO_NEW)
+	  optname = SO_SNDTIMEO_OLD;
+
+	struct __timeval32 tv32;
+	r = getsockopt_syscall (fd, level, optname, &tv32,
+				(socklen_t[]) { sizeof tv32 });
+	if (r < 0)
+	  break;
+	struct __timeval64 *tv64 = (struct __timeval64 *) optval;
+	*tv64 = valid_timeval32_to_timeval64 (tv32);
+	*len = sizeof (*tv64);
+      }
+    }
+
+  return r;
+}
+#endif
+
+int
+__getsockopt (int fd, int level, int optname, void *optval, socklen_t *len)
+{
+  int r = getsockopt_syscall (fd, level, optname, optval, len);
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r == -1 && errno == ENOPROTOOPT)
+    r = getsockopt32 (fd, level, optname, optval, len);
+#endif
+
+ return r;
+}
 weak_alias (__getsockopt, getsockopt)
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
index fda7f95d44..eca5fe045c 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
@@ -30,9 +30,20 @@
 #define SO_OOBINLINE 256
 #define SO_RCVBUF 4098
 #define SO_RCVLOWAT 4100
-#define SO_RCVTIMEO 4102
 #define SO_REUSEADDR 4
 #define SO_SNDBUF 4097
 #define SO_SNDLOWAT 4099
-#define SO_SNDTIMEO 4101
 #define SO_TYPE 4104
+
+#define SO_RCVTIMEO_OLD 4102
+#define SO_SNDTIMEO_OLD 4101
+#define SO_RCVTIMEO_NEW 16448
+#define SO_SNDTIMEO_NEW 16449
+#if (__TIMESIZE == 64 && __WORDSIZE == 32 \
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+# define SO_RCVTIMEO SO_RCVTIMEO_NEW
+# define SO_SNDTIMEO SO_SNDTIMEO_NEW
+#else
+# define SO_RCVTIMEO SO_RCVTIMEO_OLD
+# define SO_SNDTIMEO SO_SNDTIMEO_OLD
+#endif
diff --git a/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
index daa47c6c7c..961fad21b8 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
@@ -20,6 +20,8 @@
 # error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
 #endif
 
+#include <bits/timesize.h>
+
 #define SOL_SOCKET 65535
 #define SO_ACCEPTCONN 4105
 #define SO_BROADCAST 32
@@ -30,9 +32,20 @@
 #define SO_OOBINLINE 256
 #define SO_RCVBUF 4098
 #define SO_RCVLOWAT 4100
-#define SO_RCVTIMEO 4102
 #define SO_REUSEADDR 4
 #define SO_SNDBUF 4097
 #define SO_SNDLOWAT 4099
-#define SO_SNDTIMEO 4101
 #define SO_TYPE 4104
+
+#define SO_RCVTIMEO_OLD 4100
+#define SO_SNDTIMEO_OLD 4101
+#define SO_RCVTIMEO_NEW 66
+#define SO_SNDTIMEO_NEW 67
+#if (__TIMESIZE == 64 && __WORDSIZE == 32 \
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+# define SO_RCVTIMEO SO_RCVTIMEO_NEW
+# define SO_SNDTIMEO SO_SNDTIMEO_NEW
+#else
+# define SO_RCVTIMEO SO_RCVTIMEO_OLD
+# define SO_SNDTIMEO SO_SNDTIMEO_OLD
+#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
index 77fc8b207e..d0ec3cb4fc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
@@ -20,6 +20,8 @@
 # error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
 #endif
 
+#include <bits/timesize.h>
+
 #define SOL_SOCKET 1
 #define SO_ACCEPTCONN 30
 #define SO_BROADCAST 6
@@ -30,9 +32,20 @@
 #define SO_OOBINLINE 10
 #define SO_RCVBUF 8
 #define SO_RCVLOWAT 16
-#define SO_RCVTIMEO 18
 #define SO_REUSEADDR 2
 #define SO_SNDBUF 7
-#define SO_SNDLOWAT 17
-#define SO_SNDTIMEO 19
+#define SO_SNDTIMEO 67
 #define SO_TYPE 3
+
+#define SO_RCVTIMEO_OLD 18
+#define SO_SNDTIMEO_OLD 19
+#define SO_RCVTIMEO_NEW 66
+#define SO_SNDTIMEO_NEW 67
+#if (__TIMESIZE == 64 && __WORDSIZE == 32 \
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+# define SO_RCVTIMEO SO_RCVTIMEO_NEW
+# define SO_SNDTIMEO SO_SNDTIMEO_NEW
+#else
+# define SO_RCVTIMEO SO_RCVTIMEO_OLD
+# define SO_SNDTIMEO SO_SNDTIMEO_OLD
+#endif
diff --git a/sysdeps/unix/sysv/linux/setsockopt.c b/sysdeps/unix/sysv/linux/setsockopt.c
index 20c0868783..ebc32d788c 100644
--- a/sysdeps/unix/sysv/linux/setsockopt.c
+++ b/sysdeps/unix/sysv/linux/setsockopt.c
@@ -15,21 +15,81 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <signal.h>
 #include <sys/socket.h>
-
+/* The kernel header with SO_* constants is used as default for _GNU_SOURCE,
+   however the new constants that describe 64-bit time support were added
+   only on v5.1.  */
+#if !defined(SO_RCVTIMEO_NEW) || !defined(SO_RCVTIMEO_OLD)
+# include <bits/socket-constants.h>
+#endif
+#include <time.h>
+#include <sysdep.h>
 #include <socketcall.h>
-#include <kernel-features.h>
-#include <sys/syscall.h>
 
-int
-setsockopt (int fd, int level, int optname, const void *optval, socklen_t len)
+static int
+setsockopt_syscall (int fd, int level, int optname, const void *optval,
+		    socklen_t len)
 {
 #ifdef __ASSUME_SETSOCKOPT_SYSCALL
-  return INLINE_SYSCALL (setsockopt, 5, fd, level, optname, optval, len);
+  return INLINE_SYSCALL_CALL (setsockopt, fd, level, optname, optval, len);
 #else
   return SOCKETCALL (setsockopt, fd, level, optname, optval, len);
 #endif
 }
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+static int
+setsockopt32 (int fd, int level, int optname, const void *optval,
+	      socklen_t len)
+{
+  int r = -1;
+
+  if (level != SOL_SOCKET)
+    return r;
+
+  switch (optname)
+    {
+    case SO_RCVTIMEO_NEW:
+    case SO_SNDTIMEO_NEW:
+      {
+        if (len < sizeof (struct __timeval64))
+	  {
+	    __set_errno (EINVAL);
+	    break;
+	  }
+
+	struct __timeval64 *tv64 = (struct __timeval64 *) optval;
+	if (! in_time_t_range (tv64->tv_sec))
+	  {
+	    __set_errno (EOVERFLOW);
+	    break;
+	  }
+
+	if (optname == SO_RCVTIMEO_NEW)
+	  optname = SO_RCVTIMEO_OLD;
+	if (optname == SO_SNDTIMEO_NEW)
+	  optname = SO_SNDTIMEO_OLD;
+
+	struct __timeval32 tv32 = valid_timeval64_to_timeval32 (*tv64);
+
+	r = setsockopt_syscall (fd, level, optname, &tv32, sizeof (tv32));
+      }
+    }
+
+  return r;
+}
+#endif
+
+int
+setsockopt (int fd, int level, int optname, const void *optval, socklen_t len)
+{
+  int r = setsockopt_syscall (fd, level, optname, optval, len);
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r == -1 && errno == ENOPROTOOPT)
+    r = setsockopt32 (fd, level, optname, optval, len);
+#endif
+
+  return r;
+}
 weak_alias (setsockopt, __setsockopt)
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
index 6ef575e521..d4bf8f79d6 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
@@ -20,6 +20,8 @@
 # error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
 #endif
 
+#include <bits/timesize.h>
+
 #define SOL_SOCKET 65535
 #define SO_ACCEPTCONN 32768
 #define SO_BROADCAST 32
@@ -30,9 +32,20 @@
 #define SO_OOBINLINE 256
 #define SO_RCVBUF 4098
 #define SO_RCVLOWAT 2048
-#define SO_RCVTIMEO 8192
 #define SO_REUSEADDR 4
 #define SO_SNDBUF 4097
 #define SO_SNDLOWAT 4096
-#define SO_SNDTIMEO 16384
 #define SO_TYPE 4104
+
+#define SO_RCVTIMEO_OLD 8192
+#define SO_SNDTIMEO_OLD 16384
+#define SO_RCVTIMEO_NEW 68
+#define SO_SNDTIMEO_NEW 69
+#if (__TIMESIZE == 64 && __WORDSIZE == 32 \
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+# define SO_RCVTIMEO SO_RCVTIMEO_NEW
+# define SO_SNDTIMEO SO_SNDTIMEO_NEW
+#else
+# define SO_RCVTIMEO SO_RCVTIMEO_OLD
+# define SO_SNDTIMEO SO_SNDTIMEO_OLD
+#endif
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 13/14] linux: Add fallback for 64-bit time_t SO_TIMESTAMP{NS}
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (10 preceding siblings ...)
  2020-09-08 14:57 ` [RFC 12/14] linux: Add fallback for 64-bit time_t SO_{RCV,SND}TIMEO Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-08 14:57 ` [RFC 14/14] linux: Add recvvmsg " Adhemerval Zanella
  2020-09-10 19:20 ` [PATCH v2 01/14] linux: Simplify clock_getres Alistair Francis
  13 siblings, 0 replies; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

The constant value will be changed for __TIMESIZE=64, so binaries built
with 64-bit time support might fail to work properly on old kernels.
Both {get,set}sockopt will retry the syscall with the old constant
values and the timeout value adjusted when kernel returns ENOTPROTOPT.

The recvmsg handling is more complicated because it requires check the
returned kernel control message and make some convertions.  For
!__ASSUME_TIME64_SYSCALLS it converts the first 32-bit time SO_TIMESTAMP
or SO_TIMESTAMPNS and appends it to the control buffer if has extra
space or returns MSG_CTRUNC otherwise.  The 32-bit time field is kept
as-is.

Calls with __TIMESIZE=32 will see the converted 64-bit time control
messages as spurious control message of unknown type.  Calls with
__TIMESIZE=64 running on pre-time64 kernels will see the original
message as a spurious control ones of unknown typ while running on
kernel with native 64-bit time support will only see the time64 version
of the control message.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/sys/socket.h                 |  9 +++
 sysdeps/unix/sysv/linux/getsockopt.c | 12 ++++
 sysdeps/unix/sysv/linux/recvmsg.c    | 93 ++++++++++++++++++++++++++--
 sysdeps/unix/sysv/linux/setsockopt.c | 12 ++++
 4 files changed, 121 insertions(+), 5 deletions(-)

diff --git a/include/sys/socket.h b/include/sys/socket.h
index 0e39dd2a3a..c551c8fa87 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -162,6 +162,15 @@ libc_hidden_proto (__libc_sa_len)
 # define SA_LEN(_x)      __libc_sa_len((_x)->sa_family)
 #endif
 
+/* Used on y2038 emulation on 64-bit time_t binaries running on older
+   kernel without 64-bit time_t support.  */
+#define SCM_TIMESTAMP_OLD     SO_TIMESTAMP_OLD
+#define SCM_TIMESTAMPNS_OLD   SO_TIMESTAMPNS_OLD
+#define SCM_TIMESTAMPING_OLD  SO_TIMESTAMPING_OLD
+#define SCM_TIMESTAMP_NEW     SO_TIMESTAMP_NEW
+#define SCM_TIMESTAMPNS_NEW   SO_TIMESTAMPNS_NEW
+#define SCM_TIMESTAMPING_NEW  SO_TIMESTAMPING_NEW
+
 libc_hidden_proto (__cmsg_nxthdr)
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/getsockopt.c b/sysdeps/unix/sysv/linux/getsockopt.c
index 5dce0e29ee..0089a177b6 100644
--- a/sysdeps/unix/sysv/linux/getsockopt.c
+++ b/sysdeps/unix/sysv/linux/getsockopt.c
@@ -72,6 +72,18 @@ getsockopt32 (int fd, int level, int optname, void *optval,
 	*tv64 = valid_timeval32_to_timeval64 (tv32);
 	*len = sizeof (*tv64);
       }
+      break;
+
+    case SO_TIMESTAMP_NEW:
+    case SO_TIMESTAMPNS_NEW:
+      {
+	if (optname == SO_TIMESTAMP_NEW)
+	  optname = SO_TIMESTAMP_OLD;
+	if (optname == SO_TIMESTAMPNS_NEW)
+	  optname = SO_TIMESTAMPNS_OLD;
+	r = getsockopt_syscall (fd, level, optname, optval, len);
+      }
+      break;
     }
 
   return r;
diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c
index a86d502922..c6d1d10b05 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmsg.c
@@ -21,14 +21,97 @@
 #include <socketcall.h>
 #include <shlib-compat.h>
 
+#ifndef __ASSUME_TIME64_SYSCALLS
+/* It converts the first SO_TIMESTAMP or SO_TIMESTAMPNS with 32-bit time and
+   appends it to the control buffer.  The 32-bit time field is kept as-is.
+
+   Calls with __TIMESIZE=32 will see the converted 64-bit time control
+   messages as spurious control message of unknown type.
+
+   Calls with __TIMESIZE=64 running on pre-time64 kernels will see the
+   original message as a spurious control ones of unknown typ while running
+   on kernel with native 64-bit time support will only see the time64 version
+   of the control message.  */
+static void
+convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
+{
+  if (msg->msg_control == NULL || msg->msg_controllen == 0)
+    return;
+
+  /* The returnted control message format for SO_TIMESTAMP_NEW is a
+     'struct __kernel_sock_timeval' while for SO_TIMESTAMPNS_NEW is a
+     'struct __kernel_timespec'.  In both case it is essentially two
+     uint64_t members.  */
+  uint64_t tvts[2];
+
+  struct cmsghdr *cmsg, *last = NULL;
+  int type = 0;
+
+  for (cmsg = CMSG_FIRSTHDR (msg);
+       cmsg != NULL;
+       cmsg = CMSG_NXTHDR (msg, cmsg))
+    {
+      if (cmsg->cmsg_level != SOL_SOCKET)
+	continue;
+
+      switch (cmsg->cmsg_type)
+	{
+	case SCM_TIMESTAMP_OLD:
+	  if (type != 0)
+	    break;
+	  type = SCM_TIMESTAMP_NEW;
+	  goto common;
+
+	case SCM_TIMESTAMPNS_OLD:
+	  type = SCM_TIMESTAMPNS_NEW;
+
+	/* fallthrough  */
+	common:
+	  memcpy (tvts, CMSG_DATA (cmsg), sizeof (tvts));
+	  break;
+	}
+
+      last = cmsg;
+    }
+
+  if (last == NULL || type == 0)
+    return;
+
+  if (CMSG_SPACE (sizeof tvts) > msgsize - msg->msg_controllen)
+    {
+      msg->msg_flags |= MSG_CTRUNC;
+      return;
+    }
+
+  msg->msg_controllen += CMSG_SPACE (sizeof tvts);
+  cmsg = CMSG_NXTHDR(msg, last);
+  cmsg->cmsg_level = SOL_SOCKET;
+  cmsg->cmsg_type = type;
+  cmsg->cmsg_len = CMSG_LEN (sizeof tvts);
+  memcpy (CMSG_DATA (cmsg), tvts, sizeof tvts);
+}
+#endif
+
 ssize_t
 __libc_recvmsg (int fd, struct msghdr *msg, int flags)
 {
-# ifdef __ASSUME_RECVMSG_SYSCALL
-  return SYSCALL_CANCEL (recvmsg, fd, msg, flags);
-# else
-  return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
-# endif
+  ssize_t r;
+#ifndef __ASSUME_TIME64_SYSCALLS
+  socklen_t orig_controllen = msg->msg_controllen;
+#endif
+
+#ifdef __ASSUME_RECVMSG_SYSCALL
+  r = SYSCALL_CANCEL (recvmsg, fd, msg, flags);
+#else
+  r = SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
+#endif
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r >= 0)
+    convert_scm_timestamps (msg, orig_controllen);
+#endif
+
+  return r;
 }
 weak_alias (__libc_recvmsg, recvmsg)
 weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/sysdeps/unix/sysv/linux/setsockopt.c b/sysdeps/unix/sysv/linux/setsockopt.c
index ebc32d788c..6aabe8bbde 100644
--- a/sysdeps/unix/sysv/linux/setsockopt.c
+++ b/sysdeps/unix/sysv/linux/setsockopt.c
@@ -74,6 +74,18 @@ setsockopt32 (int fd, int level, int optname, const void *optval,
 
 	r = setsockopt_syscall (fd, level, optname, &tv32, sizeof (tv32));
       }
+      break;
+
+    case SO_TIMESTAMP_NEW:
+    case SO_TIMESTAMPNS_NEW:
+      {
+	if (optname == SO_TIMESTAMP_NEW)
+	  optname = SO_TIMESTAMP_OLD;
+	if (optname == SO_TIMESTAMPNS_NEW)
+	  optname = SO_TIMESTAMPNS_OLD;
+	r = setsockopt_syscall (fd, level, optname, NULL, 0);
+      }
+      break;
     }
 
   return r;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 14/14] linux: Add recvvmsg fallback for 64-bit time_t SO_TIMESTAMP{NS}
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (11 preceding siblings ...)
  2020-09-08 14:57 ` [RFC 13/14] linux: Add fallback for 64-bit time_t SO_TIMESTAMP{NS} Adhemerval Zanella
@ 2020-09-08 14:57 ` Adhemerval Zanella
  2020-09-10 19:20 ` [PATCH v2 01/14] linux: Simplify clock_getres Alistair Francis
  13 siblings, 0 replies; 25+ messages in thread
From: Adhemerval Zanella @ 2020-09-08 14:57 UTC (permalink / raw)
  To: libc-alpha

Handle the SO_TIMESTAMP{NS} similar to recvmsg: for
!__ASSUME_TIME64_SYSCALLS it converts the first 32-bit time SO_TIMESTAMP
or SO_TIMESTAMPNS and appends it to the control buffer if has extra
space or returns MSG_CTRUNC otherwise.  The 32-bit time field is kept
as-is.

Also for !__ASSUME_TIME64_SYSCALLS it limits the maximum number of
'struct mmsghdr *' to IOV_MAX (and also increases the stack size
requirement to IOV_MAX times sizeof (socklen_t)).  The Linux imposes
a similar limit to sendmmsg, so bound the array size on recvmmsg is not
unreasonable.  And this will be used only on older when building with
32-bit time support.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/sys/socket.h               |  3 +++
 sysdeps/unix/sysv/linux/recvmmsg.c | 17 +++++++++++++++--
 sysdeps/unix/sysv/linux/recvmsg.c  |  6 +++---
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/include/sys/socket.h b/include/sys/socket.h
index c551c8fa87..171440ab14 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -171,6 +171,9 @@ libc_hidden_proto (__libc_sa_len)
 #define SCM_TIMESTAMPNS_NEW   SO_TIMESTAMPNS_NEW
 #define SCM_TIMESTAMPING_NEW  SO_TIMESTAMPING_NEW
 
+extern void __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
+  attribute_hidden;
+
 libc_hidden_proto (__cmsg_nxthdr)
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
index a29c91fb76..0f67e2dcac 100644
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
@@ -44,13 +44,26 @@ __recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
       ts32 = valid_timespec64_to_timespec (*timeout);
       pts32 = &ts32;
     }
+
+  socklen_t csize[IOV_MAX];
+  if (vlen > IOV_MAX)
+    vlen = IOV_MAX;
+  for (int i = 0; i < vlen; i++)
+    csize[i] = vmessages[i].msg_hdr.msg_controllen;
+
 # ifdef __ASSUME_RECVMMSG_SYSCALL
   r = SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
 # else
   r = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
 # endif
-  if (r >= 0 && timeout != NULL)
-    *timeout = valid_timespec_to_timespec64 (ts32);
+  if (r >= 0)
+    {
+      if (timeout != NULL)
+        *timeout = valid_timespec_to_timespec64 (ts32);
+
+      for (int i=0; i < r; i++)
+        __convert_scm_timestamps (&vmessages[i].msg_hdr, csize[i]);
+    }
 #endif /* __ASSUME_TIME64_SYSCALLS  */
   return r;
 }
diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c
index c6d1d10b05..510ed04ea5 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmsg.c
@@ -32,8 +32,8 @@
    original message as a spurious control ones of unknown typ while running
    on kernel with native 64-bit time support will only see the time64 version
    of the control message.  */
-static void
-convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
+void
+__convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
 {
   if (msg->msg_control == NULL || msg->msg_controllen == 0)
     return;
@@ -108,7 +108,7 @@ __libc_recvmsg (int fd, struct msghdr *msg, int flags)
 
 #ifndef __ASSUME_TIME64_SYSCALLS
   if (r >= 0)
-    convert_scm_timestamps (msg, orig_controllen);
+    __convert_scm_timestamps (msg, orig_controllen);
 #endif
 
   return r;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 01/14] linux: Simplify clock_getres
  2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
                   ` (12 preceding siblings ...)
  2020-09-08 14:57 ` [RFC 14/14] linux: Add recvvmsg " Adhemerval Zanella
@ 2020-09-10 19:20 ` Alistair Francis
  13 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-10 19:20 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 7:57 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> With arch-syscall.h it can now assumes the existance of either
> __NR_clock_getres or __NR_clock_getres_time64.  The 32-bit time_t
> support is now only build for !__ASSUME_TIME64_SYSCALLS.
>
> It also uses the time64-support functions to simplify it further.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  sysdeps/unix/sysv/linux/clock_getres.c | 38 ++++++++++----------------
>  1 file changed, 15 insertions(+), 23 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
> index 5f6955ab10..6be73c94de 100644
> --- a/sysdeps/unix/sysv/linux/clock_getres.c
> +++ b/sysdeps/unix/sysv/linux/clock_getres.c
> @@ -21,6 +21,7 @@
>  #include <time.h>
>
>  #include <sysdep-vdso.h>
> +#include <time64-support.h>
>  #include <shlib-compat.h>
>  #include <kernel-features.h>
>
> @@ -28,36 +29,26 @@
>  int
>  __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
>  {
> -#ifdef __ASSUME_TIME64_SYSCALLS
> -  /* 64 bit ABIs or Newer 32-bit ABIs that only support 64-bit time_t.  */
> -# ifndef __NR_clock_getres_time64
> -#  define __NR_clock_getres_time64 __NR_clock_getres
> -# endif
> -# ifdef HAVE_CLOCK_GETRES64_VSYSCALL
> -  return INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
> -# else
> -  return INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
> -# endif
> -#else
>    int r;
> -  /* Old 32-bit ABI with possible 64-bit time_t support.  */
> -# ifdef __NR_clock_getres_time64
> -  /* Avoid issue a __NR_clock_getres_time64 syscall on kernels that do not
> -     support 64-bit time_t.  */
> -  static int time64_support = 1;
> -  if (atomic_load_relaxed (&time64_support) != 0)
> +
> +#ifndef __NR_clock_getres_time64
> +# define __NR_clock_getres_time64 __NR_clock_getres
> +#endif
> +  if (supports_time64 ())
>      {
> -#  ifdef HAVE_CLOCK_GETRES64_VSYSCALL
> +#ifdef HAVE_CLOCK_GETRES64_VSYSCALL
>        r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
> -#  else
> +#else
>        r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
> -#  endif
> +#endif
> +
>        if (r == 0 || errno != ENOSYS)
>         return r;
>
> -      atomic_store_relaxed (&time64_support, 0);
> +      mark_time64_unsupported ();
>      }
> -# endif
> +
> +#ifndef __ASSUME_TIME64_SYSCALLS
>    /* Fallback code that uses 32-bit support.  */
>    struct timespec ts32;
>  # ifdef HAVE_CLOCK_GETRES_VSYSCALL
> @@ -67,8 +58,9 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
>  # endif
>    if (r == 0)
>      *res = valid_timespec_to_timespec64 (ts32);
> -  return r;
>  #endif
> +
> +  return r;
>  }
>
>  #if __TIMESIZE != 64
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 02/14] linux: Add ppoll time64 optimization
  2020-09-08 14:57 ` [PATCH v2 02/14] linux: Add ppoll time64 optimization Adhemerval Zanella
@ 2020-09-10 19:21   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-10 19:21 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 7:58 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> It avoid continuing issue the __NR_ppoll_time64 syscall once the kernel
> advertise it does not support it.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  sysdeps/unix/sysv/linux/ppoll.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
> index dd2167fc55..e68a153427 100644
> --- a/sysdeps/unix/sysv/linux/ppoll.c
> +++ b/sysdeps/unix/sysv/linux/ppoll.c
> @@ -22,6 +22,7 @@
>  #include <sys/poll.h>
>  #include <sysdep-cancel.h>
>  #include <kernel-features.h>
> +#include <time64-support.h>
>
>
>  int
> @@ -37,16 +38,23 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
>        timeout = &tval;
>      }
>
> +  int ret;
> +
> +  if (supports_time64 ())
> +    {
>  #ifndef __NR_ppoll_time64
>  # define __NR_ppoll_time64 __NR_ppoll
>  #endif
> -  int ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
> -                            __NSIG_BYTES);
> +      ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
> +                           __NSIG_BYTES);
>
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (ret >= 0 || errno != ENOSYS)
> -    return ret;
> +      if (ret == 0 || errno != ENOSYS)
> +       return ret;
>
> +      mark_time64_unsupported ();
> +    }
> +
> +#ifndef __ASSUME_TIME64_SYSCALLS
>    struct timespec ts32;
>    if (timeout)
>      {
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 03/14] linux: Add time64 semtimedop support
  2020-09-08 14:57 ` [PATCH v2 03/14] linux: Add time64 semtimedop support Adhemerval Zanella
@ 2020-09-10 19:23   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-10 19:23 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 7:58 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> Either the __NR_semtimedop_time64 (for 32-bit) or the __NR_semtimedop
> (for 64-bit) syscall is used as default.  The 32-bit fallback is used
> iff __ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel
> ABI provides either __NR_ipc or __NR_semtimeop (for 32-bit time_t).
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  sysdeps/unix/sysv/linux/include/sys/sem.h |  6 +++
>  sysdeps/unix/sysv/linux/semtimedop.c      | 57 +++++++++++++++++++----
>  2 files changed, 55 insertions(+), 8 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/include/sys/sem.h b/sysdeps/unix/sysv/linux/include/sys/sem.h
> index a9151e057d..f369c6b6d3 100644
> --- a/sysdeps/unix/sysv/linux/include/sys/sem.h
> +++ b/sysdeps/unix/sysv/linux/include/sys/sem.h
> @@ -7,9 +7,15 @@ __typeof__ (semtimedop) __semtimedop attribute_hidden;
>
>  #if __TIMESIZE == 64
>  # define __semctl64 __semctl
> +# define __semtimedop64 __semtimedop
>  #else
> +# include <struct___timespec64.h>
> +
>  extern int __semctl64 (int semid, int semnum, int cmd, ...);
>  libc_hidden_proto (__semctl64);
> +extern int __semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
> +                          const struct __timespec64 *tmo);
> +libc_hidden_proto (__semtimedop64);
>  #endif
>
>  # endif
> diff --git a/sysdeps/unix/sysv/linux/semtimedop.c b/sysdeps/unix/sysv/linux/semtimedop.c
> index 6fdde09bad..56121fb0bf 100644
> --- a/sysdeps/unix/sysv/linux/semtimedop.c
> +++ b/sysdeps/unix/sysv/linux/semtimedop.c
> @@ -22,18 +22,59 @@
>  #include <errno.h>
>
>  /* Perform user-defined atomical operation of array of semaphores.  */
> +int
> +__semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
> +               const struct __timespec64 *timeout)
> +{
> +#if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> +# ifndef __NR_semtimedop_time64
> +#  define __NR_semtimedop_time64 __NR_semtimedop
> +# endif
> +  int r = INLINE_SYSCALL_CALL (semtimedop_time64, semid, sops, nsops,
> +                              timeout);
> +#else
> +  int r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
> +                              SEMTIMEDOP_IPC_ARGS (nsops, sops, timeout));
> +#endif
> +
> +#ifndef __ASSUME_TIME64_SYSCALLS
> +  if (r == 0 || errno != ENOSYS)
> +    return r;
> +
> +  struct timespec ts32, *pts32 = NULL;
> +  if (timeout != NULL)
> +    {
> +      if (! in_time_t_range (timeout->tv_sec))
> +       {
> +         __set_errno (EINVAL);
> +         return -1;
> +       }
> +      ts32 = valid_timespec64_to_timespec (*timeout);
> +      pts32 = &ts32;
> +    }
> +# if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> +  r = INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, pts32);
> +# else
> +  r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
> +                          SEMTIMEDOP_IPC_ARGS (nsops, sops, pts32));
> +# endif
> +#endif /* __ASSUME_TIME64_SYSCALLS  */
> +  return r;
> +}
> +#if __TIMESIZE != 64
> +libc_hidden_def (__semtimedop64)
>
>  int
>  __semtimedop (int semid, struct sembuf *sops, size_t nsops,
>               const struct timespec *timeout)
>  {
> -  /* semtimedop wire-up syscall is not exported for 32-bit ABIs (they have
> -     semtimedop_time64 instead with uses a 64-bit time_t).  */
> -#if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS && defined __NR_semtimedop
> -  return INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, timeout);
> -#else
> -  return INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
> -                             SEMTIMEDOP_IPC_ARGS (nsops, sops, timeout));
> -#endif
> +  struct __timespec64 ts64, *pts64 = NULL;
> +  if (timeout != NULL)
> +    {
> +      ts64 = valid_timespec_to_timespec64 (*timeout);
> +      pts64 = &ts64;
> +    }
> +  return __semtimedop64 (semid, sops, nsops, pts64);
>  }
> +#endif
>  weak_alias (__semtimedop, semtimedop)
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 04/14] linux: Add time64 pselect support
  2020-09-08 14:57 ` [PATCH v2 04/14] linux: Add time64 pselect support Adhemerval Zanella
@ 2020-09-10 19:35   ` Alistair Francis
  2020-09-12  1:22   ` H.J. Lu
  1 sibling, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-10 19:35 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 7:59 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> Changes from previous version:
>
>   * Move the 32-bit fallback implementation to pselect32.c.  It simplifies
>     the required microblaze override.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

>
> ---
>
> The syscall __NR_pselect6_time64 (32-bit) or __NR_pselect6 (64-bit)
> is used as default.  For architectures with __ASSUME_TIME64_SYSCALLS
> the 32-bit fallback uses __NR_pselec6.
>
> To accomodate microblaze missing pselect6 support on kernel older
> than 3.15 the fallback is moved to its own function to the microblaze
> specific implementation can override it.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).
> ---
>  include/sys/select.h                          | 16 ++++++
>  sysdeps/unix/sysv/linux/Makefile              |  2 +-
>  .../microblaze/{pselect.c => pselect32.c}     | 34 ++++--------
>  sysdeps/unix/sysv/linux/pselect.c             | 53 ++++++++++++++-----
>  sysdeps/unix/sysv/linux/pselect32.c           | 47 ++++++++++++++++
>  5 files changed, 116 insertions(+), 36 deletions(-)
>  rename sysdeps/unix/sysv/linux/microblaze/{pselect.c => pselect32.c} (66%)
>  create mode 100644 sysdeps/unix/sysv/linux/pselect32.c
>
> diff --git a/include/sys/select.h b/include/sys/select.h
> index 07bb49b994..b5ae9af861 100644
> --- a/include/sys/select.h
> +++ b/include/sys/select.h
> @@ -3,6 +3,22 @@
>
>  #ifndef _ISOMAC
>  /* Now define the internal interfaces.  */
> +# if __TIMESIZE == 64
> +#  define __pselect64 __pselect
> +#else
> +# include <struct___timespec64.h>
> +extern int __pselect64 (int __nfds, fd_set *__readfds,
> +                       fd_set *__writefds, fd_set *__exceptfds,
> +                       const struct __timespec64 *__timeout,
> +                       const __sigset_t *__sigmask);
> +libc_hidden_proto (__pselect64)
> +
> +extern int __pselect32 (int __nfds, fd_set *__readfds,
> +                       fd_set *__writefds, fd_set *__exceptfds,
> +                       const struct __timespec64 *__timeout,
> +                       const __sigset_t *__sigmask)
> +  attribute_hidden;
> +#endif
>  extern int __pselect (int __nfds, fd_set *__readfds,
>                       fd_set *__writefds, fd_set *__exceptfds,
>                       const struct timespec *__timeout,
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 5079f33655..03cb6e790d 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -61,7 +61,7 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
>                    open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \
>                    timerfd_gettime timerfd_settime prctl \
>                    process_vm_readv process_vm_writev clock_adjtime \
> -                  time64-support
> +                  time64-support pselect32
>
>  CFLAGS-gethostid.c = -fexceptions
>  CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
> diff --git a/sysdeps/unix/sysv/linux/microblaze/pselect.c b/sysdeps/unix/sysv/linux/microblaze/pselect32.c
> similarity index 66%
> rename from sysdeps/unix/sysv/linux/microblaze/pselect.c
> rename to sysdeps/unix/sysv/linux/microblaze/pselect32.c
> index 1dfc3b8fc9..d7cfeaa0e9 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/pselect.c
> +++ b/sysdeps/unix/sysv/linux/microblaze/pselect32.c
> @@ -23,38 +23,27 @@
>  #include <sysdep-cancel.h>
>
>  #ifndef __ASSUME_PSELECT
> -# define __pselect __pselect_syscall
> -#endif
> -
> -/* If pselect is supported, just use the Linux generic implementation.  */
> -#include <sysdeps/unix/sysv/linux/pselect.c>
> -
> -#ifndef __ASSUME_PSELECT
> -# undef __pselect
>  int
> -__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
> -          const struct timespec *timeout, const sigset_t *sigmask)
> +__pselect32 (int nfds, fd_set *readfds, fd_set *writefds,
> +            fd_set *exceptfds, const struct __timespec64 *timeout,
> +            const sigset_t *sigmask)
>  {
> -  int ret = __pselect_syscall (nfds, readfds, writefds, exceptfds, timeout,
> -                              sigmask);
> -  if (ret >= 0 || errno != ENOSYS)
> -    return ret;
> -
>    /* The fallback uses 'select' which shows the race condition regarding
>       signal mask set/restore, requires two additional syscalls, and has
>       a worse timeout precision (microseconds instead of nanoseconds).  */
>
> -  struct timeval tval, *ptval = NULL;
> +  struct timeval tv32, *ptv32 = NULL;
>    if (timeout != NULL)
>      {
> -      if (! valid_nanoseconds (timeout->tv_nsec))
> +      if (! in_time_t_range (timeout->tv_sec)
> +         || ! valid_nanoseconds (timeout->tv_nsec))
>         {
>           __set_errno (EINVAL);
>           return -1;
>         }
>
> -      TIMESPEC_TO_TIMEVAL (&tval, timeout);
> -      ptval = &tval;
> +      tv32 = valid_timespec64_to_timeval (*timeout);
> +      ptv32 = &tv32;
>      }
>
>    sigset_t savemask;
> @@ -62,12 +51,11 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
>      __sigprocmask (SIG_SETMASK, sigmask, &savemask);
>
>    /* select itself is a cancellation entrypoint.  */
> -  ret = __select (nfds, readfds, writefds, exceptfds, ptval);
> +  int r = __select (nfds, readfds, writefds, exceptfds, ptv32);
>
>    if (sigmask != NULL)
>      __sigprocmask (SIG_SETMASK, &savemask, NULL);
>
> -  return ret;
> +  return r;
>  }
> -weak_alias (__pselect, pselect)
> -#endif
> +#endif /* __ASSUME_PSELECT  */
> diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
> index 304db03338..ed36121023 100644
> --- a/sysdeps/unix/sysv/linux/pselect.c
> +++ b/sysdeps/unix/sysv/linux/pselect.c
> @@ -18,14 +18,15 @@
>
>  #include <sys/select.h>
>  #include <sysdep-cancel.h>
> +#include <time64-support.h>
>
>  int
> -__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
> -          const struct timespec *timeout, const sigset_t *sigmask)
> +__pselect64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
> +            const struct __timespec64 *timeout, const sigset_t *sigmask)
>  {
>    /* The Linux kernel can in some situations update the timeout value.
>       We do not want that so use a local variable.  */
> -  struct timespec tval;
> +  struct __timespec64 tval;
>    if (timeout != NULL)
>      {
>        tval = *timeout;
> @@ -36,18 +37,46 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
>       we can only pass in 6 directly.  If there is an architecture with
>       support for more parameters a new version of this file needs to
>       be created.  */
> -  struct
> -  {
> -    __syscall_ulong_t ss;
> -    __syscall_ulong_t ss_len;
> -  } data;
>
> -  data.ss = (__syscall_ulong_t) (uintptr_t) sigmask;
> -  data.ss_len = __NSIG_BYTES;
> +#ifndef __NR_pselect6_time64
> +# define __NR_pselect6_time64 __NR_pselect6
> +#endif
> +  int r;
> +  if (supports_time64 ())
> +    {
> +      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
> +                         timeout,
> +                         ((__syscall_ulong_t[]){ (uintptr_t) sigmask,
> +                                                 __NSIG_BYTES }));
> +      if (r == 0 || errno != ENOSYS)
> +       return r;
> +
> +      mark_time64_unsupported ();
> +    }
>
> -  return SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds,
> -                         timeout, &data);
> +#ifndef __ASSUME_TIME64_SYSCALLS
> +  r = __pselect32 (nfds, readfds, writefds, exceptfds, timeout, sigmask);
> +#endif
> +  return r;
>  }
> +
> +#if __TIMESIZE != 64
> +libc_hidden_def (__pselect64)
> +
> +int
> +__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
> +          const struct timespec *timeout, const sigset_t *sigmask)
> +{
> +  struct __timespec64 ts64, *pts64 = NULL;
> +  if (timeout != NULL)
> +    {
> +      ts64 = valid_timespec_to_timespec64 (*timeout);
> +      pts64 = &ts64;
> +    }
> +  return __pselect64 (nfds, readfds, writefds, exceptfds, pts64, sigmask);
> +}
> +#endif
> +
>  #ifndef __pselect
>  weak_alias (__pselect, pselect)
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/pselect32.c b/sysdeps/unix/sysv/linux/pselect32.c
> new file mode 100644
> index 0000000000..0a2a7ac752
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/pselect32.c
> @@ -0,0 +1,47 @@
> +/* Synchronous I/O multiplexing.  Linux 32-bit time fallback.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sys/select.h>
> +#include <sysdep-cancel.h>
> +
> +#ifndef __ASSUME_TIME64_SYSCALLS
> +
> +int
> +__pselect32 (int nfds, fd_set *readfds, fd_set *writefds,
> +            fd_set *exceptfds, const struct __timespec64 *timeout,
> +            const sigset_t *sigmask)
> +{
> +  struct timespec ts32, *pts32 = NULL;
> +  if (timeout != NULL)
> +    {
> +      if (! in_time_t_range (timeout->tv_sec))
> +       {
> +         __set_errno (EINVAL);
> +         return -1;
> +       }
> +
> +      ts32 = valid_timespec64_to_timespec (*timeout);
> +      pts32 = &ts32;
> +    }
> +
> +  return SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds,
> +                        pts32,
> +                        ((__syscall_ulong_t[]){ (uintptr_t) sigmask,
> +                                                __NSIG_BYTES }));
> +}
> +#endif
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 05/14] linux: Add time64 select support
  2020-09-08 14:57 ` [PATCH v2 05/14] linux: Add time64 select support Adhemerval Zanella
@ 2020-09-11 20:44   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-11 20:44 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 7:59 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> The syscall __NR_pselect6_time64 (32-bit) or __NR_pselect6 (64-bit)
> is used as default.  For architectures with __ASSUME_TIME64_SYSCALLS
> the 32-bit fallback uses __NR_select/__NR__newselect or __NR_pselect6
> (it should cover the microblaze case where older kernels do not
> provide __NR_pselect6).
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  include/sys/select.h             |  8 +++
>  include/time.h                   |  6 +++
>  sysdeps/unix/sysv/linux/select.c | 92 ++++++++++++++++++++++++--------
>  3 files changed, 83 insertions(+), 23 deletions(-)
>
> diff --git a/include/sys/select.h b/include/sys/select.h
> index b5ae9af861..ec073deeba 100644
> --- a/include/sys/select.h
> +++ b/include/sys/select.h
> @@ -5,8 +5,11 @@
>  /* Now define the internal interfaces.  */
>  # if __TIMESIZE == 64
>  #  define __pselect64 __pselect
> +#  define __select64  __select
>  #else
>  # include <struct___timespec64.h>
> +# include <struct___timeval64.h>
> +
>  extern int __pselect64 (int __nfds, fd_set *__readfds,
>                         fd_set *__writefds, fd_set *__exceptfds,
>                         const struct __timespec64 *__timeout,
> @@ -18,6 +21,11 @@ extern int __pselect32 (int __nfds, fd_set *__readfds,
>                         const struct __timespec64 *__timeout,
>                         const __sigset_t *__sigmask)
>    attribute_hidden;
> +
> +extern int __select64 (int __nfds, fd_set *__readfds,
> +                      fd_set *__writefds, fd_set *__exceptfds,
> +                      struct __timeval64 *__timeout);
> +libc_hidden_proto (__select64)
>  #endif
>  extern int __pselect (int __nfds, fd_set *__readfds,
>                       fd_set *__writefds, fd_set *__exceptfds,
> diff --git a/include/time.h b/include/time.h
> index fe4da9ca10..936486e206 100644
> --- a/include/time.h
> +++ b/include/time.h
> @@ -464,6 +464,12 @@ valid_timespec_to_timeval32 (const struct timespec ts)
>    return (struct __timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
>  }
>
> +static inline struct __timeval64
> +valid_timespec_to_timeval64 (const struct timespec ts)
> +{
> +  return (struct __timeval64) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
> +}
> +
>  /* Check if a value is in the valid nanoseconds range. Return true if
>     it is, false otherwise.  */
>  static inline bool
> diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
> index 54c50edba2..bed52fbda2 100644
> --- a/sysdeps/unix/sysv/linux/select.c
> +++ b/sysdeps/unix/sysv/linux/select.c
> @@ -21,6 +21,7 @@
>  #include <sys/select.h>
>  #include <errno.h>
>  #include <sysdep-cancel.h>
> +#include <time64-support.h>
>
>  /* Check the first NFDS descriptors each in READFDS (if not NULL) for read
>     readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
> @@ -28,43 +29,88 @@
>     after waiting the interval specified therein.  Returns the number of ready
>     descriptors, or -1 for errors.  */
>
> -#ifdef __NR__newselect
> -# undef __NR_select
> -# define __NR_select __NR__newselect
> -#endif
> -
>  int
> -__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
> -         struct timeval *timeout)
> +__select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
> +           struct __timeval64 *timeout)
>  {
> -#ifdef __NR_select
> -  return SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds,
> -                        timeout);
> -#else
> -  int result;
> -  struct timespec ts, *tsp = NULL;
> -
> -  if (timeout)
> +  struct __timespec64 ts64, *pts64 = NULL;
> +  if (timeout != NULL)
>      {
> -      TIMEVAL_TO_TIMESPEC (timeout, &ts);
> -      tsp = &ts;
> +      ts64 = timeval64_to_timespec64 (*timeout);
> +      pts64 = &ts64;
>      }
>
> -  result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp,
> -                          NULL);
> -
> -  if (timeout)
> +#ifndef __NR_pselect6_time64
> +# define __NR_pselect6_time64 __NR_pselect6
> +#endif
> +  int r;
> +  if (supports_time64 ())
>      {
> +      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
> +                         pts64, NULL);
>        /* Linux by default will update the timeout after a pselect6 syscall
>           (though the pselect() glibc call suppresses this behavior).
>           Since select() on Linux has the same behavior as the pselect6
>           syscall, we update the timeout here.  */
> -      TIMESPEC_TO_TIMEVAL (timeout, &ts);
> +      if (r == 0 || errno != ENOSYS)
> +       {
> +         if (timeout != NULL)
> +           TIMEVAL_TO_TIMESPEC (timeout, &ts64);
> +         return r;
> +       }
> +
> +      mark_time64_unsupported ();
>      }
>
> -  return result;
> +#ifndef __ASSUME_TIME64_SYSCALLS
> +  struct timespec ts32, *pts32 = NULL;
> +  if (timeout != NULL)
> +    {
> +      if (! in_time_t_range (timeout->tv_sec))
> +       {
> +         __set_errno (EINVAL);
> +         return -1;
> +       }
> +      ts32 = valid_timespec64_to_timespec (ts64);
> +      pts32 = &ts32;
> +    }
> +# ifndef __ASSUME_PSELECT
> +#  ifdef __NR__newselect
> +#   undef __NR_select
> +#   define __NR_select __NR__newselect
> +#  endif
> +  r = SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, pts32);
> +# else
> +  r = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, pts32,
> +                     NULL);
> +# endif
> +  if (r >= 0 && timeout != NULL)
> +    *timeout = valid_timespec_to_timeval64 (ts32);
>  #endif
> +
> +  return r;
>  }
> +
> +#if __TIMESIZE != 64
> +libc_hidden_def (__select64)
> +
> +int
> +__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
> +         struct timeval *timeout)
> +{
> +  struct __timeval64 tv64, *ptv64 = NULL;
> +  if (timeout != NULL)
> +    {
> +      tv64 = valid_timeval_to_timeval64 (*timeout);
> +      ptv64 = &tv64;
> +    }
> +  int r = __select64 (nfds, readfds, writefds, exceptfds, ptv64);
> +  if (r >= 0 && timeout != NULL)
> +    /* The remanining timeout will be always less the input TIMEOUT.  */
> +    *timeout = valid_timeval64_to_timeval (tv64);
> +  return r;
> +}
> +#endif
>  libc_hidden_def (__select)
>
>  weak_alias (__select, select)
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 06/14] linux: Add time64 sigtimedwait support
  2020-09-08 14:57 ` [PATCH v2 06/14] linux: Add time64 sigtimedwait support Adhemerval Zanella
@ 2020-09-11 20:56   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-11 20:56 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 8:00 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> The syscall __NR_sigtimedwait_time64 (for 32-bit) or __NR_sigtimedwait
> (for 64-bit) is used as default.  The 32-bit fallback is used iff
> __ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel ABI
> provides either __NR_rt_sigtimedwait (32-bit time_t).
>
> Checked on x86_64-linux-gnu and i686-linux-gnu.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  include/signal.h                       |  8 +++++
>  sysdeps/unix/sysv/linux/sigtimedwait.c | 50 +++++++++++++++++++++-----
>  2 files changed, 50 insertions(+), 8 deletions(-)
>
> diff --git a/include/signal.h b/include/signal.h
> index b4ee02d153..544d701bce 100644
> --- a/include/signal.h
> +++ b/include/signal.h
> @@ -38,6 +38,14 @@ extern int __sigwait (const sigset_t *__set, int *__sig);
>  libc_hidden_proto (__sigwait)
>  extern int __sigwaitinfo (const sigset_t *__set, siginfo_t *__info);
>  libc_hidden_proto (__sigwaitinfo)
> +#if __TIMESIZE == 64
> +# define __sigtimedwait64 __sigtimedwait
> +#else
> +# include <struct___timespec64.h>
> +extern int __sigtimedwait64 (const sigset_t *__set, siginfo_t *__info,
> +                            const struct __timespec64 *__timeout);
> +libc_hidden_proto (__sigtimedwait64)
> +#endif
>  extern int __sigtimedwait (const sigset_t *__set, siginfo_t *__info,
>                            const struct timespec *__timeout);
>  libc_hidden_proto (__sigtimedwait)
> diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
> index f2ef3aad45..4405606571 100644
> --- a/sysdeps/unix/sysv/linux/sigtimedwait.c
> +++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
> @@ -15,20 +15,38 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>
> -#include <errno.h>
>  #include <signal.h>
> -#include <string.h>
> -#include <sysdep-cancel.h>
> +#include <sysdep.h>
>
>  int
> -__sigtimedwait (const sigset_t *set, siginfo_t *info,
> -               const struct timespec *timeout)
> +__sigtimedwait64 (const sigset_t *set, siginfo_t *info,
> +                 const struct __timespec64 *timeout)
>  {
> -  /* XXX The size argument hopefully will have to be changed to the
> -     real size of the user-level sigset_t.  */
> -  int result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, timeout,
> +#ifndef __NR_rt_sigtimedwait_time64
> +# define __NR_rt_sigtimedwait_time64 __NR_rt_sigtimedwait
> +#endif
> +  int result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
>                                __NSIG_BYTES);
>
> +#ifndef __ASSUME_TIME64_SYSCALLS
> +  if (result != 0 && errno == ENOSYS)
> +    {
> +      struct timespec ts32, *pts32 = NULL;
> +      if (timeout != NULL)
> +       {
> +         if (! in_time_t_range (timeout->tv_sec))
> +           {
> +             __set_errno (EINVAL);
> +             return -1;
> +           }
> +         ts32 = valid_timespec64_to_timespec (*timeout);
> +         pts32 = &ts32;
> +       }
> +      result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, pts32,
> +                              __NSIG_BYTES);
> +    }
> +#endif
> +
>    /* The kernel generates a SI_TKILL code in si_code in case tkill is
>       used.  tkill is transparently used in raise().  Since having
>       SI_TKILL as a code is useful in general we fold the results
> @@ -38,5 +56,21 @@ __sigtimedwait (const sigset_t *set, siginfo_t *info,
>
>    return result;
>  }
> +#if __TIMESIZE != 64
> +libc_hidden_def (__sigtimedwait64)
> +
> +int
> +__sigtimedwait (const sigset_t *set, siginfo_t *info,
> +               const struct timespec *timeout)
> +{
> +  struct __timespec64 ts64, *pts64 = NULL;
> +  if (timeout != NULL)
> +    {
> +      ts64 = valid_timespec_to_timespec64 (*timeout);
> +      pts64 = &ts64;
> +    }
> +  return __sigtimedwait64 (set, info, pts64);
> +}
> +#endif
>  libc_hidden_def (__sigtimedwait)
>  weak_alias (__sigtimedwait, sigtimedwait)
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 04/14] linux: Add time64 pselect support
  2020-09-08 14:57 ` [PATCH v2 04/14] linux: Add time64 pselect support Adhemerval Zanella
  2020-09-10 19:35   ` Alistair Francis
@ 2020-09-12  1:22   ` H.J. Lu
  1 sibling, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2020-09-12  1:22 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 7:59 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> Changes from previous version:
>
>   * Move the 32-bit fallback implementation to pselect32.c.  It simplifies
>     the required microblaze override.
>
> ---
>
> The syscall __NR_pselect6_time64 (32-bit) or __NR_pselect6 (64-bit)
> is used as default.  For architectures with __ASSUME_TIME64_SYSCALLS
> the 32-bit fallback uses __NR_pselec6.
>
> To accomodate microblaze missing pselect6 support on kernel older
> than 3.15 the fallback is moved to its own function to the microblaze
> specific implementation can override it.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

This breaks x32:

FAIL: misc/tst-pselect
FAIL: nptl/tst-cancelx4
FAIL: nptl/tst-cancelx5

-- 
H.J.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 07/14] linux: Use 64-bit time_t syscall on clock_getcputclockid
  2020-09-08 14:57 ` [PATCH v2 07/14] linux: Use 64-bit time_t syscall on clock_getcputclockid Adhemerval Zanella
@ 2020-09-16 15:26   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-16 15:26 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 8:00 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> The syscall __NR_clock_getres_time64 (for 32-bit) or __NR_clock_getres
> (for 64-bit) is used as default.  The 32-bit fallback is used iff
> __ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel ABI
> provides either __NR_rt_sigtimedwait (32-bit time_t).
>
> Since the symbol does not use any type which might be affected by the
> time_t, there is no need to add a 64-bit variant.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  sysdeps/unix/sysv/linux/clock_getcpuclockid.c | 25 +++++++++++--------
>  1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
> index be1f477187..7d2e6d6bfe 100644
> --- a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
> +++ b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
> @@ -30,20 +30,25 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
>
>    const clockid_t pidclock = MAKE_PROCESS_CPUCLOCK (pid, CPUCLOCK_SCHED);
>
> -  int r = INTERNAL_SYSCALL_CALL (clock_getres, pidclock, NULL);
> -  if (!INTERNAL_SYSCALL_ERROR_P (r))
> +#ifndef __NR_clock_getres_time64
> +# define __NR_clock_getres_time64 __NR_clock_getres
> +#endif
> +  int r = INTERNAL_SYSCALL_CALL (clock_getres_time64, pidclock, NULL);
> +
> +#ifndef __ASSUME_TIME64_SYSCALLS
> +  if (r != 0 && r == -ENOSYS)
> +    r = INTERNAL_SYSCALL_CALL (clock_getres, pidclock, NULL);
> +#endif
> +
> +  if (r == 0)
>      {
>        *clock_id = pidclock;
>        return 0;
>      }
> -
> -  if (INTERNAL_SYSCALL_ERRNO (r) == EINVAL)
> -    {
> -      /* The clock_getres system call checked the PID for us.  */
> -      return ESRCH;
> -    }
> -  else
> -    return INTERNAL_SYSCALL_ERRNO (r);
> +  if (r == -EINVAL)
> +    /* The clock_getres system call checked the PID for us.  */
> +    return ESRCH;
> +  return -r;
>  }
>
>  versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17);
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 08/14] linux: Consolidate utimes
  2020-09-08 14:57 ` [PATCH v2 08/14] linux: Consolidate utimes Adhemerval Zanella
@ 2020-09-16 15:30   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-16 15:30 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 8:00 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> The generic version does not have time64 support and Linux default
> uses utimensat.  With hppa version gone, __ASSUME_UTIMES is not used
> anymore.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  sysdeps/unix/sysv/linux/generic/utimes.c      | 46 -------------------
>  .../unix/sysv/linux/hppa/kernel-features.h    |  5 --
>  sysdeps/unix/sysv/linux/hppa/utimes.c         | 30 ------------
>  3 files changed, 81 deletions(-)
>  delete mode 100644 sysdeps/unix/sysv/linux/generic/utimes.c
>  delete mode 100644 sysdeps/unix/sysv/linux/hppa/utimes.c
>
> diff --git a/sysdeps/unix/sysv/linux/generic/utimes.c b/sysdeps/unix/sysv/linux/generic/utimes.c
> deleted file mode 100644
> index 0a8100e1b8..0000000000
> --- a/sysdeps/unix/sysv/linux/generic/utimes.c
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -/* utimes -- Change access and modification times of file.  Linux version.
> -   Copyright (C) 2011-2020 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library.  If not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <stddef.h>
> -#include <utime.h>
> -#include <fcntl.h>
> -#include <sys/time.h>
> -#include <sysdep.h>
> -
> -
> -/* Change the access time of FILE to TVP[0] and
> -   the modification time of FILE to TVP[1].  */
> -int
> -__utimes (const char *file, const struct timeval tvp[2])
> -{
> -  struct timespec ts[2];
> -  struct timespec *tsp = NULL;
> -
> -  if (tvp)
> -    {
> -      TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]);
> -      TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]);
> -      tsp = &ts[0];
> -    }
> -
> -  return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, tsp, 0);
> -}
> -
> -weak_alias (__utimes, utimes)
> diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
> index 8548b5c258..80eec02314 100644
> --- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
> @@ -18,11 +18,6 @@
>     <https://www.gnu.org/licenses/>.  */
>
>
> -/* Support for the utimes syscall was added in 3.14.  */
> -#if __LINUX_KERNEL_VERSION >= 0x030e00
> -# define __ASSUME_UTIMES               1
> -#endif
> -
>  #include_next <kernel-features.h>
>
>  #define __ASSUME_RECV_SYSCALL   1
> diff --git a/sysdeps/unix/sysv/linux/hppa/utimes.c b/sysdeps/unix/sysv/linux/hppa/utimes.c
> deleted file mode 100644
> index a9c4a7ff45..0000000000
> --- a/sysdeps/unix/sysv/linux/hppa/utimes.c
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/* Implement utimes for hppa.
> -   Copyright (C) 2014-2020 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -/* hppa has the utimensat syscall in all supported kernel versions but
> -   gained the utimes syscall later, so use the linux-generic
> -   implementation of utimes in terms of the utimensat syscall unless
> -   the utimes syscall is known to be available.  */
> -
> -#include <kernel-features.h>
> -
> -#ifdef __ASSUME_UTIMES
> -# include <sysdeps/unix/sysv/linux/utimes.c>
> -#else
> -# include <sysdeps/unix/sysv/linux/generic/utimes.c>
> -#endif
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 10/14] linux: Add time64 support for nanosleep
  2020-09-08 14:57 ` [PATCH v2 10/14] linux: Add time64 support for nanosleep Adhemerval Zanella
@ 2020-09-16 17:16   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-16 17:16 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 8:01 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> It uses __clock_nanosleep64 and adds the __nanosleep64 symbol.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
> kernel).

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  include/time.h                      |  9 ++++++
>  sysdeps/unix/sysv/linux/nanosleep.c | 50 +++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+)
>  create mode 100644 sysdeps/unix/sysv/linux/nanosleep.c
>
> diff --git a/include/time.h b/include/time.h
> index 936486e206..edf6cdf829 100644
> --- a/include/time.h
> +++ b/include/time.h
> @@ -271,6 +271,15 @@ extern struct tm *__tz_convert (__time64_t timer, int use_localtime,
>  extern int __nanosleep (const struct timespec *__requested_time,
>                         struct timespec *__remaining);
>  hidden_proto (__nanosleep)
> +#if __TIMESIZE == 64
> +# define __nanosleep64 __nanosleep
> +#else
> +extern int __nanosleep64 (const struct __timespec64 *__requested_time,
> +                         struct __timespec64 *__remaining);
> +hidden_proto (__nanosleep64)
> +#endif
> +
> +
>  extern int __getdate_r (const char *__string, struct tm *__resbufp)
>    attribute_hidden;
>
> diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c
> new file mode 100644
> index 0000000000..8f4ee0f744
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/nanosleep.c
> @@ -0,0 +1,50 @@
> +/* High-resolution sleep.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <time.h>
> +#include <errno.h>
> +
> +int
> +__nanosleep64 (const struct __timespec64 *req, struct __timespec64 *rem)
> +{
> +  int ret = __clock_nanosleep_time64 (CLOCK_REALTIME, 0, req, rem);
> +  if (ret != 0)
> +    {
> +      __set_errno (ret);
> +      return -1;
> +    }
> +  return 0;
> +}
> +#if __TIMESIZE != 64
> +libc_hidden_def (__nanosleep64)
> +
> +int
> +__nanosleep (const struct timespec *req, struct timespec *rem)
> +{
> +  struct __timespec64 treq64, trem64;
> +
> +  treq64 = valid_timespec_to_timespec64 (*req);
> +  int ret = __nanosleep64 (&treq64, &trem64);
> +
> +  if (ret != 0 && errno == EINTR && rem != NULL)
> +    *rem = valid_timespec64_to_timespec (trem64);
> +  return ret;
> +}
> +#endif
> +libc_hidden_def (__nanosleep)
> +weak_alias (__nanosleep, nanosleep)
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 11/14] linux: Add time64 recvmmsg support
  2020-09-08 14:57 ` [PATCH v2 11/14] linux: Add time64 recvmmsg support Adhemerval Zanella
@ 2020-09-25 21:18   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2020-09-25 21:18 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Tue, Sep 8, 2020 at 8:02 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> The wire-up syscall __NR_recvmmsg_time64 (for 32-bit) or
> __NR_recvmmsg (for 64-bit) is used as default.  The 32-bit fallback
> is used iff __ASSUME_TIME64_SYSCALLS is not defined, which assumes the
> kernel ABI provides either __NR_socketcall or __NR_recvmmsg
> (32-bit time_t).
>
> It does not handle the timestamps on ancillary data (SCM_TIMESTAMPING
> records).
>
> Checked on x86_64-linux-gnu and i686-linux-gnu.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  include/sys/socket.h               |  8 ++++
>  sysdeps/unix/sysv/linux/recvmmsg.c | 63 ++++++++++++++++++++++++------
>  2 files changed, 60 insertions(+), 11 deletions(-)
>
> diff --git a/include/sys/socket.h b/include/sys/socket.h
> index 26db0e0d77..0e39dd2a3a 100644
> --- a/include/sys/socket.h
> +++ b/include/sys/socket.h
> @@ -104,6 +104,14 @@ extern ssize_t __libc_recvmsg (int __fd, struct msghdr *__message,
>                                int __flags);
>  extern ssize_t __recvmsg (int __fd, struct msghdr *__message,
>                           int __flags) attribute_hidden;
> +#if __TIMESIZE == 64
> +# define __recvmmsg64 __recvmmsg
> +#else
> +extern int __recvmmsg64 (int __fd, struct mmsghdr *vmessages,
> +                        unsigned int vlen, int flags,
> +                        struct __timespec64 *timeout);
> +libc_hidden_proto (__recvmmsg64)
> +#endif
>
>  /* Set socket FD's option OPTNAME at protocol level LEVEL
>     to *OPTVAL (which is OPTLEN bytes long).
> diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
> index 42c80c59c3..a29c91fb76 100644
> --- a/sysdeps/unix/sysv/linux/recvmmsg.c
> +++ b/sysdeps/unix/sysv/linux/recvmmsg.c
> @@ -16,21 +16,62 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>
> -#include <errno.h>
>  #include <sys/socket.h>
> -
> -#include <sysdep-cancel.h>
> -#include <sys/syscall.h>
> +#include <sysdep.h>
>  #include <socketcall.h>
> -#include <kernel-features.h>
>
>  int
> -recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
> -         struct timespec *tmo)
> +__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
> +             struct __timespec64 *timeout)
>  {
> -#ifdef __ASSUME_RECVMMSG_SYSCALL
> -  return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
> -#else
> -  return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
> +#ifndef __NR_recvmmsg_time64
> +# define __NR_recvmmsg_time64 __NR_recvmmsg
>  #endif
> +  int r = SYSCALL_CANCEL (recvmmsg_time64, fd, vmessages, vlen, flags,
> +                         timeout);
> +#ifndef __ASSUME_TIME64_SYSCALLS
> +  if (r >= 0 || errno != ENOSYS)
> +    return r;
> +
> +  struct timespec ts32, *pts32 = NULL;
> +  if (timeout != NULL)
> +    {
> +      if (! in_time_t_range (timeout->tv_sec))
> +       {
> +         __set_errno (EINVAL);
> +         return -1;
> +       }
> +      ts32 = valid_timespec64_to_timespec (*timeout);
> +      pts32 = &ts32;
> +    }
> +# ifdef __ASSUME_RECVMMSG_SYSCALL
> +  r = SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
> +# else
> +  r = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
> +# endif
> +  if (r >= 0 && timeout != NULL)
> +    *timeout = valid_timespec_to_timespec64 (ts32);
> +#endif /* __ASSUME_TIME64_SYSCALLS  */
> +  return r;
>  }
> +#if __TIMESIZE != 64
> +libc_hidden_def (__recvmmsg64)
> +
> +int
> +__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
> +           struct timespec *timeout)
> +{
> +  struct __timespec64 ts64, *pts64 = NULL;
> +  if (timeout != NULL)
> +    {
> +      ts64 = valid_timespec_to_timespec64 (*timeout);
> +      pts64 = &ts64;
> +    }
> +  int r = __recvmmsg64 (fd, vmessages, vlen, flags, pts64);
> +  if (r >= 0)
> +    /* The remanining timeout will be always less the input TIMEOUT.  */
> +    *timeout = valid_timespec64_to_timespec (ts64);
> +  return r;
> +}
> +#endif
> +weak_alias (__recvmmsg, recvmmsg)
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2020-09-25 21:29 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-08 14:57 [PATCH v2 01/14] linux: Simplify clock_getres Adhemerval Zanella
2020-09-08 14:57 ` [PATCH v2 02/14] linux: Add ppoll time64 optimization Adhemerval Zanella
2020-09-10 19:21   ` Alistair Francis
2020-09-08 14:57 ` [PATCH v2 03/14] linux: Add time64 semtimedop support Adhemerval Zanella
2020-09-10 19:23   ` Alistair Francis
2020-09-08 14:57 ` [PATCH v2 04/14] linux: Add time64 pselect support Adhemerval Zanella
2020-09-10 19:35   ` Alistair Francis
2020-09-12  1:22   ` H.J. Lu
2020-09-08 14:57 ` [PATCH v2 05/14] linux: Add time64 select support Adhemerval Zanella
2020-09-11 20:44   ` Alistair Francis
2020-09-08 14:57 ` [PATCH v2 06/14] linux: Add time64 sigtimedwait support Adhemerval Zanella
2020-09-11 20:56   ` Alistair Francis
2020-09-08 14:57 ` [PATCH v2 07/14] linux: Use 64-bit time_t syscall on clock_getcputclockid Adhemerval Zanella
2020-09-16 15:26   ` Alistair Francis
2020-09-08 14:57 ` [PATCH v2 08/14] linux: Consolidate utimes Adhemerval Zanella
2020-09-16 15:30   ` Alistair Francis
2020-09-08 14:57 ` [PATCH v2 09/14] linux: Fix time64 support for futimesat Adhemerval Zanella
2020-09-08 14:57 ` [PATCH v2 10/14] linux: Add time64 support for nanosleep Adhemerval Zanella
2020-09-16 17:16   ` Alistair Francis
2020-09-08 14:57 ` [PATCH v2 11/14] linux: Add time64 recvmmsg support Adhemerval Zanella
2020-09-25 21:18   ` Alistair Francis
2020-09-08 14:57 ` [RFC 12/14] linux: Add fallback for 64-bit time_t SO_{RCV,SND}TIMEO Adhemerval Zanella
2020-09-08 14:57 ` [RFC 13/14] linux: Add fallback for 64-bit time_t SO_TIMESTAMP{NS} Adhemerval Zanella
2020-09-08 14:57 ` [RFC 14/14] linux: Add recvvmsg " Adhemerval Zanella
2020-09-10 19:20 ` [PATCH v2 01/14] linux: Simplify clock_getres Alistair Francis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).