public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 00/18] More y2038 fixes
@ 2021-06-17 11:50 Adhemerval Zanella
  2021-06-17 11:50 ` [PATCH 01/18] Use 64 bit time_t stat internally Adhemerval Zanella
                   ` (18 more replies)
  0 siblings, 19 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

Hi Carlos and Lukasz,

This patchset adds more y2038 fixes that I would like to push for 2.34.
The first two patches enable more internal y2038 usage on glibc and
also for the installed programs.  Making glibc the first consumer of
these newer interfaces should improve coverage.

The next 6 patches removes an optimization I added on some specific
syscall, where a global variable it atomically set once glibc detects
that kernel supports 64-bit time.  The problem with this approach
breaks the usage case of live migration like CRIU or similar.  Also for
some interfaces that do not query information from kernel, most usages
can be optimized away by either building glibc with a minimum 5.1 kernel
or by using the 32-bit syscall for the common case.

So the following patch implement this optimization for the interfaces
that allows it.  If the provided timeout can be fit in old 32-bit
time_t, the old syscall is used instead.  This optimization is only used
for !__ASSUME_TIME64_SYSCALLS, otherwise the newer 64-bit syscall are
used.

I checked this with 3 different configation which should cover most
usages:

  - i686-linux-gnu on a 4.15 kernel and default --enable-kernel=3.2.
    This uses the 32-bit optimization to avoid calling the newer
    64-bit syscall when possible.  It also triggers and EOVERFLOW
    when 64-bit inputs are used without proper kernel support.
  - i686-linux-gnu on a 5.11 kernel and default --enable-kernel=3.2.
    This will also use the 32-bit optimization, but it will always
    succeded due proper kernel support.
  - i686-linux-gnu on a 5.11 kernel and with --enable-kernel=5.1.
    This enables __ASSUME_TIME64_SYSCALLS and only uses 64-bit
    time_t syscalls.

Adhemerval Zanella (18):
  Use 64 bit time_t stat internally
  Use LFS and 64 bit time for installed programs
  support: Add support_create_timer
  linux: Only use 64-bit syscall if required for ppoll
  linux: Only use 64-bit syscall if required for pselect
  linux: Only use 64-bit syscall if required for select
  linux: Remove supports_time64 () from clock_getres
  linux: Remove supports_time64 () from clock_gettime
  linux: Remove time64-support
  linux: timerfd_gettime minor cleanup
  linux: Only use 64-bit syscall if required for semtimedop
  linux: Only use 64-bit syscall if required for timerfd_settime
  linux: Only use 64-bit syscall if required for mq_timedreceive
  linux: Only use 64-bit syscall if required for mq_timedsend
  linux: Only use 64-bit syscall if required for sigtimedwait
  linux: Only use 64-bit syscall if required for utimensat family
  linux: Only use 64-bit syscall if required for internal futex
  linux: Only use 64-bit syscall if required for clock_nanosleep

 Makeconfig                                    |   8 +-
 Makerules                                     |  12 +-
 csu/check_fds.c                               |   8 +-
 elf/dl-load.c                                 |   8 +-
 elf/dl-misc.c                                 |   4 +-
 elf/dl-profile.c                              |   4 +-
 iconv/gconv_cache.c                           |   4 +-
 include/dirent.h                              |   2 +-
 include/file_change_detection.h               |   6 +-
 include/sys/select.h                          |   5 +
 inet/rcmd.c                                   |   6 +-
 intl/loadmsgcat.c                             |   4 +-
 io/Makefile                                   |   4 +-
 io/file_change_detection.c                    |  16 ++-
 io/getdirname.c                               |   6 +-
 libio/filedoalloc.c                           |   2 +-
 libio/fileops.c                               |   8 +-
 libio/oldfileops.c                            |   2 +-
 libio/wfileops.c                              |   2 +-
 locale/loadarchive.c                          |   8 +-
 locale/loadlocale.c                           |   6 +-
 locale/localeinfo.h                           |   2 +-
 misc/Makefile                                 |  11 ++
 misc/tst-pselect.c                            | 120 ++++++++----------
 misc/tst-select.c                             |  39 +++---
 nptl/futex-internal.c                         |  52 +++++---
 nscd/nscd_helper.c                            |   4 +-
 nss/nss_database.c                            |   4 +-
 rt/Makefile                                   |   4 +-
 rt/tst-mqueue10-time64.c                      |   1 +
 rt/tst-mqueue10.c                             |  72 +++++++++++
 support/Makefile                              |   1 +
 support/support.h                             |  11 ++
 support/support_create_timer.c                |  69 ++++++++++
 sysdeps/nptl/futex-internal.h                 |  24 ++--
 sysdeps/posix/dl-fileid.h                     |   4 +-
 sysdeps/posix/euidaccess.c                    |   4 +-
 sysdeps/posix/getaddrinfo.c                   |  21 +--
 sysdeps/posix/getcwd.c                        |  15 ++-
 sysdeps/posix/pathconf.c                      |   4 +-
 sysdeps/posix/sysconf.c                       |   4 +-
 sysdeps/posix/tempname.c                      |   8 +-
 sysdeps/unix/sysv/linux/Makefile              |  15 ++-
 sysdeps/unix/sysv/linux/clock_getres.c        |  16 +--
 sysdeps/unix/sysv/linux/clock_gettime.c       |  14 +-
 sysdeps/unix/sysv/linux/clock_nanosleep.c     |  47 ++++---
 sysdeps/unix/sysv/linux/fdopendir.c           |   4 +-
 sysdeps/unix/sysv/linux/fexecve.c             |   4 +-
 .../unix/sysv/linux/microblaze/pselect32.c    |   3 +-
 sysdeps/unix/sysv/linux/mq_timedreceive.c     |  35 ++---
 sysdeps/unix/sysv/linux/mq_timedsend.c        |  35 ++---
 sysdeps/unix/sysv/linux/opendir.c             |   7 +-
 sysdeps/unix/sysv/linux/pathconf.c            |   5 +-
 sysdeps/unix/sysv/linux/ppoll.c               |  41 +++---
 sysdeps/unix/sysv/linux/pselect.c             |  47 ++++---
 sysdeps/unix/sysv/linux/pselect32.c           |   6 -
 sysdeps/unix/sysv/linux/select.c              |  60 +++------
 sysdeps/unix/sysv/linux/select32.c            |  58 +++++++++
 sysdeps/unix/sysv/linux/semtimedop.c          |  54 ++++----
 sysdeps/unix/sysv/linux/sigtimedwait.c        |  26 ++--
 sysdeps/unix/sysv/linux/time64-support.c      |  23 ----
 sysdeps/unix/sysv/linux/time64-support.h      |  70 ----------
 sysdeps/unix/sysv/linux/timerfd_gettime.c     |  10 +-
 sysdeps/unix/sysv/linux/timerfd_settime.c     |  25 ++--
 sysdeps/unix/sysv/linux/tst-ppoll.c           |  15 +++
 sysdeps/unix/sysv/linux/tst-sigtimedwait.c    |  18 +++
 sysdeps/unix/sysv/linux/tst-timerfd.c         |  29 ++++-
 sysdeps/unix/sysv/linux/ttyname.h             |  10 +-
 sysdeps/unix/sysv/linux/ttyname_r.c           |  16 +--
 sysdeps/unix/sysv/linux/utimensat.c           |  35 +++--
 sysvipc/Makefile                              |   9 ++
 sysvipc/ftok.c                                |   4 +-
 sysvipc/test-sysvsem.c                        |  22 +++-
 time/Makefile                                 |   9 ++
 time/tst-clock_nanosleep.c                    |  40 +++---
 time/tzfile.c                                 |   6 +-
 76 files changed, 851 insertions(+), 566 deletions(-)
 create mode 100644 rt/tst-mqueue10-time64.c
 create mode 100644 rt/tst-mqueue10.c
 create mode 100644 support/support_create_timer.c
 create mode 100644 sysdeps/unix/sysv/linux/select32.c
 delete mode 100644 sysdeps/unix/sysv/linux/time64-support.c
 delete mode 100644 sysdeps/unix/sysv/linux/time64-support.h

-- 
2.30.2


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

* [PATCH 01/18] Use 64 bit time_t stat internally
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:42   ` Lukasz Majewski
  2021-06-22 19:37   ` Florian Weimer
  2021-06-17 11:50 ` [PATCH 02/18] Use LFS and 64 bit time for installed programs Adhemerval Zanella
                   ` (17 subsequent siblings)
  18 siblings, 2 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For the legacy ABI with supports 32 bit time_t it calls the 64 bit
time directly, since the LFS symbols calls the 64 bit time_t ones
internally.

Checked on i686-linux-gnu and x86_64-linux-gnu.
---
 csu/check_fds.c                     |  8 ++++----
 elf/dl-load.c                       |  8 ++++----
 elf/dl-misc.c                       |  4 ++--
 elf/dl-profile.c                    |  4 ++--
 iconv/gconv_cache.c                 |  4 ++--
 include/dirent.h                    |  2 +-
 include/file_change_detection.h     |  6 +++---
 inet/rcmd.c                         |  6 +++---
 intl/loadmsgcat.c                   |  4 ++--
 io/Makefile                         |  4 ++--
 io/file_change_detection.c          | 16 +++++++++-------
 io/getdirname.c                     |  6 +++---
 libio/filedoalloc.c                 |  2 +-
 libio/fileops.c                     |  8 ++++----
 libio/oldfileops.c                  |  2 +-
 libio/wfileops.c                    |  2 +-
 locale/loadarchive.c                |  8 ++++----
 locale/loadlocale.c                 |  6 +++---
 nscd/nscd_helper.c                  |  4 ++--
 nss/nss_database.c                  |  4 ++--
 sysdeps/posix/dl-fileid.h           |  4 ++--
 sysdeps/posix/euidaccess.c          |  4 ++--
 sysdeps/posix/getaddrinfo.c         | 21 +++++++++++----------
 sysdeps/posix/getcwd.c              | 15 ++++++++-------
 sysdeps/posix/pathconf.c            |  4 ++--
 sysdeps/posix/sysconf.c             |  4 ++--
 sysdeps/posix/tempname.c            |  8 ++++----
 sysdeps/unix/sysv/linux/fdopendir.c |  4 ++--
 sysdeps/unix/sysv/linux/fexecve.c   |  4 ++--
 sysdeps/unix/sysv/linux/opendir.c   |  7 ++++---
 sysdeps/unix/sysv/linux/pathconf.c  |  5 +++--
 sysdeps/unix/sysv/linux/ttyname.h   | 10 ++--------
 sysdeps/unix/sysv/linux/ttyname_r.c | 16 ++++++++--------
 sysvipc/ftok.c                      |  4 ++--
 time/tzfile.c                       |  6 +++---
 35 files changed, 112 insertions(+), 112 deletions(-)

diff --git a/csu/check_fds.c b/csu/check_fds.c
index fbab28c284..6dc67334af 100644
--- a/csu/check_fds.c
+++ b/csu/check_fds.c
@@ -69,10 +69,10 @@ check_one_fd (int fd, int mode)
 	 Note that the following code assumes that STDIN_FILENO,
 	 STDOUT_FILENO, STDERR_FILENO are the three lowest file
 	 decsriptor numbers, in this order.  */
-      struct stat64 st;
-      if (__builtin_expect (nullfd != fd, 0)
-	  || __builtin_expect (__fstat64 (fd, &st), 0) != 0
-	  || __builtin_expect (S_ISCHR (st.st_mode), 1) == 0
+      struct __stat64_t64 st;
+      if (__glibc_unlikely (nullfd != fd)
+	  || __glibc_likely (__fstat64_time64 (fd, &st) != 0)
+	  || __glibc_unlikely (S_ISCHR (st.st_mode) == 0)
 	  || st.st_rdev != dev)
 	/* We cannot even give an error message here since it would
 	   run into the same problems.  */
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 918ec7546c..a08df001af 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1946,11 +1946,11 @@ open_path (const char *name, size_t namelen, int mode,
 		{
 		  /* We failed to open machine dependent library.  Let's
 		     test whether there is any directory at all.  */
-		  struct stat64 st;
+		  struct __stat64_t64 st;
 
 		  buf[buflen - namelen - 1] = '\0';
 
-		  if (__stat64 (buf, &st) != 0
+		  if (__stat64_time64 (buf, &st) != 0
 		      || ! S_ISDIR (st.st_mode))
 		    /* The directory does not exist or it is no directory.  */
 		    this_dir->status[cnt] = nonexisting;
@@ -1968,9 +1968,9 @@ open_path (const char *name, size_t namelen, int mode,
 	      /* This is an extra security effort to make sure nobody can
 		 preload broken shared objects which are in the trusted
 		 directories and so exploit the bugs.  */
-	      struct stat64 st;
+	      struct __stat64_t64 st;
 
-	      if (__fstat64 (fd, &st) != 0
+	      if (__fstat64_time64 (fd, &st) != 0
 		  || (st.st_mode & S_ISUID) == 0)
 		{
 		  /* The shared object cannot be tested for being SUID
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
index d4803bba4e..b256d792c6 100644
--- a/elf/dl-misc.c
+++ b/elf/dl-misc.c
@@ -43,11 +43,11 @@ void *
 _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
 {
   void *result = MAP_FAILED;
-  struct stat64 st;
+  struct __stat64_t64 st;
   int fd = __open64_nocancel (file, O_RDONLY | O_CLOEXEC);
   if (fd >= 0)
     {
-      if (__fstat64 (fd, &st) >= 0)
+      if (__fstat64_time64 (fd, &st) >= 0)
 	{
 	  *sizep = st.st_size;
 
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index 35b03959bc..088c023d95 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -185,7 +185,7 @@ _dl_start_profile (void)
 {
   char *filename;
   int fd;
-  struct stat64 st;
+  struct __stat64_t64 st;
   const ElfW(Phdr) *ph;
   ElfW(Addr) mapstart = ~((ElfW(Addr)) 0);
   ElfW(Addr) mapend = 0;
@@ -342,7 +342,7 @@ _dl_start_profile (void)
       return;
     }
 
-  if (__fstat64 (fd, &st) < 0 || !S_ISREG (st.st_mode))
+  if (__fstat64_time64 (fd, &st) < 0 || !S_ISREG (st.st_mode))
     {
       /* Not stat'able or not a regular file => don't use it.  */
       errstr = "%s: cannot stat file: %s\n";
diff --git a/iconv/gconv_cache.c b/iconv/gconv_cache.c
index 642cc731eb..68d6386d01 100644
--- a/iconv/gconv_cache.c
+++ b/iconv/gconv_cache.c
@@ -48,7 +48,7 @@ int
 __gconv_load_cache (void)
 {
   int fd;
-  struct stat64 st;
+  struct __stat64_t64 st;
   struct gconvcache_header *header;
 
   /* We cannot use the cache if the GCONV_PATH environment variable is
@@ -64,7 +64,7 @@ __gconv_load_cache (void)
     return -1;
 
   /* Get information about the file.  */
-  if (__builtin_expect (__fstat64 (fd, &st), 0) < 0
+  if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0)
       /* We do not have to start looking at the file if it cannot contain
 	 at least the cache header.  */
       || (size_t) st.st_size < sizeof (struct gconvcache_header))
diff --git a/include/dirent.h b/include/dirent.h
index f1d7e8359c..d7567f5e86 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -49,7 +49,7 @@ extern int __versionsort64 (const struct dirent64 **a,
 			    const struct dirent64 **b)
      __attribute_pure__;
 extern DIR *__alloc_dir (int fd, bool close_fd, int flags,
-			 const struct stat64 *statp)
+			 const struct __stat64_t64 *statp)
      __nonnull (4) attribute_hidden;
 extern __typeof (rewinddir) __rewinddir;
 extern __typeof (seekdir) __seekdir;
diff --git a/include/file_change_detection.h b/include/file_change_detection.h
index 9de2bd0b79..953de7c7fd 100644
--- a/include/file_change_detection.h
+++ b/include/file_change_detection.h
@@ -33,8 +33,8 @@ struct file_change_detection
   off64_t size;
 
   ino64_t ino;
-  struct timespec mtime;
-  struct timespec ctime;
+  struct __timespec64 mtime;
+  struct __timespec64 ctime;
 };
 
 /* Returns true if *LEFT and *RIGHT describe the same version of the
@@ -45,7 +45,7 @@ bool __file_is_unchanged (const struct file_change_detection *left,
 /* Extract file change information to *FILE from the stat buffer
    *ST.  */
 void __file_change_detection_for_stat (struct file_change_detection *file,
-                                       const struct stat64 *st);
+                                       const struct __stat64_t64 *st);
 
 /* Writes file change information for PATH to *FILE.  Returns true on
    success.  For benign errors, *FILE is cleared, and true is
diff --git a/inet/rcmd.c b/inet/rcmd.c
index 0cfdaee15e..0d6b595572 100644
--- a/inet/rcmd.c
+++ b/inet/rcmd.c
@@ -468,14 +468,14 @@ ruserok (const char *rhost, int superuser, const char *ruser,
 static FILE *
 iruserfopen (const char *file, uid_t okuser)
 {
-  struct stat64 st;
+  struct __stat64_t64 st;
   char *cp = NULL;
   FILE *res = NULL;
 
   /* If not a regular file, if owned by someone other than user or
      root, if writeable by anyone but the owner, or if hardlinked
      anywhere, quit.  */
-  if (__lstat64 (file, &st))
+  if (__lstat64_time64 (file, &st))
     cp = _("lstat failed");
   else if (!S_ISREG (st.st_mode))
     cp = _("not regular file");
@@ -484,7 +484,7 @@ iruserfopen (const char *file, uid_t okuser)
       res = fopen (file, "rce");
       if (!res)
 	cp = _("cannot open");
-      else if (__fstat64 (fileno (res), &st) < 0)
+      else if (__fstat64_time64 (fileno (res), &st) < 0)
 	cp = _("fstat failed");
       else if (st.st_uid && st.st_uid != okuser)
 	cp = _("bad owner");
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index 4fda9b0219..30588e9996 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -756,7 +756,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
   int fd = -1;
   size_t size;
 #ifdef _LIBC
-  struct stat64 st;
+  struct __stat64_t64 st;
 #else
   struct stat st;
 #endif
@@ -804,7 +804,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
   /* We must know about the size of the file.  */
   if (
 #ifdef _LIBC
-      __builtin_expect (__fstat64 (fd, &st) != 0, 0)
+      __builtin_expect (__fstat64_time64 (fd, &st) != 0, 0)
 #else
       __builtin_expect (fstat (fd, &st) != 0, 0)
 #endif
diff --git a/io/Makefile b/io/Makefile
index ba8bd37355..1a16990205 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -69,7 +69,7 @@ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
 		   tst-posix_fallocate tst-posix_fallocate64 \
 		   tst-fts tst-fts-lfs tst-open-tmpfile \
 		   tst-copy_file_range tst-getcwd-abspath tst-lockf \
-		   tst-ftw-lnk tst-file_change_detection tst-lchmod \
+		   tst-ftw-lnk tst-lchmod \
 		   tst-ftw-bz26353 tst-stat tst-stat-lfs \
 		   tst-utime \
 		   tst-utimes \
@@ -90,7 +90,7 @@ tests-time64 := \
   tst-utimes-time64 \
 
 # Likewise for statx, but we do not need static linking here.
-tests-internal += tst-statx
+tests-internal += tst-statx tst-file_change_detection
 tests-static += tst-statx
 
 ifeq ($(run-built-tests),yes)
diff --git a/io/file_change_detection.c b/io/file_change_detection.c
index 9871bc9166..ac5e451513 100644
--- a/io/file_change_detection.c
+++ b/io/file_change_detection.c
@@ -44,7 +44,7 @@ libc_hidden_def (__file_is_unchanged)
 
 void
 __file_change_detection_for_stat (struct file_change_detection *file,
-                                  const struct stat64 *st)
+                                  const struct __stat64_t64 *st)
 {
   if (S_ISDIR (st->st_mode))
     /* Treat as empty file.  */
@@ -56,8 +56,10 @@ __file_change_detection_for_stat (struct file_change_detection *file,
     {
       file->size = st->st_size;
       file->ino = st->st_ino;
-      file->mtime = st->st_mtim;
-      file->ctime = st->st_ctim;
+      file->mtime = (struct __timespec64 ) { .tv_sec  = st->st_mtim.tv_sec,
+					     .tv_nsec = st->st_mtim.tv_nsec };
+      file->ctime = (struct __timespec64 ) { .tv_sec  = st->st_ctim.tv_sec,
+					     .tv_nsec = st->st_mtim.tv_nsec };
     }
 }
 libc_hidden_def (__file_change_detection_for_stat)
@@ -66,8 +68,8 @@ bool
 __file_change_detection_for_path (struct file_change_detection *file,
                                   const char *path)
 {
-  struct stat64 st;
-  if (__stat64 (path, &st) != 0)
+  struct __stat64_t64 st;
+  if (__stat64_time64 (path, &st) != 0)
     switch (errno)
       {
       case EACCES:
@@ -104,8 +106,8 @@ __file_change_detection_for_fp (struct file_change_detection *file,
     }
   else
     {
-      struct stat64 st;
-      if (__fstat64 (__fileno (fp), &st) != 0)
+      struct __stat64_t64 st;
+      if (__fstat64_time64 (__fileno (fp), &st) != 0)
         /* If we already have a file descriptor, all errors are fatal.  */
         return false;
       else
diff --git a/io/getdirname.c b/io/getdirname.c
index 32b5ab4b6c..f29e910b37 100644
--- a/io/getdirname.c
+++ b/io/getdirname.c
@@ -28,12 +28,12 @@ char *
 get_current_dir_name (void)
 {
   char *pwd;
-  struct stat64 dotstat, pwdstat;
+  struct __stat64_t64 dotstat, pwdstat;
 
   pwd = getenv ("PWD");
   if (pwd != NULL
-      && __stat64 (".", &dotstat) == 0
-      && __stat64 (pwd, &pwdstat) == 0
+      && __stat64_time64 (".", &dotstat) == 0
+      && __stat64_time64 (pwd, &pwdstat) == 0
       && pwdstat.st_dev == dotstat.st_dev
       && pwdstat.st_ino == dotstat.st_ino)
     /* The PWD value is correct.  Use it.  */
diff --git a/libio/filedoalloc.c b/libio/filedoalloc.c
index 7afa3cb683..c792eec88f 100644
--- a/libio/filedoalloc.c
+++ b/libio/filedoalloc.c
@@ -78,7 +78,7 @@ _IO_file_doallocate (FILE *fp)
 {
   size_t size;
   char *p;
-  struct stat64 st;
+  struct __stat64_t64 st;
 
   size = BUFSIZ;
   if (fp->_fileno >= 0 && __builtin_expect (_IO_SYSSTAT (fp, &st), 0) >= 0)
diff --git a/libio/fileops.c b/libio/fileops.c
index a71a567547..e8ee374821 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -545,7 +545,7 @@ libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow)
 static int
 mmap_remap_check (FILE *fp)
 {
-  struct stat64 st;
+  struct __stat64_t64 st;
 
   if (_IO_SYSSTAT (fp, &st) == 0
       && S_ISREG (st.st_mode) && st.st_size != 0
@@ -663,7 +663,7 @@ decide_maybe_mmap (FILE *fp)
      file descriptors are for mmap-able objects and on 32-bit
      machines we don't want to map files which are too large since
      this would require too much virtual memory.  */
-  struct stat64 st;
+  struct __stat64_t64 st;
 
   if (_IO_SYSSTAT (fp, &st) == 0
       && S_ISREG (st.st_mode) && st.st_size != 0
@@ -962,7 +962,7 @@ _IO_new_file_seekoff (FILE *fp, off64_t offset, int dir, int mode)
       break;
     case _IO_seek_end:
       {
-	struct stat64 st;
+	struct __stat64_t64 st;
 	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
 	  {
 	    offset += st.st_size;
@@ -1145,7 +1145,7 @@ libc_hidden_def (_IO_file_seek)
 int
 _IO_file_stat (FILE *fp, void *st)
 {
-  return __fstat64 (fp->_fileno, (struct stat64 *) st);
+  return __fstat64_time64 (fp->_fileno, (struct __stat64_t64 *) st);
 }
 libc_hidden_def (_IO_file_stat)
 
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index ed235360ad..ed3c98bd6d 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -487,7 +487,7 @@ _IO_old_file_seekoff (FILE *fp, off64_t offset, int dir, int mode)
       break;
     case _IO_seek_end:
       {
-	struct stat64 st;
+	struct __stat64_t64 st;
 	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
 	  {
 	    offset += st.st_size;
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 5d23566171..37f44780f8 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -840,7 +840,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
       break;
     case _IO_seek_end:
       {
-	struct stat64 st;
+	struct __stat64_t64 st;
 	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
 	  {
 	    offset += st.st_size;
diff --git a/locale/loadarchive.c b/locale/loadarchive.c
index 4177fc8972..512769eaec 100644
--- a/locale/loadarchive.c
+++ b/locale/loadarchive.c
@@ -78,7 +78,7 @@ static struct archmapped *archmapped;
    ARCHMAPPED points to this; if mapping the archive header failed,
    then headmap.ptr is null.  */
 static struct archmapped headmap;
-static struct stat64 archive_stat; /* stat of archive when header mapped.  */
+static struct __stat64_t64 archive_stat; /* stat of archive when header mapped.  */
 
 /* Record of locales that we have already loaded from the archive.  */
 struct locale_in_archive
@@ -207,7 +207,7 @@ _nl_load_locale_from_archive (int category, const char **namep)
 	/* Cannot open the archive, for whatever reason.  */
 	return NULL;
 
-      if (__fstat64 (fd, &archive_stat) == -1)
+      if (__fstat64_time64 (fd, &archive_stat) == -1)
 	{
 	  /* stat failed, very strange.  */
 	close_and_out:
@@ -396,7 +396,7 @@ _nl_load_locale_from_archive (int category, const char **namep)
 	  /* Open the file if it hasn't happened yet.  */
 	  if (fd == -1)
 	    {
-	      struct stat64 st;
+	      struct __stat64_t64 st;
 	      fd = __open_nocancel (archfname,
 				    O_RDONLY|O_LARGEFILE|O_CLOEXEC);
 	      if (fd == -1)
@@ -405,7 +405,7 @@ _nl_load_locale_from_archive (int category, const char **namep)
 	      /* Now verify we think this is really the same archive file
 		 we opened before.  If it has been changed we cannot trust
 		 the header we read previously.  */
-	      if (__fstat64 (fd, &st) < 0
+	      if (__fstat64_time64 (fd, &st) < 0
 		  || st.st_size != archive_stat.st_size
 		  || st.st_mtime != archive_stat.st_mtime
 		  || st.st_dev != archive_stat.st_dev
diff --git a/locale/loadlocale.c b/locale/loadlocale.c
index 9c03490883..f4e6cc9fc2 100644
--- a/locale/loadlocale.c
+++ b/locale/loadlocale.c
@@ -167,7 +167,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
 {
   int fd;
   void *filedata;
-  struct stat64 st;
+  struct __stat64_t64 st;
   struct __locale_data *newdata;
   int save_err;
   int alloc = ld_mapped;
@@ -180,7 +180,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
     /* Cannot open the file.  */
     return;
 
-  if (__builtin_expect (__fstat64 (fd, &st), 0) < 0)
+  if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0))
     {
     puntfd:
       __close_nocancel_nostatus (fd);
@@ -206,7 +206,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
       if (__builtin_expect (fd, 0) < 0)
 	return;
 
-      if (__builtin_expect (__fstat64 (fd, &st), 0) < 0)
+      if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0))
 	goto puntfd;
     }
 
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 462504d828..06ba7476e5 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -324,8 +324,8 @@ __nscd_get_mapping (request_type type, const char *key,
 
   if (__glibc_unlikely (n == keylen))
     {
-      struct stat64 st;
-      if (__builtin_expect (__fstat64 (mapfd, &st) != 0, 0)
+      struct __stat64_t64 st;
+      if (__glibc_unlikely (__fstat64_time64 (mapfd, &st) != 0)
 	  || __builtin_expect (st.st_size < sizeof (struct database_pers_head),
 			       0))
 	goto out_close;
diff --git a/nss/nss_database.c b/nss/nss_database.c
index 1e11294406..ab121cb371 100644
--- a/nss/nss_database.c
+++ b/nss/nss_database.c
@@ -394,7 +394,7 @@ nss_database_check_reload_and_get (struct nss_database_state *local,
                                    nss_action_list *result,
                                    enum nss_database database_index)
 {
-  struct stat64 str;
+  struct __stat64_t64 str;
 
   /* Acquire MO is needed because the thread that sets reload_disabled
      may have loaded the configuration first, so synchronize with the
@@ -424,7 +424,7 @@ nss_database_check_reload_and_get (struct nss_database_state *local,
      errors here are very unlikely, but the chance that we're entering
      a container is also very unlikely, so we err on the side of both
      very unlikely things not happening at the same time.  */
-  if (__stat64 ("/", &str) != 0
+  if (__stat64_time64 ("/", &str) != 0
       || (local->root_ino != 0
 	  && (str.st_ino != local->root_ino
 	      ||  str.st_dev != local->root_dev)))
diff --git a/sysdeps/posix/dl-fileid.h b/sysdeps/posix/dl-fileid.h
index 0bb6794dbe..bf437f3d71 100644
--- a/sysdeps/posix/dl-fileid.h
+++ b/sysdeps/posix/dl-fileid.h
@@ -32,9 +32,9 @@ struct r_file_id
 static inline bool
 _dl_get_file_id (int fd, struct r_file_id *id)
 {
-  struct stat64 st;
+  struct __stat64_t64 st;
 
-  if (__glibc_unlikely (__fstat64 (fd, &st) < 0))
+  if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0))
     return false;
 
   id->dev = st.st_dev;
diff --git a/sysdeps/posix/euidaccess.c b/sysdeps/posix/euidaccess.c
index 26ebb432a2..86f3285471 100644
--- a/sysdeps/posix/euidaccess.c
+++ b/sysdeps/posix/euidaccess.c
@@ -119,7 +119,7 @@ int group_member ();
 int
 euidaccess (const char *path, int mode)
 {
-  struct stat64 stats;
+  struct __stat64_t64 stats;
   int granted;
 
 #ifdef	_LIBC
@@ -140,7 +140,7 @@ euidaccess (const char *path, int mode)
     return access (path, mode);
 #endif
 
-  if (__stat64 (path, &stats))
+  if (__stat64_time64 (path, &stats))
     return -1;
 
   mode &= (X_OK | W_OK | R_OK);	/* Clear any bogus bits. */
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index b7e1aee80f..b2831508c4 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1636,16 +1636,17 @@ static int gaiconf_reload_flag_ever_set;
 /* Last modification time.  */
 #ifdef _STATBUF_ST_NSEC
 
-static struct timespec gaiconf_mtime;
+static struct __timespec64 gaiconf_mtime;
 
 static inline void
-save_gaiconf_mtime (const struct stat64 *st)
+save_gaiconf_mtime (const struct __stat64_t64 *st)
 {
-  gaiconf_mtime = st->st_mtim;
+  gaiconf_mtime = (struct __timespec64) { .tv_sec  = st->st_mtim.tv_sec,
+					  .tv_nsec = st->st_mtim.tv_nsec };
 }
 
 static inline bool
-check_gaiconf_mtime (const struct stat64 *st)
+check_gaiconf_mtime (const struct __stat64_t64 *st)
 {
   return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
           && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
@@ -1656,13 +1657,13 @@ check_gaiconf_mtime (const struct stat64 *st)
 static time_t gaiconf_mtime;
 
 static inline void
-save_gaiconf_mtime (const struct stat64 *st)
+save_gaiconf_mtime (const struct __stat64_t64 *st)
 {
   gaiconf_mtime = st->st_mtime;
 }
 
 static inline bool
-check_gaiconf_mtime (const struct stat64 *st)
+check_gaiconf_mtime (const struct __stat64_t64 *st)
 {
   return st->st_mtime == gaiconf_mtime;
 }
@@ -1777,8 +1778,8 @@ gaiconf_init (void)
   FILE *fp = fopen (GAICONF_FNAME, "rce");
   if (fp != NULL)
     {
-      struct stat64 st;
-      if (__fstat64 (fileno (fp), &st) != 0)
+      struct __stat64_t64 st;
+      if (__fstat64_time64 (fileno (fp), &st) != 0)
 	{
 	  fclose (fp);
 	  goto no_file;
@@ -2130,8 +2131,8 @@ gaiconf_init (void)
 static void
 gaiconf_reload (void)
 {
-  struct stat64 st;
-  if (__stat64 (GAICONF_FNAME, &st) != 0
+  struct __stat64_t64 st;
+  if (__stat64_time64 (GAICONF_FNAME, &st) != 0
       || !check_gaiconf_mtime (&st))
     gaiconf_init ();
 }
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index f11644aae7..13680026ff 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -183,7 +183,7 @@ __getcwd_generic (char *buf, size_t size)
   ino_t rootino, thisino;
   char *dir;
   register char *dirp;
-  struct stat64 st;
+  struct __stat64_t64 st;
   size_t allocated = size;
   size_t used;
 
@@ -249,12 +249,12 @@ __getcwd_generic (char *buf, size_t size)
   dirp = dir + allocated;
   *--dirp = '\0';
 
-  if (__lstat64 (".", &st) < 0)
+  if (__lstat64_time64 (".", &st) < 0)
     goto lose;
   thisdev = st.st_dev;
   thisino = st.st_ino;
 
-  if (__lstat64 ("/", &st) < 0)
+  if (__lstat64_time64 ("/", &st) < 0)
     goto lose;
   rootdev = st.st_dev;
   rootino = st.st_ino;
@@ -276,12 +276,12 @@ __getcwd_generic (char *buf, size_t size)
       if (fd < 0)
         goto lose;
       fd_needs_closing = true;
-      parent_status = __fstat64 (fd, &st);
+      parent_status = __fstat64_time64 (fd, &st);
 #else
       dotlist[dotlen++] = '.';
       dotlist[dotlen++] = '.';
       dotlist[dotlen] = '\0';
-      parent_status = __lstat64 (dotlist, &st);
+      parent_status = __lstat64_time64 (dotlist, &st);
 #endif
       if (parent_status != 0)
         goto lose;
@@ -353,7 +353,8 @@ __getcwd_generic (char *buf, size_t size)
           {
             int entry_status;
 #if HAVE_OPENAT_SUPPORT
-            entry_status = __fstatat64 (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
+            entry_status = __fstatat64_time64 (fd, d->d_name, &st,
+					       AT_SYMLINK_NOFOLLOW);
 #else
             /* Compute size needed for this file name, or for the file
                name ".." in the same directory, whichever is larger.
@@ -390,7 +391,7 @@ __getcwd_generic (char *buf, size_t size)
               }
 
             memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
-            entry_status = __lstat64 (dotlist, &st);
+            entry_status = __lstat64_time64 (dotlist, &st);
 #endif
             /* We don't fail here if we cannot stat() a directory entry.
                This can happen when (network) file systems fail.  If this
diff --git a/sysdeps/posix/pathconf.c b/sysdeps/posix/pathconf.c
index 9eb17d1536..89fcfad49d 100644
--- a/sysdeps/posix/pathconf.c
+++ b/sysdeps/posix/pathconf.c
@@ -129,9 +129,9 @@ __pathconf (const char *path, int name)
 #ifdef	_POSIX_ASYNC_IO
       {
 	/* AIO is only allowed on regular files and block devices.  */
-	struct stat64 st;
+	struct __stat64_t64 st;
 
-	if (__stat64 (path, &st) < 0
+	if (__stat64_time64 (path, &st) < 0
 	    || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode)))
 	  return -1;
 	else
diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c
index 54d6046d00..3e8ec5cd51 100644
--- a/sysdeps/posix/sysconf.c
+++ b/sysdeps/posix/sysconf.c
@@ -1215,8 +1215,8 @@ __sysconf_check_spec (const char *spec)
 		   "/POSIX_V6_", sizeof ("/POSIX_V6_") - 1),
 	  spec, speclen + 1);
 
-  struct stat64 st;
-  long int ret = __stat64 (name, &st) >= 0 ? 1 : -1;
+  struct __stat64_t64 st;
+  long int ret = __stat64_time64 (name, &st) >= 0 ? 1 : -1;
 
   __set_errno (save_errno);
   return ret;
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 5f804b38d7..ff38f1e31f 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -55,14 +55,14 @@
 #include <time.h>
 
 #if _LIBC
-# define struct_stat64 struct stat64
+# define struct_stat64 struct __stat64_t64
 # define __secure_getenv __libc_secure_getenv
 #else
 # define struct_stat64 struct stat
 # define __gen_tempname gen_tempname
 # define __mkdir mkdir
 # define __open open
-# define __lstat64(file, buf) lstat (file, buf)
+# define __lstat64_time64(file, buf) lstat (file, buf)
 # define __stat64(file, buf) stat (file, buf)
 # define __getrandom getrandom
 # define __clock_gettime64 clock_gettime
@@ -99,7 +99,7 @@ static int
 direxists (const char *dir)
 {
   struct_stat64 buf;
-  return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
+  return __stat64_time64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
 }
 
 /* Path search algorithm, for tmpnam, tmpfile, etc.  If DIR is
@@ -191,7 +191,7 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
 {
   struct_stat64 st;
 
-  if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW)
+  if (__lstat64_time64 (tmpl, &st) == 0 || errno == EOVERFLOW)
     __set_errno (EEXIST);
   return errno == ENOENT ? 0 : -1;
 }
diff --git a/sysdeps/unix/sysv/linux/fdopendir.c b/sysdeps/unix/sysv/linux/fdopendir.c
index ede43f2485..32ec10e206 100644
--- a/sysdeps/unix/sysv/linux/fdopendir.c
+++ b/sysdeps/unix/sysv/linux/fdopendir.c
@@ -27,9 +27,9 @@
 DIR *
 __fdopendir (int fd)
 {
-  struct stat64 statbuf;
+  struct __stat64_t64 statbuf;
 
-  if (__builtin_expect (__fstat64 (fd, &statbuf), 0) < 0)
+  if (__glibc_unlikely (__fstat64_time64 (fd, &statbuf) < 0))
     return NULL;
   if (__glibc_unlikely (! S_ISDIR (statbuf.st_mode)))
     {
diff --git a/sysdeps/unix/sysv/linux/fexecve.c b/sysdeps/unix/sysv/linux/fexecve.c
index df25c2acb8..4dfcaeedc1 100644
--- a/sysdeps/unix/sysv/linux/fexecve.c
+++ b/sysdeps/unix/sysv/linux/fexecve.c
@@ -58,8 +58,8 @@ fexecve (int fd, char *const argv[], char *const envp[])
 
   /* We come here only if the 'execve' call fails.  Determine whether
      /proc is mounted.  If not we return ENOSYS.  */
-  struct stat64 st;
-  if (__stat64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
+  struct __stat64_t64 st;
+  if (__stat64_time64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
     save = ENOSYS;
 
   __set_errno (save);
diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c
index 4020a826f9..48f254d169 100644
--- a/sysdeps/unix/sysv/linux/opendir.c
+++ b/sysdeps/unix/sysv/linux/opendir.c
@@ -49,8 +49,8 @@ opendir_tail (int fd)
   /* Now make sure this really is a directory and nothing changed since the
      `stat' call.  The S_ISDIR check is superfluous if O_DIRECTORY works,
      but it's cheap and we need the stat call for st_blksize anyway.  */
-  struct stat64 statbuf;
-  if (__glibc_unlikely (__fstat64 (fd, &statbuf) < 0))
+  struct __stat64_t64 statbuf;
+  if (__glibc_unlikely (__fstat64_time64 (fd, &statbuf) < 0))
     goto lose;
   if (__glibc_unlikely (! S_ISDIR (statbuf.st_mode)))
     {
@@ -88,7 +88,8 @@ __opendir (const char *name)
 weak_alias (__opendir, opendir)
 
 DIR *
-__alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
+__alloc_dir (int fd, bool close_fd, int flags,
+	     const struct __stat64_t64 *statp)
 {
   /* We have to set the close-on-exit flag if the user provided the
      file descriptor.  */
diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c
index f37e8aaf68..b599a66c93 100644
--- a/sysdeps/unix/sysv/linux/pathconf.c
+++ b/sysdeps/unix/sysv/linux/pathconf.c
@@ -65,9 +65,10 @@ distinguish_extX (const struct statfs *fsbuf, const char *file, int fd)
 {
   char buf[64];
   char path[PATH_MAX];
-  struct stat64 st;
+  struct __stat64_t64 st;
 
-  if ((file == NULL ? __fstat64 (fd, &st) : __stat64 (file, &st)) != 0)
+  if ((file == NULL ? __fstat64_time64 (fd, &st)
+		    : __stat64_time64 (file, &st)) != 0)
     /* Strange.  The statfd call worked, but stat fails.  Default to
        the more pessimistic value.  */
     return EXT2_LINK_MAX;
diff --git a/sysdeps/unix/sysv/linux/ttyname.h b/sysdeps/unix/sysv/linux/ttyname.h
index 0a0048cc02..5dcbfef973 100644
--- a/sysdeps/unix/sysv/linux/ttyname.h
+++ b/sysdeps/unix/sysv/linux/ttyname.h
@@ -25,24 +25,18 @@
    linux/Documentation/devices.txt (on linux < 4.10) or
    linux/Documentation/admin-guide/devices.txt (on linux >= 4.10).  */
 static inline bool
-is_pty (struct stat64 *sb)
+is_pty (struct __stat64_t64 *sb)
 {
-#ifdef _STATBUF_ST_RDEV
   int m = __gnu_dev_major (sb->st_rdev);
   return (136 <= m && m <= 143);
-#else
-  return false;
-#endif
 }
 
 static inline bool
-is_mytty (const struct stat64 *mytty, const struct stat64 *maybe)
+is_mytty (const struct __stat64_t64 *mytty, const struct __stat64_t64 *maybe)
 {
   return (maybe->st_ino == mytty->st_ino
 	  && maybe->st_dev == mytty->st_dev
-#ifdef _STATBUF_ST_RDEV
 	  && S_ISCHR (maybe->st_mode)
 	  && maybe->st_rdev == mytty->st_rdev
-#endif
 	  );
 }
diff --git a/sysdeps/unix/sysv/linux/ttyname_r.c b/sysdeps/unix/sysv/linux/ttyname_r.c
index 899a851a83..9ef9f42883 100644
--- a/sysdeps/unix/sysv/linux/ttyname_r.c
+++ b/sysdeps/unix/sysv/linux/ttyname_r.c
@@ -31,15 +31,15 @@
 #include "ttyname.h"
 
 static int getttyname_r (char *buf, size_t buflen,
-			 const struct stat64 *mytty, int save,
+			 const struct __stat64_t64 *mytty, int save,
 			 int *dostat);
 
 static int
 attribute_compat_text_section
-getttyname_r (char *buf, size_t buflen, const struct stat64 *mytty,
+getttyname_r (char *buf, size_t buflen, const struct __stat64_t64 *mytty,
 	      int save, int *dostat)
 {
-  struct stat64 st;
+  struct __stat64_t64 st;
   DIR *dirstream;
   struct dirent64 *d;
   size_t devlen = strlen (buf);
@@ -71,7 +71,7 @@ getttyname_r (char *buf, size_t buflen, const struct stat64 *mytty,
 	cp = __stpncpy (buf + devlen, d->d_name, needed);
 	cp[0] = '\0';
 
-	if (__stat64 (buf, &st) == 0
+	if (__stat64_time64 (buf, &st) == 0
 	    && is_mytty (mytty, &st))
 	  {
 	    (void) __closedir (dirstream);
@@ -93,7 +93,7 @@ int
 __ttyname_r (int fd, char *buf, size_t buflen)
 {
   struct fd_to_filename filename;
-  struct stat64 st, st1;
+  struct __stat64_t64 st, st1;
   int dostat = 0;
   int doispty = 0;
   int save = errno;
@@ -118,7 +118,7 @@ __ttyname_r (int fd, char *buf, size_t buflen)
   if (__glibc_unlikely (__tcgetattr (fd, &term) < 0))
     return errno;
 
-  if (__fstat64 (fd, &st) < 0)
+  if (__fstat64_time64 (fd, &st) < 0)
     return errno;
 
   /* We try using the /proc filesystem.  */
@@ -144,7 +144,7 @@ __ttyname_r (int fd, char *buf, size_t buflen)
 
       /* Verify readlink result, fall back on iterating through devices.  */
       if (buf[0] == '/'
-	  && __stat64 (buf, &st1) == 0
+	  && __stat64_time64 (buf, &st1) == 0
 	  && is_mytty (&st, &st1))
 	return 0;
 
@@ -155,7 +155,7 @@ __ttyname_r (int fd, char *buf, size_t buflen)
   memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/"));
   buflen -= sizeof ("/dev/pts/") - 1;
 
-  if (__stat64 (buf, &st1) == 0 && S_ISDIR (st1.st_mode))
+  if (__stat64_time64 (buf, &st1) == 0 && S_ISDIR (st1.st_mode))
     {
       ret = getttyname_r (buf, buflen, &st, save,
 			  &dostat);
diff --git a/sysvipc/ftok.c b/sysvipc/ftok.c
index 2e39c74415..bd633bd395 100644
--- a/sysvipc/ftok.c
+++ b/sysvipc/ftok.c
@@ -22,10 +22,10 @@
 key_t
 ftok (const char *pathname, int proj_id)
 {
-  struct stat64 st;
+  struct __stat64_t64 st;
   key_t key;
 
-  if (__stat64 (pathname, &st) < 0)
+  if (__stat64_time64 (pathname, &st) < 0)
     return (key_t) -1;
 
   key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16)
diff --git a/time/tzfile.c b/time/tzfile.c
index 040a5e341f..4377018a55 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -150,9 +150,9 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
     }
 
   /* If we were already using tzfile, check whether the file changed.  */
-  struct stat64 st;
+  struct __stat64_t64 st;
   if (was_using_tzfile
-      && __stat64 (file, &st) == 0
+      && __stat64_time64 (file, &st) == 0
       && tzfile_ino == st.st_ino && tzfile_dev == st.st_dev
       && tzfile_mtime == st.st_mtime)
     goto done;  /* Nothing to do.  */
@@ -164,7 +164,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
     goto ret_free_transitions;
 
   /* Get information about the file we are actually using.  */
-  if (__fstat64 (__fileno (f), &st) != 0)
+  if (__fstat64_time64 (__fileno (f), &st) != 0)
     goto lose;
 
   free ((void *) transitions);
-- 
2.30.2


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

* [PATCH 02/18] Use LFS and 64 bit time for installed programs
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
  2021-06-17 11:50 ` [PATCH 01/18] Use 64 bit time_t stat internally Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-17 12:19   ` Andreas Schwab
  2021-06-17 20:49   ` Joseph Myers
  2021-06-17 11:50 ` [PATCH 03/18] support: Add support_create_timer Adhemerval Zanella
                   ` (16 subsequent siblings)
  18 siblings, 2 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

The installed programs are built with a combination of different
values for MODULE_NAME, as below.  To enable both Long File Support
and 64 bt time, -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 is added for
nonlib, nscd, lddlibc4, ldconfig, locale_programs, and iconvprogs
modules.

  nscd/nscd
    nscd/nscd.o                           MODULE_NAME=nscd
    nscd/connections.o                    MODULE_NAME=nscd
    nscd/pwdcache.o                       MODULE_NAME=nscd
    nscd/getpwnam_r.o                     MODULE_NAME=nscd
    nscd/getpwuid_r.o                     MODULE_NAME=nscd
    nscd/grpcache.o                       MODULE_NAME=nscd
    nscd/getgrnam_r.o                     MODULE_NAME=nscd
    nscd/getgrgid_r.o                     MODULE_NAME=nscd
    nscd/hstcache.o                       MODULE_NAME=nscd
    nscd/gethstbyad_r.o                   MODULE_NAME=nscd
    nscd/gethstbynm3_r.o                  MODULE_NAME=nscd
    nscd/getsrvbynm_r.o                   MODULE_NAME=nscd
    nscd/getsrvbypt_r.o                   MODULE_NAME=nscd
    nscd/servicescache.o                  MODULE_NAME=nscd
    nscd/dbg_log.o                        MODULE_NAME=nscd
    nscd/nscd_conf.o                      MODULE_NAME=nscd
    nscd/nscd_stat.o                      MODULE_NAME=nscd
    nscd/cache.o                          MODULE_NAME=nscd
    nscd/mem.o                            MODULE_NAME=nscd
    nscd/nscd_setup_thread.o              MODULE_NAME=nscd
    nscd/xmalloc.o                        MODULE_NAME=nscd
    nscd/xstrdup.o                        MODULE_NAME=nscd
    nscd/aicache.o                        MODULE_NAME=nscd
    nscd/initgrcache.o                    MODULE_NAME=nscd
    nscd/gai.o                            MODULE_NAME=nscd
    nscd/res_hconf.o                      MODULE_NAME=nscd
    nscd/netgroupcache.o                  MODULE_NAME=nscd
    nscd/cachedumper.o                    MODULE_NAME=nscd
  elf/lddlibc4
    elf/lddlibc4                          MODULE_NAME=lddlibc4
  elf/pldd
    elf/pldd.o                            MODULE_NAME=nonlib
    elf/xmalloc.o                         MODULE_NAME=nonlib
  elf/sln
    elf/sln.o                             MODULE_NAME=nonlib
    elf/static-stubs.o                    MODULE_NAME=nonlib
  elf/sprof                               MODULE_NAME=nonlib
  elf/ldconfig
    elf/ldconfig.o                        MODULE_NAME=ldconfig
    elf/cache.o                           MODULE_NAME=nonlib
    elf/readlib.o                         MODULE_NAME=nonlib
    elf/xmalloc.o                         MODULE_NAME=nonlib
    elf/xstrdup.o                         MODULE_NAME=nonlib
    elf/chroot_canon.o                    MODULE_NAME=nonlib
    elf/static-stubs.o                    MODULE_NAME=nonlib
    elf/stringtable.o                     MODULE_NAME=nonlib
  io/pwd
    io/pwd.o                              MODULE_NAME=nonlib
  locale/locale
    locale/locale.o                       MODULE_NAME=locale_programs
    locale/locale-spec.o                  MODULE_NAME=locale_programs
    locale/charmap-dir.o                  MODULE_NAME=locale_programs
    locale/simple-hash.o                  MODULE_NAME=locale_programs
    locale/xmalloc.o                      MODULE_NAME=locale_programs
    locale/xstrdup.o                      MODULE_NAME=locale_programs
    locale/record-status.o                MODULE_NAME=locale_programs
    locale/xasprintf.o                    MODULE_NAME=locale_programs
  locale/localedef
    locale/localedef.o                    MODULE_NAME=locale_programs
    locale/ld-ctype.o                     MODULE_NAME=locale_programs
    locale/ld-messages.o                  MODULE_NAME=locale_programs
    locale/ld-monetary.o                  MODULE_NAME=locale_programs
    locale/ld-numeric.o                   MODULE_NAME=locale_programs
    locale/ld-time.o                      MODULE_NAME=locale_programs
    locale/ld-paper.o                     MODULE_NAME=locale_programs
    locale/ld-name.o                      MODULE_NAME=locale_programs
    locale/ld-address.o                   MODULE_NAME=locale_programs
    locale/ld-telephone.o                 MODULE_NAME=locale_programs
    locale/ld-measurement.o               MODULE_NAME=locale_programs
    locale/ld-identification.o            MODULE_NAME=locale_programs
    locale/ld-collate.o                   MODULE_NAME=locale_programs
    locale/charmap.o                      MODULE_NAME=locale_programs
    locale/linereader.o                   MODULE_NAME=locale_programs
    locale/locfile.o                      MODULE_NAME=locale_programs
    locale/repertoire.o                   MODULE_NAME=locale_programs
    locale/locarchive.o                   MODULE_NAME=locale_programs
    locale/md5.o                          MODULE_NAME=locale_programs
    locale/charmap-dir.o                  MODULE_NAME=locale_programs
    locale/simple-hash.o                  MODULE_NAME=locale_programs
    locale/xmalloc.o                      MODULE_NAME=locale_programs
    locale/xstrdup.o                      MODULE_NAME=locale_programs
    locale/record-status.o                MODULE_NAME=locale_programs
    locale/xasprintf.o                    MODULE_NAME=locale_programs
  catgets/gencat
    catgets/gencat.o                      MODULE_NAME=nonlib
    catgets/xmalloc.o                     MODULE_NAME=nonlib
  nss/makedb
    nss/makedb.o                          MODULE_NAME=nonlib
    nss/xmalloc.o                         MODULE_NAME=nonlib
    nss/hash-string.o                     MODULE_NAME=nonlib
  nss/getent
    nss/getent.o                          MODULE_NAME=nonlib
  posix/getconf
    posix/getconf.o                       MODULE_NAME=nonlib
  login/utmpdump
    login/utmpdump.o                      MODULE_NAME=nonlib
  debug/pcprofiledump
    debug/pcprofiledump.o                 MODULE_NAME=nonlib
  timezone/zic
    timezone/zic.o                        MODULE_NAME=nonlib
  timezone/zdump
    timezone/zdump.o                      MODULE_NAME=nonlib
  iconv/iconv_prog
    iconv/iconv_prog.o                    MODULE_NAME=nonlib
    iconv/iconv_charmap.o                 MODULE_NAME=iconvprogs
    iconv/charmap.o                       MODULE_NAME=iconvprogs
    iconv/charmap-dir.o                   MODULE_NAME=iconvprogs
    iconv/linereader.o                    MODULE_NAME=iconvprogs
    iconv/dummy-repertoire.o              MODULE_NAME=iconvprogs
    iconv/simple-hash.o                   MODULE_NAME=iconvprogs
    iconv/xstrdup.o                       MODULE_NAME=iconvprogs
    iconv/xmalloc.o                       MODULE_NAME=iconvprogs
    iconv/record-status.o                 MODULE_NAME=iconvprogs
  iconv/iconvconfig
    iconv/iconvconfig.o                   MODULE_NAME=nonlib
    iconv/strtab.o                        MODULE_NAME=iconvprogs
    iconv/xmalloc.o                       MODULE_NAME=iconvprogs
    iconv/hash-string.o                   MODULE_NAME=iconvprogs

Also, to avoid addinf both LFS and 64 bit time support on internal
tests they are moved to a newer 'testsuite-internal' module.  It
should be similar to 'nonlib' regarding internal definition and
linking namespace.

This patch also enables LFS and 64 bit support of libsupport container
programs (echo-container, test-container, shell-container, and
true-container).

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 Makeconfig          |  8 ++++++--
 Makerules           | 12 ++++++++++--
 locale/localeinfo.h |  2 +-
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/Makeconfig b/Makeconfig
index 6482a43025..de30ba3fa6 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -851,6 +851,10 @@ endif
 # -fno-math-errno.
 +extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno)
 
+# Use 64 bit time_t support for installed programs
++extra-time-flags = $(if $(filter nonlib nscd lddlibc4 ldconfig locale_programs iconvprogs,\
+                           $(in-module)),-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64)
+
 # We might want to compile with some stack-protection flag.
 ifneq ($(stack-protector),)
 +stack-protector=$(stack-protector)
@@ -951,7 +955,7 @@ libio-include = -I$(..)libio
 built-modules = iconvprogs iconvdata ldconfig lddlibc4 libmemusage \
 		libSegFault libpcprofile librpcsvc locale-programs \
 		memusagestat nonlib nscd extramodules libnldbl libsupport \
-		testsuite
+		testsuite testsuite-internal
 
 in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \
 				    $(libof-$(<F)) \
@@ -991,7 +995,7 @@ endif
 
 override CFLAGS	= -std=gnu11 -fgnu89-inline $(config-extra-cflags) \
 		  $(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \
-		  $(+extra-math-flags) \
+		  $(+extra-math-flags) $(+extra-time-flags) \
 		  $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \
 		  $(CFLAGS-$(@F)) $(tls-model) \
 		  $(foreach lib,$(libof-$(basename $(@F))) \
diff --git a/Makerules b/Makerules
index 12f1a5cb50..770a573134 100644
--- a/Makerules
+++ b/Makerules
@@ -1313,14 +1313,22 @@ lib := testsuite
 include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
 endif
 
-all-nonlib := $(strip $(tests-internal) $(test-internal-extras) \
-		      $(others) $(others-extras))
+all-nonlib := $(strip $(others) $(others-extras))
 ifneq (,$(all-nonlib))
 cpp-srcs-left = $(all-nonlib)
 lib := nonlib
 include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
 endif
 
+# All internal tests use testsuite-internal module since for 64 bit time
+# support is set as default for MODULE_NAME=nonlib (which include some
+# installed programs.
+all-testsuite-internal := $(strip $(tests-internal) $(test-internal-extras))
+ifneq (,$(all-testsuite-internal))
+cpp-srcs-left = $(all-testsuite-internal)
+lib := testsuite-internal
+include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
+endif
 
 ifeq ($(build-shared),yes)
 # Generate normalized lists of symbols, versions, and data sizes.
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index b3d4da0185..9e53681829 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -50,7 +50,7 @@ struct __locale_data
 {
   const char *name;
   const char *filedata;		/* Region mapping the file data.  */
-  off_t filesize;		/* Size of the file (and the region).  */
+  __off_t filesize;		/* Size of the file (and the region).  */
   enum				/* Flavor of storage used for those.  */
   {
     ld_malloced,		/* Both are malloc'd.  */
-- 
2.30.2


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

* [PATCH 03/18] support: Add support_create_timer
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
  2021-06-17 11:50 ` [PATCH 01/18] Use 64 bit time_t stat internally Adhemerval Zanella
  2021-06-17 11:50 ` [PATCH 02/18] Use LFS and 64 bit time for installed programs Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:42   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 04/18] linux: Only use 64-bit syscall if required for ppoll Adhemerval Zanella
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

It is a simple wrapper over timer_create, timer_settime, and
sigaction.  It will be used to check for large timeout to trigger an
EINTR.
---
 support/Makefile               |  1 +
 support/support.h              | 11 ++++++
 support/support_create_timer.c | 69 ++++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)
 create mode 100644 support/support_create_timer.c

diff --git a/support/Makefile b/support/Makefile
index f3ebaa8d2e..278f4627d8 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -50,6 +50,7 @@ libsupport-routines = \
   support_chroot \
   support_copy_file \
   support_copy_file_range \
+  support_create_timer \
   support_descriptor_supports_holes \
   support_descriptors \
   support_enter_mount_namespace \
diff --git a/support/support.h b/support/support.h
index 874204b7fc..9ec8ecb8d7 100644
--- a/support/support.h
+++ b/support/support.h
@@ -24,6 +24,7 @@
 #define SUPPORT_H
 
 #include <stdbool.h>
+#include <stdint.h>
 #include <stddef.h>
 #include <sys/cdefs.h>
 /* For mode_t.  */
@@ -153,6 +154,16 @@ extern bool support_select_modifies_timeout (void);
    tv_usec larger than 1000000.  */
 extern bool support_select_normalizes_timeout (void);
 
+/* Create a timer that trigger after SEC seconds and NSEC nanoseconds.  If
+   REPEAT is true the timer will repeat indefinitely.  If CALLBACK is not
+   NULL, the function will be called when the timer expires; otherwise a
+   dummy empty function is used instead.
+   This is implemented with POSIX per-process timer with SIGEV_SIGNAL.  */
+timer_t support_create_timer (uint64_t sec, long int nsec, bool repeat,
+			      void (*callback)(int));
+/* Disable the timer TIMER.  */
+void support_delete_timer (timer_t timer);
+
 __END_DECLS
 
 #endif /* SUPPORT_H */
diff --git a/support/support_create_timer.c b/support/support_create_timer.c
new file mode 100644
index 0000000000..c93aaa5c6b
--- /dev/null
+++ b/support/support_create_timer.c
@@ -0,0 +1,69 @@
+/* Create a periodic timer.
+   Copyright (C) 2021 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 <support/check.h>
+#include <support/support.h>
+#include <support/xsignal.h>
+#include <time.h>
+
+static void
+dummy_alrm_handler (int sig)
+{
+}
+
+timer_t
+support_create_timer (uint64_t sec, long int nsec, bool repeat,
+		      void (*callback)(int))
+{
+  struct sigaction sa;
+  sa.sa_handler = callback != NULL ? callback : dummy_alrm_handler;
+  sigemptyset (&sa.sa_mask);
+  sa.sa_flags = 0;
+  xsigaction (SIGALRM, &sa, NULL);
+
+  struct sigevent ev = {
+    .sigev_notify = SIGEV_SIGNAL,
+    .sigev_signo = SIGALRM
+  };
+  timer_t timerid;
+  int r = timer_create (CLOCK_REALTIME, &ev, &timerid);
+  if (r == -1)
+    FAIL_EXIT1 ("timer_create: %m");
+
+  /* Single timer with 0.1s.  */
+  struct itimerspec its =
+    {
+      { .tv_sec = repeat ? sec : 0, .tv_nsec = repeat ? nsec : 0 },
+      { .tv_sec = sec, .tv_nsec = nsec }
+    };
+  r = timer_settime (timerid, 0, &its, NULL);
+  if (r == -1)
+    FAIL_EXIT1 ("timer_settime: %m");
+
+  return timerid;
+}
+
+/* Disable the timer TIMER.  */
+void
+support_delete_timer (timer_t timer)
+{
+  int r = timer_delete (timer);
+  if (r == -1)
+    FAIL_EXIT1 ("timer_delete: %m");
+  xsignal (SIGALRM, SIG_DFL);
+}
-- 
2.30.2


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

* [PATCH 04/18] linux: Only use 64-bit syscall if required for ppoll
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 03/18] support: Add support_create_timer Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:42   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 05/18] linux: Only use 64-bit syscall if required for pselect Adhemerval Zanella
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.  This also avoids the need
to use supports_time64() (which breaks the usage case of live migration
like CRIU or similar).

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/Makefile    |  9 +++++++
 sysdeps/unix/sysv/linux/ppoll.c     | 41 +++++++++++------------------
 sysdeps/unix/sysv/linux/tst-ppoll.c | 15 +++++++++++
 3 files changed, 40 insertions(+), 25 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 294c366e3b..c36ea0e494 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -137,6 +137,15 @@ tests-time64 += \
 
 CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
 
+ifeq (yes,$(build-shared))
+librt = $(common-objpfx)rt/librt.so
+else
+librt = $(common-objpfx)rt/librt.a
+endif
+
+$(objpfx)tst-ppoll: $(librt)
+$(objpfx)tst-ppoll-time64: $(librt)
+
 # Generate the list of SYS_* macros for the system calls (__NR_*
 # macros).  The file syscall-names.list contains all possible system
 # call names, and the generated header file produces SYS_* macros for
diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index 624f14f517..e1ad316e2e 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -21,9 +21,6 @@
 #include <time.h>
 #include <sys/poll.h>
 #include <sysdep-cancel.h>
-#include <kernel-features.h>
-#include <time64-support.h>
-
 
 int
 __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
@@ -38,40 +35,34 @@ __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
+
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
+			 __NSIG_BYTES);
+#else
+  bool is32bit = timeout != NULL
+		 ? in_time_t_range (timeout->tv_sec) : true;
+  int ret;
+  if (!is32bit)
+    {
       ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
 			    __NSIG_BYTES);
-
       if (ret == 0 || errno != ENOSYS)
 	return ret;
-
-      mark_time64_unsupported ();
+      __set_errno (EOVERFLOW);
+      return -1;
     }
 
-#ifndef __ASSUME_TIME64_SYSCALLS
   struct timespec ts32;
-  if (timeout)
-    {
-      if (! in_time_t_range (timeout->tv_sec))
-        {
-          __set_errno (EOVERFLOW);
-          return -1;
-        }
-
-      ts32 = valid_timespec64_to_timespec (*timeout);
-    }
+  if (timeout != NULL)
+    ts32 = valid_timespec64_to_timespec (*timeout);
 
-  ret = SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL, sigmask,
-			__NSIG_BYTES);
+  return SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL, sigmask,
+			 __NSIG_BYTES);
 #endif
-
-  return ret;
 }
 
 #if __TIMESIZE != 64
diff --git a/sysdeps/unix/sysv/linux/tst-ppoll.c b/sysdeps/unix/sysv/linux/tst-ppoll.c
index 9fe6ad07ce..e21e2fcc72 100644
--- a/sysdeps/unix/sysv/linux/tst-ppoll.c
+++ b/sysdeps/unix/sysv/linux/tst-ppoll.c
@@ -19,9 +19,11 @@
 #include <time.h>
 #include <poll.h>
 #include <errno.h>
+#include <intprops.h>
 #include <support/check.h>
 #include <support/xtime.h>
 #include <support/timespec.h>
+#include <support/support.h>
 #include <stdbool.h>
 
 static int test_ppoll_timeout (bool zero_tmo)
@@ -41,6 +43,16 @@ static int test_ppoll_timeout (bool zero_tmo)
   return 0;
 }
 
+static void
+test_ppoll_large_timeout (void)
+{
+  support_create_timer (0, 100000000, false, NULL);
+  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
+  struct pollfd fds = { -1, 0, 0 };
+  TEST_COMPARE (ppoll (&fds, 1, &ts, 0), -1);
+  TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+}
+
 static int
 do_test (void)
 {
@@ -50,6 +62,9 @@ do_test (void)
   /* Check if ppoll exits after specified timeout.  */
   test_ppoll_timeout (false);
 
+  /* Check if ppoll with large timeout.  */
+  test_ppoll_large_timeout ();
+
   return 0;
 }
 
-- 
2.30.2


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

* [PATCH 05/18] linux: Only use 64-bit syscall if required for pselect
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 04/18] linux: Only use 64-bit syscall if required for ppoll Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:42   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 06/18] linux: Only use 64-bit syscall if required for select Adhemerval Zanella
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.  This also avoids the need
to use supports_time64() (which breaks the usage case of live migration
like CRIU or similar).

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 misc/Makefile                                 |   9 ++
 misc/tst-pselect.c                            | 120 ++++++++----------
 .../unix/sysv/linux/microblaze/pselect32.c    |   3 +-
 sysdeps/unix/sysv/linux/pselect.c             |  47 ++++---
 sysdeps/unix/sysv/linux/pselect32.c           |   6 -
 5 files changed, 95 insertions(+), 90 deletions(-)

diff --git a/misc/Makefile b/misc/Makefile
index f34ab09fe3..fa40bf0e11 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -148,6 +148,12 @@ CFLAGS-brk.op = $(no-stack-protector)
 
 include ../Rules
 
+ifeq (yes,$(build-shared))
+librt = $(common-objpfx)rt/librt.so
+else
+librt = $(common-objpfx)rt/librt.a
+endif
+
 $(objpfx)libg.a: $(dep-dummy-lib); $(make-dummy-lib)
 
 $(objpfx)tst-tsearch: $(libm)
@@ -162,3 +168,6 @@ tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace
 $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
 	$(evaluate-test)
+
+$(objpfx)tst-pselect: $(librt)
+$(objpfx)tst-pselect-time64: $(librt)
diff --git a/misc/tst-pselect.c b/misc/tst-pselect.c
index c89176b058..f8c404c275 100644
--- a/misc/tst-pselect.c
+++ b/misc/tst-pselect.c
@@ -16,14 +16,14 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/select.h>
-#include <sys/wait.h>
+#include <intprops.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xsignal.h>
+#include <support/xunistd.h>
+#include <support/xtime.h>
 #include <stdlib.h>
 
-
 static volatile int handler_called;
 
 static void
@@ -33,59 +33,43 @@ handler (int sig)
 }
 
 
-static int
-do_test (void)
+static void
+test_pselect_basic (void)
 {
   struct sigaction sa;
   sa.sa_handler = handler;
   sa.sa_flags = 0;
   sigemptyset (&sa.sa_mask);
 
-  if (sigaction (SIGUSR1, &sa, NULL) != 0)
-    {
-      puts ("sigaction failed");
-      return 1;
-    }
+  xsigaction (SIGUSR1, &sa, NULL);
 
   sa.sa_handler = SIG_IGN;
-  if (sigaction (SIGCHLD, &sa, NULL) != 0)
-    {
-      puts ("2nd sigaction failed");
-      return 1;
-    }
+  xsigaction (SIGCHLD, &sa, NULL);
 
   sigset_t ss_usr1;
   sigemptyset (&ss_usr1);
   sigaddset (&ss_usr1, SIGUSR1);
-  if (sigprocmask (SIG_BLOCK, &ss_usr1, NULL) != 0)
-    {
-      puts ("sigprocmask failed");
-      return 1;
-    }
+  TEST_COMPARE (sigprocmask (SIG_BLOCK, &ss_usr1, NULL), 0);
 
   int fds[2][2];
-
-  if (pipe (fds[0]) != 0 || pipe (fds[1]) != 0)
-    {
-      puts ("pipe failed");
-      return 1;
-    }
+  xpipe (fds[0]);
+  xpipe (fds[1]);
 
   fd_set rfds;
   FD_ZERO (&rfds);
 
   sigset_t ss;
-  sigprocmask (SIG_SETMASK, NULL, &ss);
+  TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0);
   sigdelset (&ss, SIGUSR1);
 
   struct timespec to = { .tv_sec = 0, .tv_nsec = 500000000 };
 
   pid_t parent = getpid ();
-  pid_t p = fork ();
+  pid_t p = xfork ();
   if (p == 0)
     {
-      close (fds[0][1]);
-      close (fds[1][0]);
+      xclose (fds[0][1]);
+      xclose (fds[1][0]);
 
       FD_SET (fds[0][0], &rfds);
 
@@ -93,55 +77,63 @@ do_test (void)
       do
 	{
 	  if (getppid () != parent)
-	    exit (2);
+	    FAIL_EXIT1 ("getppid()=%d != parent=%d", getppid(), parent);
 
 	  errno = 0;
 	  e = pselect (fds[0][0] + 1, &rfds, NULL, NULL, &to, &ss);
 	}
       while (e == 0);
 
-      if (e != -1)
-	{
-	  puts ("child: pselect did not fail");
-	  return 0;
-	}
-      if (errno != EINTR)
-	{
-	  puts ("child: pselect did not set errno to EINTR");
-	  return 0;
-	}
+      TEST_COMPARE (e, -1);
+      TEST_COMPARE (errno, EINTR);
 
       TEMP_FAILURE_RETRY (write (fds[1][1], "foo", 3));
 
       exit (0);
     }
 
-  close (fds[0][0]);
-  close (fds[1][1]);
+  xclose (fds[0][0]);
+  xclose (fds[1][1]);
 
   FD_SET (fds[1][0], &rfds);
 
-  kill (p, SIGUSR1);
+  TEST_COMPARE (kill (p, SIGUSR1), 0);
 
   int e = pselect (fds[1][0] + 1, &rfds, NULL, NULL, NULL, &ss);
-  if (e == -1)
-    {
-      puts ("parent: pselect failed");
-      return 1;
-    }
-  if (e != 1)
-    {
-      puts ("parent: pselect did not report readable fd");
-      return 1;
-    }
-  if (!FD_ISSET (fds[1][0], &rfds))
-    {
-      puts ("parent: pselect reports wrong fd");
-      return 1;
-    }
+  TEST_COMPARE (e, 1);
+  TEST_VERIFY (FD_ISSET (fds[1][0], &rfds));
+}
+
+static void
+test_pselect_large_timeout (void)
+{
+  support_create_timer (0, 100000000, false, NULL);
+
+  int fds[2];
+  xpipe (fds);
+
+  fd_set rfds;
+  FD_ZERO (&rfds);
+  FD_SET (fds[0], &rfds);
+
+  sigset_t ss;
+  TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0);
+  sigdelset (&ss, SIGALRM);
+
+  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
+
+  TEST_COMPARE (pselect (fds[0] + 1, &rfds, NULL, NULL, &ts, &ss), -1);
+  TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+}
+
+static int
+do_test (void)
+{
+  test_pselect_basic ();
+
+  test_pselect_large_timeout ();
 
   return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/microblaze/pselect32.c b/sysdeps/unix/sysv/linux/microblaze/pselect32.c
index a4f436462b..70b7b52a48 100644
--- a/sysdeps/unix/sysv/linux/microblaze/pselect32.c
+++ b/sysdeps/unix/sysv/linux/microblaze/pselect32.c
@@ -35,8 +35,7 @@ __pselect32 (int nfds, fd_set *readfds, fd_set *writefds,
   struct timeval tv32, *ptv32 = NULL;
   if (timeout != NULL)
     {
-      if (! in_time_t_range (timeout->tv_sec)
-	  || ! valid_nanoseconds (timeout->tv_nsec))
+      if (! valid_nanoseconds (timeout->tv_nsec))
 	{
 	  __set_errno (EINVAL);
 	  return -1;
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index 5e8a0cc2dc..79e8584ea7 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -18,7 +18,23 @@
 
 #include <sys/select.h>
 #include <sysdep-cancel.h>
-#include <time64-support.h>
+
+static int
+pselect64_syscall (int nfds, fd_set *readfds, fd_set *writefds,
+		   fd_set *exceptfds, const struct __timespec64 *timeout,
+		   const sigset_t *sigmask)
+{
+#ifndef __NR_pselect6_time64
+# define __NR_pselect6_time64 __NR_pselect6
+#endif
+  /* NB: This is required by ARGIFY used in x32 internal_syscallN.  */
+  __syscall_ulong_t data[2] =
+    {
+      (uintptr_t) sigmask, __NSIG_BYTES
+    };
+  return SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
+			 timeout, data);
+}
 
 int
 __pselect64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
@@ -37,30 +53,25 @@ __pselect64 (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.  */
-
-#ifndef __NR_pselect6_time64
-# define __NR_pselect6_time64 __NR_pselect6
-#endif
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return pselect64_syscall (nfds, readfds, writefds, exceptfds, timeout,
+			    sigmask);
+#else
+  bool is32bit = timeout != NULL
+		 ? in_time_t_range (timeout->tv_sec) : true;
   int r;
-  if (supports_time64 ())
+  if (!is32bit)
     {
-      /* NB: This is required by ARGIFY used in x32 internal_syscallN.  */
-      __syscall_ulong_t data[2] =
-	{
-	  (uintptr_t) sigmask, __NSIG_BYTES
-	};
-      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
-			  timeout, data);
+      r = pselect64_syscall (nfds, readfds, writefds, exceptfds, timeout,
+			     sigmask);
       if (r == 0 || errno != ENOSYS)
 	return r;
-
-      mark_time64_unsupported ();
+      __set_errno (EOVERFLOW);
+      return -1;
     }
 
-#ifndef __ASSUME_TIME64_SYSCALLS
-  r = __pselect32 (nfds, readfds, writefds, exceptfds, timeout, sigmask);
+  return __pselect32 (nfds, readfds, writefds, exceptfds, timeout, sigmask);
 #endif
-  return r;
 }
 
 #if __TIMESIZE != 64
diff --git a/sysdeps/unix/sysv/linux/pselect32.c b/sysdeps/unix/sysv/linux/pselect32.c
index eb59b51cdf..48724d8727 100644
--- a/sysdeps/unix/sysv/linux/pselect32.c
+++ b/sysdeps/unix/sysv/linux/pselect32.c
@@ -29,12 +29,6 @@ __pselect32 (int nfds, fd_set *readfds, fd_set *writefds,
   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;
     }
-- 
2.30.2


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

* [PATCH 06/18] linux: Only use 64-bit syscall if required for select
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 05/18] linux: Only use 64-bit syscall if required for pselect Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:43   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 07/18] linux: Remove supports_time64 () from clock_getres Adhemerval Zanella
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.  This also avoids the need
to use supports_time64() (which breaks the usage case of live migration
like CRIU or similar).

It also fixes an issue on 32-bit select call for !__ASSUME_PSELECT
(microblase with older kernels only) where the expected timeout
is a 'struct timeval' instead of 'struct timespec'.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 include/sys/select.h               |  5 +++
 misc/Makefile                      |  2 +
 misc/tst-select.c                  | 39 +++++++++++--------
 sysdeps/unix/sysv/linux/Makefile   |  2 +-
 sysdeps/unix/sysv/linux/select.c   | 60 ++++++++++--------------------
 sysdeps/unix/sysv/linux/select32.c | 58 +++++++++++++++++++++++++++++
 6 files changed, 109 insertions(+), 57 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/select32.c

diff --git a/include/sys/select.h b/include/sys/select.h
index ec073deeba..a8961afbed 100644
--- a/include/sys/select.h
+++ b/include/sys/select.h
@@ -21,6 +21,11 @@ extern int __pselect32 (int __nfds, fd_set *__readfds,
 			const struct __timespec64 *__timeout,
 			const __sigset_t *__sigmask)
   attribute_hidden;
+extern int __select32 (int __nfds, fd_set *__readfds,
+		       fd_set *__writefds, fd_set *__exceptfds,
+		       const struct __timespec64 *ts64,
+		       struct __timeval64 *timeout)
+  attribute_hidden;
 
 extern int __select64 (int __nfds, fd_set *__readfds,
 		       fd_set *__writefds, fd_set *__exceptfds,
diff --git a/misc/Makefile b/misc/Makefile
index fa40bf0e11..66586bcc7e 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -169,5 +169,7 @@ $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
 	$(evaluate-test)
 
+$(objpfx)tst-select: $(librt)
+$(objpfx)tst-select-time64: $(librt)
 $(objpfx)tst-pselect: $(librt)
 $(objpfx)tst-pselect-time64: $(librt)
diff --git a/misc/tst-select.c b/misc/tst-select.c
index 52aa26651f..134eed99be 100644
--- a/misc/tst-select.c
+++ b/misc/tst-select.c
@@ -17,6 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
+#include <intprops.h>
 #include <support/capture_subprocess.h>
 #include <support/check.h>
 #include <support/support.h>
@@ -31,12 +32,6 @@ struct child_args
   struct timeval tmo;
 };
 
-static void
-alarm_handler (int signum)
-{
-  /* Do nothing.  */
-}
-
 static void
 do_test_child (void *clousure)
 {
@@ -69,17 +64,20 @@ do_test_child (void *clousure)
 static void
 do_test_child_alarm (void *clousure)
 {
-  struct sigaction act = { .sa_handler = alarm_handler };
-  xsigaction (SIGALRM, &act, NULL);
-  alarm (1);
+  struct child_args *args = (struct child_args *) clousure;
 
-  struct timeval tv = { .tv_sec = 10, .tv_usec = 0 };
+  support_create_timer (0, 100000000, false, NULL);
+  struct timeval tv = { .tv_sec = args->tmo.tv_sec, .tv_usec = 0 };
   int r = select (0, NULL, NULL, NULL, &tv);
   TEST_COMPARE (r, -1);
-  TEST_COMPARE (errno, EINTR);
-
-  if (support_select_modifies_timeout ())
-    TEST_VERIFY (tv.tv_sec < 10);
+  if (args->tmo.tv_sec > INT_MAX)
+    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+  else
+    {
+      TEST_COMPARE (errno, EINTR);
+      if (support_select_modifies_timeout ())
+       TEST_VERIFY (tv.tv_sec < args->tmo.tv_sec);
+    }
 }
 
 static int
@@ -121,13 +119,24 @@ do_test (void)
   xclose (args.fds[0][0]);
   xclose (args.fds[1][1]);
 
+  args.tmo = (struct timeval) { .tv_sec = 10, .tv_usec = 0 };
+  {
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (do_test_child_alarm, &args);
+    support_capture_subprocess_check (&result, "tst-select-child", 0,
+				      sc_allow_none);
+  }
+
+  args.tmo = (struct timeval) { .tv_sec = TYPE_MAXIMUM (time_t),
+				.tv_usec = 0 };
   {
     struct support_capture_subprocess result;
-    result = support_capture_subprocess (do_test_child_alarm, NULL);
+    result = support_capture_subprocess (do_test_child_alarm, &args);
     support_capture_subprocess_check (&result, "tst-select-child", 0,
 				      sc_allow_none);
   }
 
+  args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
   {
     fd_set rfds;
     FD_ZERO (&rfds);
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index c36ea0e494..710169a454 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 pselect32 \
+		   time64-support pselect32 select32 \
 		   xstat fxstat lxstat xstat64 fxstat64 lxstat64 \
 		   fxstatat fxstatat64 \
 		   xmknod xmknodat convert_scm_timestamps
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index dc16a816ed..2d2a7fa720 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -21,7 +21,6 @@
 #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
@@ -65,53 +64,32 @@ __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 #ifndef __NR_pselect6_time64
 # define __NR_pselect6_time64 __NR_pselect6
 #endif
+
+#ifdef __ASSUME_TIME64_SYSCALLS
+  int r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
+			  pts64, NULL);
+  if (timeout != NULL)
+    TIMESPEC_TO_TIMEVAL (timeout, pts64);
+  return r;
+#else
+  bool is32bit = timeout != NULL
+		 ? in_time_t_range (timeout->tv_sec) : true;
   int r;
-  if (supports_time64 ())
+  if (!is32bit)
     {
-      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.  */
-      if (r >= 0 || errno != ENOSYS)
+      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds,
+			      exceptfds, pts64, NULL);
+      if ((r >= 0 || errno != ENOSYS) && timeout != NULL)
 	{
-	  if (timeout != NULL)
-	    TIMESPEC_TO_TIMEVAL (timeout, &ts64);
-	  return r;
+	  TIMESPEC_TO_TIMEVAL (timeout, &ts64);
 	}
-
-      mark_time64_unsupported ();
+      else
+	__set_errno (EOVERFLOW);
+      return r;
     }
 
-#ifndef __ASSUME_TIME64_SYSCALLS
-  struct timespec ts32, *pts32 = NULL;
-  if (pts64 != NULL)
-    {
-      if (! in_time_t_range (pts64->tv_sec))
-	{
-	  __set_errno (EINVAL);
-	  return -1;
-	}
-      ts32.tv_sec = s;
-      ts32.tv_nsec = ns;
-      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 (timeout != NULL)
-    *timeout = valid_timespec_to_timeval64 (ts32);
+  return __select32 (nfds, readfds, writefds, exceptfds, pts64, timeout);
 #endif
-
-  return r;
 }
 
 #if __TIMESIZE != 64
diff --git a/sysdeps/unix/sysv/linux/select32.c b/sysdeps/unix/sysv/linux/select32.c
new file mode 100644
index 0000000000..b7e122fe2c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/select32.c
@@ -0,0 +1,58 @@
+/* Synchronous I/O multiplexing.  Linux 32-bit time fallback.
+   Copyright (C) 2020-2021 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
+__select32 (int nfds, fd_set *readfds, fd_set *writefds,
+	    fd_set *exceptfds, const struct __timespec64 *ts64,
+	    struct __timeval64 *timeout)
+{
+#ifdef __ASSUME_PSELECT
+  struct timespec ts32, *pts32 = NULL;
+  if (ts64 != NULL)
+    {
+      ts32.tv_sec = ts64->tv_sec;
+      ts32.tv_nsec = ts64->tv_nsec;
+      pts32 = &ts32;
+    }
+
+  int r = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, pts32,
+			  NULL);
+  if (timeout != NULL)
+    TIMESPEC_TO_TIMEVAL (timeout, pts32);
+  return r;
+#else
+  struct timeval tv32, *ptv32 = NULL;
+  if (ts64 != NULL)
+    {
+      tv32 = valid_timespec64_to_timeval (*ts64);
+      ptv32 = &tv32;
+    }
+
+  int r = SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, ptv32);
+  if (timeout != NULL)
+    *timeout = valid_timeval_to_timeval64 (tv32);
+  return r;
+#endif /* __ASSUME_PSELECT  */
+}
+
+#endif
-- 
2.30.2


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

* [PATCH 07/18] linux: Remove supports_time64 () from clock_getres
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (5 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 06/18] linux: Only use 64-bit syscall if required for select Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:43   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 08/18] linux: Remove supports_time64 () from clock_gettime Adhemerval Zanella
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

It breaks the usage case of live migration like CRIU or similar.
The performance drawback is it would require an extra syscall
on older kernels without 64-bit time support.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/clock_getres.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index a9edec93e6..83f0593074 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -21,7 +21,6 @@
 #include <time.h>
 
 #include <sysdep-vdso.h>
-#include <time64-support.h>
 #include <shlib-compat.h>
 #include <kernel-features.h>
 
@@ -34,19 +33,14 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
 #ifndef __NR_clock_getres_time64
 # define __NR_clock_getres_time64 __NR_clock_getres
 #endif
-  if (supports_time64 ())
-    {
+
 #ifdef HAVE_CLOCK_GETRES64_VSYSCALL
-      r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
+  r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
 #else
-      r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
+  r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
 #endif
-
-      if (r == 0 || errno != ENOSYS)
-	return r;
-
-      mark_time64_unsupported ();
-    }
+  if (r == 0 || errno != ENOSYS)
+    return r;
 
 #ifndef __ASSUME_TIME64_SYSCALLS
   /* Fallback code that uses 32-bit support.  */
-- 
2.30.2


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

* [PATCH 08/18] linux: Remove supports_time64 () from clock_gettime
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (6 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 07/18] linux: Remove supports_time64 () from clock_getres Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:43   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 09/18] linux: Remove time64-support Adhemerval Zanella
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

It breaks the usage case of live migration like CRIU or similar.
The performance drawback is it would require an extra syscall
on older kernels without 64-bit time support.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/clock_gettime.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index 781d05c2fd..cfe9370455 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -22,7 +22,6 @@
 #include <time.h>
 #include "kernel-posix-cpu-timers.h"
 #include <sysdep-vdso.h>
-#include <time64-support.h>
 #include <shlib-compat.h>
 
 /* Get current value of CLOCK and store it in TP.  */
@@ -35,19 +34,14 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
 # define __NR_clock_gettime64 __NR_clock_gettime
 #endif
 
-  if (supports_time64 ())
-    {
 #ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
-      r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
+  r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
 #else
-      r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
+  r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
 #endif
 
-      if (r == 0 || errno != ENOSYS)
-	return r;
-
-      mark_time64_unsupported ();
-   }
+  if (r == 0 || errno != ENOSYS)
+    return r;
 
 #ifndef __ASSUME_TIME64_SYSCALLS
   /* Fallback code that uses 32-bit support.  */
-- 
2.30.2


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

* [PATCH 09/18] linux: Remove time64-support
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (7 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 08/18] linux: Remove supports_time64 () from clock_gettime Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:43   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 10/18] linux: timerfd_gettime minor cleanup Adhemerval Zanella
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

It breaks the usage case of live migration like CRIU or similar
and most usages can be optimized away by either building glibc with
a minimum 5.1 kernel or by using the 32-bit syscall for the common
case.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/Makefile         |  2 +-
 sysdeps/unix/sysv/linux/time64-support.c | 23 --------
 sysdeps/unix/sysv/linux/time64-support.h | 70 ------------------------
 3 files changed, 1 insertion(+), 94 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/time64-support.c
 delete mode 100644 sysdeps/unix/sysv/linux/time64-support.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 710169a454..982755f980 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 pselect32 select32 \
+		   pselect32 select32 \
 		   xstat fxstat lxstat xstat64 fxstat64 lxstat64 \
 		   fxstatat fxstatat64 \
 		   xmknod xmknodat convert_scm_timestamps
diff --git a/sysdeps/unix/sysv/linux/time64-support.c b/sysdeps/unix/sysv/linux/time64-support.c
deleted file mode 100644
index 0718e7421b..0000000000
--- a/sysdeps/unix/sysv/linux/time64-support.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Auxiliary definitions for 64-bit time_t support.
-   Copyright (C) 2020-2021 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 <time64-support.h>
-
-#ifndef __ASSUME_TIME64_SYSCALLS
-int __time64_support = 1;
-#endif
diff --git a/sysdeps/unix/sysv/linux/time64-support.h b/sysdeps/unix/sysv/linux/time64-support.h
deleted file mode 100644
index 8466d37f8f..0000000000
--- a/sysdeps/unix/sysv/linux/time64-support.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Auxiliary definitions for 64-bit time_t support.
-   Copyright (C) 2020-2021 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 <stdbool.h>
-#include <atomic.h>
-
-/* These helper functions are used to optimize the 64-bit time_t support on
-   configurations that requires support for 32-bit time_t fallback
-   (!__ASSUME_TIME64_SYSCALLS).  The idea is once the kernel advertises that
-   it does not have 64-bit time_t support, glibc will stop to try issue the
-   64-bit time_t syscall altogether.
-
-   For instance:
-
-     #ifndef __NR_symbol_time64
-     # define __NR_symbol_time64 __NR_symbol
-     #endif
-     int r;
-     if (supports_time64 ())
-       {
-         r = INLINE_SYSCALL_CALL (symbol, ...);
-         if (r == 0 || errno != ENOSYS)
-	   return r;
-
-         mark_time64_unsupported ();
-       }
-     #ifndef __ASSUME_TIME64_SYSCALLS
-     <32-bit fallback syscall>
-     #endif
-     return r;
-
-   On configuration with default 64-bit time_t this optimization should be
-   optimized away by the compiler resulting in no overhead.  */
-
-#ifndef __ASSUME_TIME64_SYSCALLS
-extern int __time64_support attribute_hidden;
-#endif
-
-static inline bool
-supports_time64 (void)
-{
-#ifdef __ASSUME_TIME64_SYSCALLS
-  return true;
-#else
-  return atomic_load_relaxed (&__time64_support) != 0;
-#endif
-}
-
-static inline void
-mark_time64_unsupported (void)
-{
-#ifndef __ASSUME_TIME64_SYSCALLS
-  atomic_store_relaxed (&__time64_support, 0);
-#endif
-}
-- 
2.30.2


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

* [PATCH 10/18] linux: timerfd_gettime minor cleanup
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (8 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 09/18] linux: Remove time64-support Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:43   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 11/18] linux: Only use 64-bit syscall if required for semtimedop Adhemerval Zanella
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

The __NR_timerfd_gettime64 is always defined.
---
 sysdeps/unix/sysv/linux/timerfd_gettime.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/timerfd_gettime.c b/sysdeps/unix/sysv/linux/timerfd_gettime.c
index 89f8066b91..5f668257c4 100644
--- a/sysdeps/unix/sysv/linux/timerfd_gettime.c
+++ b/sysdeps/unix/sysv/linux/timerfd_gettime.c
@@ -25,17 +25,17 @@
 int
 __timerfd_gettime64 (int fd, struct __itimerspec64 *value)
 {
+#ifndef __NR_timerfd_gettime64
+# define __NR_timerfd_gettime64 __NR_timerfd_gettime
+#endif
+
 #ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_timerfd_gettime64
-#  define __NR_timerfd_gettime64 __NR_timerfd_gettime
-# endif
   return INLINE_SYSCALL_CALL (timerfd_gettime64, fd, value);
 #else
-# ifdef __NR_timerfd_gettime64
   int ret = INLINE_SYSCALL_CALL (timerfd_gettime64, fd, value);
   if (ret == 0 || errno != ENOSYS)
     return ret;
-# endif
+
   struct itimerspec its32;
   int retval = INLINE_SYSCALL_CALL (timerfd_gettime, fd, &its32);
   if (retval == 0)
-- 
2.30.2


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

* [PATCH 11/18] linux: Only use 64-bit syscall if required for semtimedop
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (9 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 10/18] linux: timerfd_gettime minor cleanup Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:43   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 12/18] linux: Only use 64-bit syscall if required for timerfd_settime Adhemerval Zanella
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/semtimedop.c | 54 ++++++++++++++++------------
 sysvipc/Makefile                     |  9 +++++
 sysvipc/test-sysvsem.c               | 22 +++++++++---
 3 files changed, 57 insertions(+), 28 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/semtimedop.c b/sysdeps/unix/sysv/linux/semtimedop.c
index b732b6db48..65a8c080f7 100644
--- a/sysdeps/unix/sysv/linux/semtimedop.c
+++ b/sysdeps/unix/sysv/linux/semtimedop.c
@@ -21,44 +21,52 @@
 #include <sysdep.h>
 #include <errno.h>
 
+static int
+semtimedop_syscall (int semid, struct sembuf *sops, size_t nsops,
+		    const struct __timespec64 *timeout)
+{
+#ifdef __NR_semtimedop_time64
+  return INLINE_SYSCALL_CALL (semtimedop_time64, semid, sops, nsops, timeout);
+#elif 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
+}
+
 /* Perform user-defined atomical operation of array of semaphores.  */
 int
 __semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
 		const struct __timespec64 *timeout)
 {
-  int r;
-#if defined __NR_semtimedop_time64
-  r = INLINE_SYSCALL_CALL (semtimedop_time64, semid, sops, nsops, timeout);
-#elif defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS && defined __NR_semtimedop
-  r = INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, timeout);
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return semtimedop_syscall (semid, sops, nsops, timeout);
 #else
-  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;
+  bool is32bit = timeout != NULL
+		 ? in_time_t_range (timeout->tv_sec) : true;
+  if (!is32bit)
+    {
+      int r = semtimedop_syscall (semid, sops, nsops, timeout);
+      if (r == 0 || errno != ENOSYS)
+	return r;
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
 
   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);
+# ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+  return INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, pts32);
 # else
-  r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
-			   SEMTIMEDOP_IPC_ARGS (nsops, sops, pts32));
+  return INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
+			      SEMTIMEDOP_IPC_ARGS (nsops, sops, pts32));
 # endif
-#endif /* __ASSUME_TIME64_SYSCALLS  */
-  return r;
+#endif
 }
 #if __TIMESIZE != 64
 libc_hidden_def (__semtimedop64)
diff --git a/sysvipc/Makefile b/sysvipc/Makefile
index 86911803b5..d2acb6a70b 100644
--- a/sysvipc/Makefile
+++ b/sysvipc/Makefile
@@ -38,3 +38,12 @@ include ../Rules
 
 CFLAGS-msgrcv.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-msgsnd.c += -fexceptions -fasynchronous-unwind-tables
+
+ifeq (yes,$(build-shared))
+librt = $(common-objpfx)rt/librt.so
+else
+librt = $(common-objpfx)rt/librt.a
+endif
+
+$(objpfx)test-sysvsem: $(librt)
+$(objpfx)test-sysvsem-time64: $(librt)
diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c
index 092418205d..d9034c3dae 100644
--- a/sysvipc/test-sysvsem.c
+++ b/sysvipc/test-sysvsem.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <intprops.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -30,6 +31,8 @@
 #include <support/support.h>
 #include <support/check.h>
 #include <support/temp_file.h>
+#include <support/xtime.h>
+#include <support/xsignal.h>
 
 /* These are for the temporary file we generate.  */
 static char *name;
@@ -112,11 +115,20 @@ do_test (void)
 #ifdef _GNU_SOURCE
   /* Set a time for half a second.  The semaphore operation should timeout
      with EAGAIN.  */
-  struct timespec ts = { 0 /* sec */, 500000000 /* nsec */ };
-  if (semtimedop (semid, &sb2, 1, &ts) != -1
-      || (errno != EAGAIN && errno != ENOSYS))
-    FAIL_EXIT1 ("semtimedop succeed or returned errno != {EAGAIN,ENOSYS} "
-		"(errno=%i)", errno);
+  {
+    struct timespec ts = { 0 /* sec */, 500000000 /* nsec */ };
+    if (semtimedop (semid, &sb2, 1, &ts) != -1
+        || (errno != EAGAIN && errno != ENOSYS))
+      FAIL_EXIT1 ("semtimedop succeed or returned errno != {EAGAIN,ENOSYS} "
+		  "(errno=%i)", errno);
+  }
+
+  {
+    support_create_timer (0, 100000000, false, NULL);
+    struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
+    TEST_COMPARE (semtimedop (semid, &sb2, 1, &ts), -1);
+    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+  }
 #endif
 
   /* Finally free up the semnaphore resource.  */
-- 
2.30.2


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

* [PATCH 12/18] linux: Only use 64-bit syscall if required for timerfd_settime
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (10 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 11/18] linux: Only use 64-bit syscall if required for semtimedop Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:44   ` Lukasz Majewski
  2021-06-17 11:50 ` [PATCH 13/18] linux: Only use 64-bit syscall if required for mq_timedreceive Adhemerval Zanella
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/Makefile          |  2 ++
 sysdeps/unix/sysv/linux/timerfd_settime.c | 25 ++++++++++---------
 sysdeps/unix/sysv/linux/tst-timerfd.c     | 29 +++++++++++++++++++++--
 3 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 982755f980..2e5b5e1dc4 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -145,6 +145,8 @@ endif
 
 $(objpfx)tst-ppoll: $(librt)
 $(objpfx)tst-ppoll-time64: $(librt)
+$(objpfx)tst-timerfd: $(librt)
+$(objpfx)tst-timerfd-time64: $(librt)
 
 # Generate the list of SYS_* macros for the system calls (__NR_*
 # macros).  The file syscall-names.list contains all possible system
diff --git a/sysdeps/unix/sysv/linux/timerfd_settime.c b/sysdeps/unix/sysv/linux/timerfd_settime.c
index 0dd6fa026e..8f08133a73 100644
--- a/sysdeps/unix/sysv/linux/timerfd_settime.c
+++ b/sysdeps/unix/sysv/linux/timerfd_settime.c
@@ -29,31 +29,34 @@ __timerfd_settime64 (int fd, int flags, const struct __itimerspec64 *value,
 #ifndef __NR_timerfd_settime64
 # define __NR_timerfd_settime64 __NR_timerfd_settime
 #endif
-  int ret = INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags, value, ovalue);
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (ret == 0 || errno != ENOSYS)
-    return ret;
 
-  if (! in_time_t_range ((value->it_value).tv_sec)
-      || ! in_time_t_range ((value->it_interval).tv_sec))
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags, value, ovalue);
+#else
+  bool is32bit_value = in_time_t_range (value->it_value.tv_sec);
+  bool is32bit_interval = in_time_t_range (value->it_interval.tv_sec);
+  if (!is32bit_value || !is32bit_interval)
     {
+      int r = INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags, value,
+				   ovalue);
+      if (r == 0 || errno != ENOSYS)
+	return r;
       __set_errno (EOVERFLOW);
-      return -1;
+      return r;
     }
 
   struct itimerspec its32, oits32;
   its32.it_interval = valid_timespec64_to_timespec (value->it_interval);
   its32.it_value = valid_timespec64_to_timespec (value->it_value);
-
-  ret = INLINE_SYSCALL_CALL (timerfd_settime, fd, flags,
-			     &its32, ovalue ? &oits32 : NULL);
+  int ret = INLINE_SYSCALL_CALL (timerfd_settime, fd, flags,
+				 &its32, ovalue != NULL ? &oits32 : NULL);
   if (ret == 0 && ovalue != NULL)
     {
       ovalue->it_interval = valid_timespec_to_timespec64 (oits32.it_interval);
       ovalue->it_value = valid_timespec_to_timespec64 (oits32.it_value);
     }
-#endif
   return ret;
+#endif
 }
 
 #if __TIMESIZE != 64
diff --git a/sysdeps/unix/sysv/linux/tst-timerfd.c b/sysdeps/unix/sysv/linux/tst-timerfd.c
index 8828399119..27f1263ac6 100644
--- a/sysdeps/unix/sysv/linux/tst-timerfd.c
+++ b/sysdeps/unix/sysv/linux/tst-timerfd.c
@@ -16,15 +16,18 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <errno.h>
+#include <intprops.h>
 #include <time.h>
 #include <support/check.h>
+#include <support/support.h>
 #include <support/xunistd.h>
 #include <support/timespec.h>
 #include <sys/time.h>
 #include <sys/timerfd.h>
 
-static int
-do_test (void)
+static void
+timerfd_test (void)
 {
   struct itimerspec settings = { { 0, 0 }, { 2, 0 } };
   struct itimerspec val;
@@ -52,6 +55,28 @@ do_test (void)
   /* Check difference between timerfd_gettime calls.  */
   TEST_COMPARE (support_timespec_check_in_range
                 ((struct timespec) { 1, 0 }, val.it_value, 0.9, 1.0), 1);
+
+  xclose (fd);
+}
+
+static void
+timerfd_large_timeout (void)
+{
+  int fd = timerfd_create (CLOCK_REALTIME, 0);
+  TEST_VERIFY (fd != -1);
+  support_create_timer (0, 100000000, false, NULL);
+  struct itimerspec it = { { 0, 0 }, { TYPE_MAXIMUM (time_t), 0 } };
+  TEST_COMPARE (timerfd_settime (fd, 0, &it, NULL), 0);
+  uint64_t buf;
+  TEST_COMPARE (read (fd, &buf, sizeof (buf)), -1);
+  TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+}
+
+static int
+do_test (void)
+{
+  timerfd_test ();
+  timerfd_large_timeout ();
   return 0;
 }
 
-- 
2.30.2


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

* [PATCH 13/18] linux: Only use 64-bit syscall if required for mq_timedreceive
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (11 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 12/18] linux: Only use 64-bit syscall if required for timerfd_settime Adhemerval Zanella
@ 2021-06-17 11:50 ` Adhemerval Zanella
  2021-06-21  7:44   ` Lukasz Majewski
  2021-06-17 11:51 ` [PATCH 14/18] linux: Only use 64-bit syscall if required for mq_timedsend Adhemerval Zanella
                   ` (5 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:50 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 rt/Makefile                               |  4 +-
 rt/tst-mqueue10-time64.c                  |  1 +
 rt/tst-mqueue10.c                         | 62 +++++++++++++++++++++++
 sysdeps/unix/sysv/linux/mq_timedreceive.c | 35 +++++++------
 4 files changed, 85 insertions(+), 17 deletions(-)
 create mode 100644 rt/tst-mqueue10-time64.c
 create mode 100644 rt/tst-mqueue10.c

diff --git a/rt/Makefile b/rt/Makefile
index 797f2da51e..3382c7a1d2 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -48,7 +48,8 @@ tests := tst-shm tst-timer tst-timer2 \
 	 tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \
 	 tst-timer3 tst-timer4 tst-timer5 \
 	 tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
-	 tst-shm-cancel
+	 tst-shm-cancel \
+	 tst-mqueue10
 tests-internal := tst-timer-sigmask
 
 tests-time64 := \
@@ -58,6 +59,7 @@ tests-time64 := \
   tst-mqueue2-time64 \
   tst-mqueue4-time64 \
   tst-mqueue8-time64 \
+  tst-mqueue10-time64 \
   tst-timer4-time64
 
 extra-libs := librt
diff --git a/rt/tst-mqueue10-time64.c b/rt/tst-mqueue10-time64.c
new file mode 100644
index 0000000000..2c8a4ae372
--- /dev/null
+++ b/rt/tst-mqueue10-time64.c
@@ -0,0 +1 @@
+#include "tst-mqueue10.c"
diff --git a/rt/tst-mqueue10.c b/rt/tst-mqueue10.c
new file mode 100644
index 0000000000..7fb53a1cae
--- /dev/null
+++ b/rt/tst-mqueue10.c
@@ -0,0 +1,62 @@
+/* Check for large timeout with mq_timedsend and mq_timedreceive.
+   Copyright (C) 2021 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 <errno.h>
+#include <intprops.h>
+#include <mqueue.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <unistd.h>
+
+static char name[sizeof "/tst-mqueue2-" + INT_BUFSIZE_BOUND (pid_t)];
+
+static void
+do_cleanup (void)
+{
+  mq_unlink (name);
+}
+#define CLEANUP_HANDLER	do_cleanup
+
+static int
+do_test (void)
+{
+  snprintf (name, sizeof (name), "/tst-mqueue2-%u", getpid ());
+
+  char msg[8] = { 0x55 };
+
+  struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = sizeof (msg) };
+  mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
+  TEST_VERIFY_EXIT (q != (mqd_t) -1);
+
+  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
+
+  {
+    timer_t timer = support_create_timer (0, 100000000, false, NULL);
+    TEST_COMPARE (mq_timedreceive (q, msg, sizeof (msg), NULL, &ts), -1);
+    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+    support_delete_timer (timer);
+  }
+
+  mq_unlink (name);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c b/sysdeps/unix/sysv/linux/mq_timedreceive.c
index eb948ccc18..8776977daf 100644
--- a/sysdeps/unix/sysv/linux/mq_timedreceive.c
+++ b/sysdeps/unix/sysv/linux/mq_timedreceive.c
@@ -29,30 +29,33 @@ __mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
 #ifndef __NR_mq_timedreceive_time64
 # define __NR_mq_timedreceive_time64 __NR_mq_timedreceive
 #endif
-  int ret = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len,
-                            msg_prio, abs_timeout);
 
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (ret == 0 || errno != ENOSYS)
-    return ret;
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len,
+			 msg_prio, abs_timeout);
+#else
+  bool is32bit = abs_timeout != NULL
+		 ? in_time_t_range (abs_timeout->tv_sec) : true;
+  if (!is32bit)
+    {
+      int r = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len,
+			      msg_prio, abs_timeout);
+      if (r == 0 || errno != ENOSYS)
+	return r;
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
 
-  struct timespec ts32;
+  struct timespec ts32, *pts32 = NULL;
   if (abs_timeout != NULL)
     {
-      if (! in_time_t_range (abs_timeout->tv_sec))
-        {
-          __set_errno (EOVERFLOW);
-          return -1;
-        }
-
       ts32 = valid_timespec64_to_timespec (*abs_timeout);
+      pts32 = &ts32;
     }
 
-  ret = SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio,
-			abs_timeout != NULL ? &ts32 : NULL);
+  return SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio,
+			 pts32);
 #endif
-
-  return ret;
 }
 
 #if __TIMESIZE != 64
-- 
2.30.2


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

* [PATCH 14/18] linux: Only use 64-bit syscall if required for mq_timedsend
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (12 preceding siblings ...)
  2021-06-17 11:50 ` [PATCH 13/18] linux: Only use 64-bit syscall if required for mq_timedreceive Adhemerval Zanella
@ 2021-06-17 11:51 ` Adhemerval Zanella
  2021-06-21  7:44   ` Lukasz Majewski
  2021-06-17 11:51 ` [PATCH 15/18] linux: Only use 64-bit syscall if required for sigtimedwait Adhemerval Zanella
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:51 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 rt/tst-mqueue10.c                      | 10 ++++++++
 sysdeps/unix/sysv/linux/mq_timedsend.c | 35 ++++++++++++++------------
 2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/rt/tst-mqueue10.c b/rt/tst-mqueue10.c
index 7fb53a1cae..18795808e0 100644
--- a/rt/tst-mqueue10.c
+++ b/rt/tst-mqueue10.c
@@ -54,6 +54,16 @@ do_test (void)
     support_delete_timer (timer);
   }
 
+  {
+    timer_t timer = support_create_timer (0, 100000000, false, NULL);
+    /* Fill the internal buffer first.  */
+    TEST_COMPARE (mq_timedsend (q, msg, sizeof (msg), 0,
+				&(struct timespec) { 0, 0 }), 0);
+    TEST_COMPARE (mq_timedsend (q, msg, sizeof (msg), 0, &ts), -1);
+    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+    support_delete_timer (timer);
+  }
+
   mq_unlink (name);
 
   return 0;
diff --git a/sysdeps/unix/sysv/linux/mq_timedsend.c b/sysdeps/unix/sysv/linux/mq_timedsend.c
index 5f14ecb0bf..8fa8c010ad 100644
--- a/sysdeps/unix/sysv/linux/mq_timedsend.c
+++ b/sysdeps/unix/sysv/linux/mq_timedsend.c
@@ -29,30 +29,33 @@ __mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
 # ifndef __NR_mq_timedsend_time64
 #  define __NR_mq_timedsend_time64 __NR_mq_timedsend
 # endif
-  int ret = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len,
-			    msg_prio, abs_timeout);
 
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (ret == 0 || errno != ENOSYS)
-    return ret;
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len,
+			 msg_prio, abs_timeout);
+#else
+  bool is32bit = abs_timeout != NULL
+		 ? in_time_t_range (abs_timeout->tv_sec) : true;
+  if (!is32bit)
+    {
+      int r = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len,
+			      msg_prio, abs_timeout);
+      if (r == 0 || errno != ENOSYS)
+	return r;
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
 
-  struct timespec ts32;
+  struct timespec ts32, *pts32 = NULL;
   if (abs_timeout != NULL)
     {
-      if (! in_time_t_range (abs_timeout->tv_sec))
-        {
-          __set_errno (EOVERFLOW);
-          return -1;
-        }
-
       ts32 = valid_timespec64_to_timespec (*abs_timeout);
+      pts32 = &ts32;
     }
 
-  ret = SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio,
-			abs_timeout != NULL ? &ts32 : NULL);
+  return SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio,
+			 pts32);
 #endif
-
-  return ret;
 }
 
 #if __TIMESIZE != 64
-- 
2.30.2


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

* [PATCH 15/18] linux: Only use 64-bit syscall if required for sigtimedwait
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (13 preceding siblings ...)
  2021-06-17 11:51 ` [PATCH 14/18] linux: Only use 64-bit syscall if required for mq_timedsend Adhemerval Zanella
@ 2021-06-17 11:51 ` Adhemerval Zanella
  2021-06-17 12:25   ` Andreas Schwab
  2021-06-17 11:51 ` [PATCH 16/18] linux: Only use 64-bit syscall if required for utimensat family Adhemerval Zanella
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:51 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/Makefile           |  2 ++
 sysdeps/unix/sysv/linux/sigtimedwait.c     | 26 ++++++++++++++--------
 sysdeps/unix/sysv/linux/tst-sigtimedwait.c | 18 +++++++++++++++
 3 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 2e5b5e1dc4..9a65fc39c0 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -145,6 +145,8 @@ endif
 
 $(objpfx)tst-ppoll: $(librt)
 $(objpfx)tst-ppoll-time64: $(librt)
+$(objpfx)tst-sigtimedwait: $(librt)
+$(objpfx)tst-sigtimedwait-time64: $(librt)
 $(objpfx)tst-timerfd: $(librt)
 $(objpfx)tst-timerfd-time64: $(librt)
 
diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
index 25ed0adb0d..bae9bf44bc 100644
--- a/sysdeps/unix/sysv/linux/sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -25,20 +25,28 @@ __sigtimedwait64 (const sigset_t *set, siginfo_t *info,
 #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)
+  int result;
+#ifdef __ASSUME_TIME64_SYSCALLS
+  result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
+			   __NSIG_BYTES);
+#else
+  bool is32bit = timeout != NULL
+		 ? in_time_t_range (timeout->tv_sec) : true;
+  if (!is32bit)
+    {
+      result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
+			       __NSIG_BYTES);
+      if (result == 0 || errno != ENOSYS)
+	return result;
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+  else
     {
       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;
 	}
diff --git a/sysdeps/unix/sysv/linux/tst-sigtimedwait.c b/sysdeps/unix/sysv/linux/tst-sigtimedwait.c
index 973fb5d301..a8b9893c61 100644
--- a/sysdeps/unix/sysv/linux/tst-sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/tst-sigtimedwait.c
@@ -17,11 +17,13 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <time.h>
+#include <intprops.h>
 #include <errno.h>
 #include <signal.h>
 #include <support/check.h>
 #include <support/xtime.h>
 #include <support/timespec.h>
+#include <support/support.h>
 #include <stdbool.h>
 
 static int
@@ -47,6 +49,20 @@ test_sigtimedwait_timeout (bool zero_tmo)
   return 0;
 }
 
+static void
+test_sigtimedwait_large_timeout (void)
+{
+  support_create_timer (0, 100000000, false, NULL);
+  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
+
+  sigset_t ss_usr1;
+  sigemptyset (&ss_usr1);
+  sigaddset (&ss_usr1, SIGUSR1);
+
+  TEST_COMPARE (sigtimedwait (&ss_usr1, NULL, &ts), -1);
+  TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
+}
+
 static int
 do_test (void)
 {
@@ -56,6 +72,8 @@ do_test (void)
   /* Check if sigtimedwait exits after specified timeout.  */
   test_sigtimedwait_timeout (false);
 
+  test_sigtimedwait_large_timeout ();
+
   return 0;
 }
 
-- 
2.30.2


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

* [PATCH 16/18] linux: Only use 64-bit syscall if required for utimensat family
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (14 preceding siblings ...)
  2021-06-17 11:51 ` [PATCH 15/18] linux: Only use 64-bit syscall if required for sigtimedwait Adhemerval Zanella
@ 2021-06-17 11:51 ` Adhemerval Zanella
  2021-06-21  7:45   ` Lukasz Majewski
  2021-06-17 11:51 ` [PATCH 17/18] linux: Only use 64-bit syscall if required for internal futex Adhemerval Zanella
                   ` (2 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:51 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

The large timeout are already tests by io/tst-utimensat-skeleton.c.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/utimensat.c | 35 ++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index 909a29762b..e79e4351d6 100644
--- a/sysdeps/unix/sysv/linux/utimensat.c
+++ b/sysdeps/unix/sysv/linux/utimensat.c
@@ -31,34 +31,43 @@ __utimensat64_helper (int fd, const char *file,
 #ifndef __NR_utimensat_time64
 # define __NR_utimensat_time64 __NR_utimensat
 #endif
-  int ret = INLINE_SYSCALL_CALL (utimensat_time64, fd, file, &tsp64[0], flags);
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (ret == 0 || errno != ENOSYS)
-    return ret;
 
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return INLINE_SYSCALL_CALL (utimensat_time64, fd, file, &tsp64[0], flags);
+#else
   /* For UTIME_NOW and UTIME_OMIT the value of tv_sec field is ignored.  */
-# define TS_VALID(ns) \
-  ((((ns).tv_nsec == UTIME_NOW || (ns).tv_nsec == UTIME_OMIT) \
-   || in_time_t_range ((ns).tv_sec)))
+# define TS_SPECIAL(ts) \
+  ((ts).tv_nsec == UTIME_NOW || (ts).tv_nsec == UTIME_OMIT)
 
-  if (tsp64 != NULL
-      && (!TS_VALID (tsp64[0]) || !TS_VALID (tsp64[1])))
+  bool is32bit_t0 = tsp64 != NULL
+		    ? TS_SPECIAL (tsp64[0])
+		      || in_time_t_range (tsp64[0].tv_sec)
+	            : true;
+  bool is32bit_t1 = tsp64 != NULL
+		    ? TS_SPECIAL (tsp64[1])
+		      || in_time_t_range (tsp64[1].tv_sec)
+	            : true;
+
+  if (!is32bit_t0 || !is32bit_t1)
     {
+      int r = INLINE_SYSCALL_CALL (utimensat_time64, fd, file, &tsp64[0],
+				   flags);
+      if (r == 0 || errno != ENOSYS)
+	return r;
       __set_errno (EOVERFLOW);
       return -1;
     }
 
-  struct timespec tsp32[2];
+  struct timespec tsp32[2], *ptsp32 = NULL;
   if (tsp64)
     {
       tsp32[0] = valid_timespec64_to_timespec (tsp64[0]);
       tsp32[1] = valid_timespec64_to_timespec (tsp64[1]);
+      ptsp32 = tsp32;
     }
 
-  ret = INLINE_SYSCALL_CALL (utimensat, fd, file, tsp64 ? &tsp32[0] : NULL,
-			     flags);
+  return INLINE_SYSCALL_CALL (utimensat, fd, file, ptsp32, flags);
 #endif
-  return ret;
 }
 libc_hidden_def (__utimensat64_helper)
 
-- 
2.30.2


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

* [PATCH 17/18] linux: Only use 64-bit syscall if required for internal futex
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (15 preceding siblings ...)
  2021-06-17 11:51 ` [PATCH 16/18] linux: Only use 64-bit syscall if required for utimensat family Adhemerval Zanella
@ 2021-06-17 11:51 ` Adhemerval Zanella
  2021-06-21  7:45   ` Lukasz Majewski
  2021-06-17 11:51 ` [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep Adhemerval Zanella
  2021-06-17 14:20 ` [PATCH 00/18] More y2038 fixes Lukasz Majewski
  18 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:51 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 nptl/futex-internal.c         | 52 +++++++++++++++++++++++------------
 sysdeps/nptl/futex-internal.h | 24 ++++++++++------
 2 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/nptl/futex-internal.c b/nptl/futex-internal.c
index 850bf4fd83..277e60986e 100644
--- a/nptl/futex-internal.c
+++ b/nptl/futex-internal.c
@@ -32,9 +32,6 @@ __futex_abstimed_wait_common32 (unsigned int* futex_word,
   struct timespec ts32, *pts32 = NULL;
   if (abstime != NULL)
     {
-      if (! in_time_t_range (abstime->tv_sec))
-	return -EOVERFLOW;
-
       ts32 = valid_timespec64_to_timespec (*abstime);
       pts32 = &ts32;
     }
@@ -52,12 +49,28 @@ __futex_abstimed_wait_common32 (unsigned int* futex_word,
 
 static int
 __futex_abstimed_wait_common64 (unsigned int* futex_word,
-                                unsigned int expected, clockid_t clockid,
+                                unsigned int expected, int op,
                                 const struct __timespec64* abstime,
                                 int private, bool cancel)
 {
-  unsigned int clockbit;
+  if (cancel)
+    return INTERNAL_SYSCALL_CANCEL (futex_time64, futex_word, op, expected,
+				    abstime, NULL /* Unused.  */,
+				    FUTEX_BITSET_MATCH_ANY);
+  else
+    return INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op, expected,
+				  abstime, NULL /* Ununsed.  */,
+				  FUTEX_BITSET_MATCH_ANY);
+}
+
+static int
+__futex_abstimed_wait_common (unsigned int* futex_word,
+                              unsigned int expected, clockid_t clockid,
+                              const struct __timespec64* abstime,
+                              int private, bool cancel)
+{
   int err;
+  unsigned int clockbit;
 
   /* Work around the fact that the kernel rejects negative timeout values
      despite them being valid.  */
@@ -70,16 +83,19 @@ __futex_abstimed_wait_common64 (unsigned int* futex_word,
   clockbit = (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;
   int op = __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);
 
-  if (cancel)
-    err = INTERNAL_SYSCALL_CANCEL (futex_time64, futex_word, op, expected,
-                                   abstime, NULL /* Unused.  */,
-                                   FUTEX_BITSET_MATCH_ANY);
+#ifdef __ASSUME_TIME64_SYSCALLS
+  err = __futex_abstimed_wait_common64 (futex_word, expected, op, abstime,
+					private, cancel);
+#else
+  bool is32bit = abstime != NULL ? in_time_t_range (abstime->tv_sec) : true;
+  if (!is32bit)
+    {
+      err = __futex_abstimed_wait_common64 (futex_word, expected, op, abstime,
+					    private, cancel);
+      if (err == -ENOSYS)
+	err = -EOVERFLOW;
+    }
   else
-    err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op, expected,
-                                 abstime, NULL /* Ununsed.  */,
-                                 FUTEX_BITSET_MATCH_ANY);
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (err == -ENOSYS)
     err = __futex_abstimed_wait_common32 (futex_word, expected, op, abstime,
                                           private, cancel);
 #endif
@@ -109,8 +125,8 @@ __futex_abstimed_wait64 (unsigned int* futex_word, unsigned int expected,
                          clockid_t clockid,
                          const struct __timespec64* abstime, int private)
 {
-  return __futex_abstimed_wait_common64 (futex_word, expected, clockid,
-                                         abstime, private, false);
+  return __futex_abstimed_wait_common (futex_word, expected, clockid,
+                                       abstime, private, false);
 }
 libc_hidden_def (__futex_abstimed_wait64)
 
@@ -120,7 +136,7 @@ __futex_abstimed_wait_cancelable64 (unsigned int* futex_word,
                                     const struct __timespec64* abstime,
                                     int private)
 {
-  return __futex_abstimed_wait_common64 (futex_word, expected, clockid,
-                                         abstime, private, true);
+  return __futex_abstimed_wait_common (futex_word, expected, clockid,
+                                       abstime, private, true);
 }
 libc_hidden_def (__futex_abstimed_wait_cancelable64)
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index 969ab2bf4b..b54fdd44c1 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -254,15 +254,23 @@ static __always_inline int
 futex_lock_pi64 (int *futex_word, const struct __timespec64 *abstime,
                  int private)
 {
-  int err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
-                                   __lll_private_flag
-                                   (FUTEX_LOCK_PI, private), 0, abstime);
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (err == -ENOSYS)
+  int err;
+#ifdef __ASSUME_TIME64_SYSCALLS
+  err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
+			       __lll_private_flag (FUTEX_LOCK_PI, private), 0,
+			       abstime);
+#else
+  bool is32bit = abstime != NULL ? in_time_t_range (abstime->tv_sec) : true;
+  if (!is32bit)
+    {
+      err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
+				   __lll_private_flag (FUTEX_LOCK_PI, private),
+				   0, abstime);
+      if (err == -ENOSYS)
+	err = -EOVERFLOW;
+    }
+  else
     {
-      if (abstime != NULL && ! in_time_t_range (abstime->tv_sec))
-        return EOVERFLOW;
-
       struct timespec ts32;
       if (abstime != NULL)
         ts32 = valid_timespec64_to_timespec (*abstime);
-- 
2.30.2


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

* [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (16 preceding siblings ...)
  2021-06-17 11:51 ` [PATCH 17/18] linux: Only use 64-bit syscall if required for internal futex Adhemerval Zanella
@ 2021-06-17 11:51 ` Adhemerval Zanella
  2021-06-17 15:11   ` Lukasz Majewski
  2021-06-21  7:46   ` Lukasz Majewski
  2021-06-17 14:20 ` [PATCH 00/18] More y2038 fixes Lukasz Majewski
  18 siblings, 2 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 11:51 UTC (permalink / raw)
  To: libc-alpha, Lukasz Majewski, Carlos O'Donell

For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall
if the provided timeout fits in a 32-bit one.  The 64-bit usage should
be rare since the timeout is a relative one.

Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
(with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/clock_nanosleep.c | 47 +++++++++++++----------
 time/Makefile                             |  9 +++++
 time/tst-clock_nanosleep.c                | 40 +++++++++++--------
 3 files changed, 60 insertions(+), 36 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index 007f1736cb..46b0f1e269 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -27,8 +27,9 @@
 /* We can simply use the syscall.  The CPU clocks are not supported
    with this function.  */
 int
-__clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec64 *req,
-                          struct __timespec64 *rem)
+__clock_nanosleep_time64 (clockid_t clock_id, int flags,
+			  const struct __timespec64 *req,
+			  struct __timespec64 *rem)
 {
   if (clock_id == CLOCK_THREAD_CPUTIME_ID)
     return EINVAL;
@@ -37,33 +38,37 @@ __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec
 
   /* If the call is interrupted by a signal handler or encounters an error,
      it returns a positive value similar to errno.  */
+
 #ifndef __NR_clock_nanosleep_time64
 # define __NR_clock_nanosleep_time64 __NR_clock_nanosleep
 #endif
-  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
-				   flags, req, rem);
-
-#ifndef __ASSUME_TIME64_SYSCALLS
-  if (r == 0 || r != -ENOSYS)
-    return -r;
 
-  if (! in_time_t_range (req->tv_sec))
+  int r;
+#ifdef __ASSUME_TIME64_SYSCALLS
+  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id, flags, req,
+			       rem);
+#else
+  bool is32bit = in_time_t_range (req->tv_sec);
+  if (!is32bit)
     {
-      __set_errno (EOVERFLOW);
-      return -1;
+      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id, flags,
+				   req, rem);
+      if (r == -ENOSYS)
+	r = -EOVERFLOW;
     }
-
-  struct timespec tr32;
-  struct timespec ts32 = valid_timespec64_to_timespec (*req);
-  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
-                               &ts32, &tr32);
-  if (INTERNAL_SYSCALL_ERROR_P (r))
+  else
     {
-      if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0)
-	*rem = valid_timespec_to_timespec64 (tr32);
+      struct timespec tr32;
+      struct timespec ts32 = valid_timespec64_to_timespec (*req);
+      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags, &ts32,
+				   &tr32);
+      if (INTERNAL_SYSCALL_ERROR_P (r))
+	{
+	  if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0)
+	    *rem = valid_timespec_to_timespec64 (tr32);
+	}
     }
-#endif /* __ASSUME_TIME64_SYSCALLS */
-
+#endif
   return -r;
 }
 
diff --git a/time/Makefile b/time/Makefile
index c84bd5d3ec..0bea84966c 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -86,6 +86,15 @@ $(objpfx)tst-strftime2.out: $(gen-locales)
 $(objpfx)tst-strftime3.out: $(gen-locales)
 endif
 
+ifeq (yes,$(build-shared))
+librt = $(common-objpfx)rt/librt.so
+else
+librt = $(common-objpfx)rt/librt.a
+endif
+
+$(objpfx)tst-clock_nanosleep: $(librt)
+$(objpfx)tst-clock_nanosleep-time64: $(librt)
+
 tz-cflags = -DTZDIR='"$(zonedir)"' \
 	    -DTZDEFAULT='"$(localtime-file)"' \
 	    -DTZDEFRULES='"$(posixrules-file)"'
diff --git a/time/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c
index 47537435c1..a5a7f9430a 100644
--- a/time/tst-clock_nanosleep.c
+++ b/time/tst-clock_nanosleep.c
@@ -20,38 +20,48 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <time.h>
-
+#include <intprops.h>
+#include <support/support.h>
+#include <support/check.h>
 
 /* Test that clock_nanosleep() does sleep.  */
-static int
-do_test (void)
+static void
+clock_nanosleep_test (void)
 {
   /* Current time.  */
   struct timeval tv1;
-  (void) gettimeofday (&tv1, NULL);
+  gettimeofday (&tv1, NULL);
 
-  struct timespec ts;
-  ts.tv_sec = 1;
-  ts.tv_nsec = 0;
+  struct timespec ts = { 1, 0 };
   TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts));
 
   /* At least one second must have passed.  */
   struct timeval tv2;
-  (void) gettimeofday (&tv2, NULL);
+  gettimeofday (&tv2, NULL);
 
   tv2.tv_sec -= tv1.tv_sec;
   tv2.tv_usec -= tv1.tv_usec;
   if (tv2.tv_usec < 0)
     --tv2.tv_sec;
 
-  if (tv2.tv_sec < 1)
-    {
-      puts ("clock_nanosleep didn't sleep long enough");
-      return 1;
-    }
+  TEST_VERIFY (tv2.tv_sec >= 1);
+}
+
+static void
+clock_nanosleep_large_timeout (void)
+{
+  support_create_timer (0, 100000000, false, NULL);
+  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
+  int r = clock_nanosleep (CLOCK_REALTIME, 0, &ts, NULL);
+  TEST_VERIFY (r == EINTR || r == EOVERFLOW);
+}
 
+static int
+do_test (void)
+{
+  clock_nanosleep_test ();
+  clock_nanosleep_large_timeout ();
   return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
-- 
2.30.2


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

* Re: [PATCH 02/18] Use LFS and 64 bit time for installed programs
  2021-06-17 11:50 ` [PATCH 02/18] Use LFS and 64 bit time for installed programs Adhemerval Zanella
@ 2021-06-17 12:19   ` Andreas Schwab
  2021-06-18 18:50     ` Adhemerval Zanella
  2021-06-17 20:49   ` Joseph Myers
  1 sibling, 1 reply; 48+ messages in thread
From: Andreas Schwab @ 2021-06-17 12:19 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

On Jun 17 2021, Adhemerval Zanella via Libc-alpha wrote:

> diff --git a/Makeconfig b/Makeconfig
> index 6482a43025..de30ba3fa6 100644
> --- a/Makeconfig
> +++ b/Makeconfig
> @@ -851,6 +851,10 @@ endif
>  # -fno-math-errno.
>  +extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno)
>  
> +# Use 64 bit time_t support for installed programs
> ++extra-time-flags = $(if $(filter nonlib nscd lddlibc4 ldconfig locale_programs iconvprogs,\

I'd suggest to put the list of module names in a variable, to make it
easier to shorten the line.

> diff --git a/Makerules b/Makerules
> index 12f1a5cb50..770a573134 100644
> --- a/Makerules
> +++ b/Makerules
> @@ -1313,14 +1313,22 @@ lib := testsuite
>  include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
>  endif
>  
> -all-nonlib := $(strip $(tests-internal) $(test-internal-extras) \
> -		      $(others) $(others-extras))
> +all-nonlib := $(strip $(others) $(others-extras))
>  ifneq (,$(all-nonlib))
>  cpp-srcs-left = $(all-nonlib)
>  lib := nonlib
>  include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
>  endif
>  
> +# All internal tests use testsuite-internal module since for 64 bit time
> +# support is set as default for MODULE_NAME=nonlib (which include some
> +# installed programs.

Missing close paren.

> diff --git a/locale/localeinfo.h b/locale/localeinfo.h
> index b3d4da0185..9e53681829 100644
> --- a/locale/localeinfo.h
> +++ b/locale/localeinfo.h
> @@ -50,7 +50,7 @@ struct __locale_data
>  {
>    const char *name;
>    const char *filedata;		/* Region mapping the file data.  */
> -  off_t filesize;		/* Size of the file (and the region).  */
> +  __off_t filesize;		/* Size of the file (and the region).  */

Why is that needed?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH 15/18] linux: Only use 64-bit syscall if required for sigtimedwait
  2021-06-17 11:51 ` [PATCH 15/18] linux: Only use 64-bit syscall if required for sigtimedwait Adhemerval Zanella
@ 2021-06-17 12:25   ` Andreas Schwab
  2021-06-22 14:58     ` Adhemerval Zanella
  0 siblings, 1 reply; 48+ messages in thread
From: Andreas Schwab @ 2021-06-17 12:25 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

On Jun 17 2021, Adhemerval Zanella via Libc-alpha wrote:

> +  bool is32bit = timeout != NULL
> +		 ? in_time_t_range (timeout->tv_sec) : true;

     bool is32bit = timeout == NULL || in_time_t_range (timeout->tv_sec);

or

     bool need_time64 = timeout != NULL && !in_time_t_range (timeout->tv_sec);

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH 00/18] More y2038 fixes
  2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
                   ` (17 preceding siblings ...)
  2021-06-17 11:51 ` [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep Adhemerval Zanella
@ 2021-06-17 14:20 ` Lukasz Majewski
  2021-06-17 17:41   ` Adhemerval Zanella
  18 siblings, 1 reply; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-17 14:20 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 8804 bytes --]

Hi Adhemerval,

> Hi Carlos and Lukasz,
> 
> This patchset adds more y2038 fixes that I would like to push for
> 2.34. The first two patches enable more internal y2038 usage on glibc
> and also for the installed programs.  Making glibc the first consumer
> of these newer interfaces should improve coverage.
> 

Those two patches were already available for review for some time.
Indeed, by using 64-bit time internally we may have more testing
(sooner).

> The next 6 patches removes an optimization I added on some specific
> syscall, where a global variable it atomically set once glibc detects
> that kernel supports 64-bit time.  The problem with this approach
> breaks the usage case of live migration like CRIU or similar.

I do recall that this optimization was to avoid performance regression
on legacy systems - to avoid issuing two syscalls (64 bit one and then
32 bit one).

>  Also
> for some interfaces that do not query information from kernel, most
> usages can be optimized away by either building glibc with a minimum
> 5.1 kernel or by using the 32-bit syscall for the common case.

I do think that this approach (with classification of use cases based
on specified kernel version) aligns with how people will build setups
for those systems (at least I do it in this way for OE/Yocto).

> 
> So the following patch implement this optimization for the interfaces
> that allows it.  If the provided timeout can be fit in old 32-bit
> time_t, the old syscall is used instead.  This optimization is only
> used for !__ASSUME_TIME64_SYSCALLS, otherwise the newer 64-bit
> syscall are used.

Ok.

> 
> I checked this with 3 different configation which should cover most
> usages:
> 
>   - i686-linux-gnu on a 4.15 kernel and default --enable-kernel=3.2.
>     This uses the 32-bit optimization to avoid calling the newer
>     64-bit syscall when possible.  It also triggers and EOVERFLOW
>     when 64-bit inputs are used without proper kernel support.

Ok.

>   - i686-linux-gnu on a 5.11 kernel and default --enable-kernel=3.2.
>     This will also use the 32-bit optimization, but it will always
>     succeded due proper kernel support.

Ok.

>   - i686-linux-gnu on a 5.11 kernel and with --enable-kernel=5.1.
>     This enables __ASSUME_TIME64_SYSCALLS and only uses 64-bit
>     time_t syscalls.

Ok.

BTW: I'm wondering when the minimal, supported Linux kernel version is
going to be moved forward?

> 
> Adhemerval Zanella (18):
>   Use 64 bit time_t stat internally
>   Use LFS and 64 bit time for installed programs
>   support: Add support_create_timer
>   linux: Only use 64-bit syscall if required for ppoll
>   linux: Only use 64-bit syscall if required for pselect
>   linux: Only use 64-bit syscall if required for select
>   linux: Remove supports_time64 () from clock_getres
>   linux: Remove supports_time64 () from clock_gettime
>   linux: Remove time64-support
>   linux: timerfd_gettime minor cleanup
>   linux: Only use 64-bit syscall if required for semtimedop
>   linux: Only use 64-bit syscall if required for timerfd_settime
>   linux: Only use 64-bit syscall if required for mq_timedreceive
>   linux: Only use 64-bit syscall if required for mq_timedsend
>   linux: Only use 64-bit syscall if required for sigtimedwait
>   linux: Only use 64-bit syscall if required for utimensat family
>   linux: Only use 64-bit syscall if required for internal futex
>   linux: Only use 64-bit syscall if required for clock_nanosleep
> 
>  Makeconfig                                    |   8 +-
>  Makerules                                     |  12 +-
>  csu/check_fds.c                               |   8 +-
>  elf/dl-load.c                                 |   8 +-
>  elf/dl-misc.c                                 |   4 +-
>  elf/dl-profile.c                              |   4 +-
>  iconv/gconv_cache.c                           |   4 +-
>  include/dirent.h                              |   2 +-
>  include/file_change_detection.h               |   6 +-
>  include/sys/select.h                          |   5 +
>  inet/rcmd.c                                   |   6 +-
>  intl/loadmsgcat.c                             |   4 +-
>  io/Makefile                                   |   4 +-
>  io/file_change_detection.c                    |  16 ++-
>  io/getdirname.c                               |   6 +-
>  libio/filedoalloc.c                           |   2 +-
>  libio/fileops.c                               |   8 +-
>  libio/oldfileops.c                            |   2 +-
>  libio/wfileops.c                              |   2 +-
>  locale/loadarchive.c                          |   8 +-
>  locale/loadlocale.c                           |   6 +-
>  locale/localeinfo.h                           |   2 +-
>  misc/Makefile                                 |  11 ++
>  misc/tst-pselect.c                            | 120
> ++++++++---------- misc/tst-select.c                             |
> 39 +++--- nptl/futex-internal.c                         |  52 +++++---
>  nscd/nscd_helper.c                            |   4 +-
>  nss/nss_database.c                            |   4 +-
>  rt/Makefile                                   |   4 +-
>  rt/tst-mqueue10-time64.c                      |   1 +
>  rt/tst-mqueue10.c                             |  72 +++++++++++
>  support/Makefile                              |   1 +
>  support/support.h                             |  11 ++
>  support/support_create_timer.c                |  69 ++++++++++
>  sysdeps/nptl/futex-internal.h                 |  24 ++--
>  sysdeps/posix/dl-fileid.h                     |   4 +-
>  sysdeps/posix/euidaccess.c                    |   4 +-
>  sysdeps/posix/getaddrinfo.c                   |  21 +--
>  sysdeps/posix/getcwd.c                        |  15 ++-
>  sysdeps/posix/pathconf.c                      |   4 +-
>  sysdeps/posix/sysconf.c                       |   4 +-
>  sysdeps/posix/tempname.c                      |   8 +-
>  sysdeps/unix/sysv/linux/Makefile              |  15 ++-
>  sysdeps/unix/sysv/linux/clock_getres.c        |  16 +--
>  sysdeps/unix/sysv/linux/clock_gettime.c       |  14 +-
>  sysdeps/unix/sysv/linux/clock_nanosleep.c     |  47 ++++---
>  sysdeps/unix/sysv/linux/fdopendir.c           |   4 +-
>  sysdeps/unix/sysv/linux/fexecve.c             |   4 +-
>  .../unix/sysv/linux/microblaze/pselect32.c    |   3 +-
>  sysdeps/unix/sysv/linux/mq_timedreceive.c     |  35 ++---
>  sysdeps/unix/sysv/linux/mq_timedsend.c        |  35 ++---
>  sysdeps/unix/sysv/linux/opendir.c             |   7 +-
>  sysdeps/unix/sysv/linux/pathconf.c            |   5 +-
>  sysdeps/unix/sysv/linux/ppoll.c               |  41 +++---
>  sysdeps/unix/sysv/linux/pselect.c             |  47 ++++---
>  sysdeps/unix/sysv/linux/pselect32.c           |   6 -
>  sysdeps/unix/sysv/linux/select.c              |  60 +++------
>  sysdeps/unix/sysv/linux/select32.c            |  58 +++++++++
>  sysdeps/unix/sysv/linux/semtimedop.c          |  54 ++++----
>  sysdeps/unix/sysv/linux/sigtimedwait.c        |  26 ++--
>  sysdeps/unix/sysv/linux/time64-support.c      |  23 ----
>  sysdeps/unix/sysv/linux/time64-support.h      |  70 ----------
>  sysdeps/unix/sysv/linux/timerfd_gettime.c     |  10 +-
>  sysdeps/unix/sysv/linux/timerfd_settime.c     |  25 ++--
>  sysdeps/unix/sysv/linux/tst-ppoll.c           |  15 +++
>  sysdeps/unix/sysv/linux/tst-sigtimedwait.c    |  18 +++
>  sysdeps/unix/sysv/linux/tst-timerfd.c         |  29 ++++-
>  sysdeps/unix/sysv/linux/ttyname.h             |  10 +-
>  sysdeps/unix/sysv/linux/ttyname_r.c           |  16 +--
>  sysdeps/unix/sysv/linux/utimensat.c           |  35 +++--
>  sysvipc/Makefile                              |   9 ++
>  sysvipc/ftok.c                                |   4 +-
>  sysvipc/test-sysvsem.c                        |  22 +++-
>  time/Makefile                                 |   9 ++
>  time/tst-clock_nanosleep.c                    |  40 +++---
>  time/tzfile.c                                 |   6 +-
>  76 files changed, 851 insertions(+), 566 deletions(-)
>  create mode 100644 rt/tst-mqueue10-time64.c
>  create mode 100644 rt/tst-mqueue10.c
>  create mode 100644 support/support_create_timer.c
>  create mode 100644 sysdeps/unix/sysv/linux/select32.c
>  delete mode 100644 sysdeps/unix/sysv/linux/time64-support.c
>  delete mode 100644 sysdeps/unix/sysv/linux/time64-support.h
> 



Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep
  2021-06-17 11:51 ` [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep Adhemerval Zanella
@ 2021-06-17 15:11   ` Lukasz Majewski
  2021-06-17 17:45     ` Adhemerval Zanella
  2021-06-21  7:46   ` Lukasz Majewski
  1 sibling, 1 reply; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-17 15:11 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 6999 bytes --]

Hi Adhemerval,

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.

I'm not sure if the above description is correct.

As fair as I understand this patch set - we check if timeout fits into
32-bit if:

- We want to use legacy (32 bit) syscall when __ASSUME_TIME64_SYSCALLS
  is not defined to avoid calling syscalls twice.

The problem with relative 64 bit timeouts will be apparent after we
pass Y2038 year threshold. 

> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/clock_nanosleep.c | 47
> +++++++++++++---------- time/Makefile                             |
> 9 +++++ time/tst-clock_nanosleep.c                | 40
> +++++++++++-------- 3 files changed, 60 insertions(+), 36 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c
> b/sysdeps/unix/sysv/linux/clock_nanosleep.c index
> 007f1736cb..46b0f1e269 100644 ---
> a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++
> b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -27,8 +27,9 @@
>  /* We can simply use the syscall.  The CPU clocks are not supported
>     with this function.  */
>  int
> -__clock_nanosleep_time64 (clockid_t clock_id, int flags, const
> struct __timespec64 *req,
> -                          struct __timespec64 *rem)
> +__clock_nanosleep_time64 (clockid_t clock_id, int flags,
> +			  const struct __timespec64 *req,
> +			  struct __timespec64 *rem)
>  {
>    if (clock_id == CLOCK_THREAD_CPUTIME_ID)
>      return EINVAL;
> @@ -37,33 +38,37 @@ __clock_nanosleep_time64 (clockid_t clock_id, int
> flags, const struct __timespec 
>    /* If the call is interrupted by a signal handler or encounters an
> error, it returns a positive value similar to errno.  */
> +
>  #ifndef __NR_clock_nanosleep_time64
>  # define __NR_clock_nanosleep_time64 __NR_clock_nanosleep
>  #endif
> -  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
> -				   flags, req, rem);
> -
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (r == 0 || r != -ENOSYS)
> -    return -r;
>  
> -  if (! in_time_t_range (req->tv_sec))
> +  int r;
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
> flags, req,
> +			       rem);
> +#else
> +  bool is32bit = in_time_t_range (req->tv_sec);
> +  if (!is32bit)
>      {
> -      __set_errno (EOVERFLOW);
> -      return -1;
> +      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
> flags,
> +				   req, rem);
> +      if (r == -ENOSYS)
> +	r = -EOVERFLOW;
>      }
> -
> -  struct timespec tr32;
> -  struct timespec ts32 = valid_timespec64_to_timespec (*req);
> -  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
> -                               &ts32, &tr32);
> -  if (INTERNAL_SYSCALL_ERROR_P (r))
> +  else
>      {
> -      if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0)
> -	*rem = valid_timespec_to_timespec64 (tr32);
> +      struct timespec tr32;
> +      struct timespec ts32 = valid_timespec64_to_timespec (*req);
> +      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
> &ts32,
> +				   &tr32);
> +      if (INTERNAL_SYSCALL_ERROR_P (r))
> +	{
> +	  if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME)
> == 0)
> +	    *rem = valid_timespec_to_timespec64 (tr32);
> +	}
>      }
> -#endif /* __ASSUME_TIME64_SYSCALLS */
> -
> +#endif
>    return -r;
>  }
>  
> diff --git a/time/Makefile b/time/Makefile
> index c84bd5d3ec..0bea84966c 100644
> --- a/time/Makefile
> +++ b/time/Makefile
> @@ -86,6 +86,15 @@ $(objpfx)tst-strftime2.out: $(gen-locales)
>  $(objpfx)tst-strftime3.out: $(gen-locales)
>  endif
>  
> +ifeq (yes,$(build-shared))
> +librt = $(common-objpfx)rt/librt.so
> +else
> +librt = $(common-objpfx)rt/librt.a
> +endif
> +
> +$(objpfx)tst-clock_nanosleep: $(librt)
> +$(objpfx)tst-clock_nanosleep-time64: $(librt)
> +
>  tz-cflags = -DTZDIR='"$(zonedir)"' \
>  	    -DTZDEFAULT='"$(localtime-file)"' \
>  	    -DTZDEFRULES='"$(posixrules-file)"'
> diff --git a/time/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c
> index 47537435c1..a5a7f9430a 100644
> --- a/time/tst-clock_nanosleep.c
> +++ b/time/tst-clock_nanosleep.c
> @@ -20,38 +20,48 @@
>  #include <unistd.h>
>  #include <sys/time.h>
>  #include <time.h>
> -
> +#include <intprops.h>
> +#include <support/support.h>
> +#include <support/check.h>
>  
>  /* Test that clock_nanosleep() does sleep.  */
> -static int
> -do_test (void)
> +static void
> +clock_nanosleep_test (void)
>  {
>    /* Current time.  */
>    struct timeval tv1;
> -  (void) gettimeofday (&tv1, NULL);
> +  gettimeofday (&tv1, NULL);
>  
> -  struct timespec ts;
> -  ts.tv_sec = 1;
> -  ts.tv_nsec = 0;
> +  struct timespec ts = { 1, 0 };
>    TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts));
>  
>    /* At least one second must have passed.  */
>    struct timeval tv2;
> -  (void) gettimeofday (&tv2, NULL);
> +  gettimeofday (&tv2, NULL);
>  
>    tv2.tv_sec -= tv1.tv_sec;
>    tv2.tv_usec -= tv1.tv_usec;
>    if (tv2.tv_usec < 0)
>      --tv2.tv_sec;
>  
> -  if (tv2.tv_sec < 1)
> -    {
> -      puts ("clock_nanosleep didn't sleep long enough");
> -      return 1;
> -    }
> +  TEST_VERIFY (tv2.tv_sec >= 1);
> +}
> +
> +static void
> +clock_nanosleep_large_timeout (void)
> +{

Please correct me if I'm wrong:

> +  support_create_timer (0, 100000000, false, NULL);

You create timer with 100ms timeout

> +  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };

ts is created to have maximal value for time_t seconds.

> +  int r = clock_nanosleep (CLOCK_REALTIME, 0, &ts, NULL);

The clock_nanosleep is called (64 or 32 bit version - with proper
in-glibc aliasing).

> +  TEST_VERIFY (r == EINTR || r == EOVERFLOW);

We check if:

- return is EOVERFLOW - this means that we want to use 64 bit time on
  machine which is only supporting 64 bit time.

- return is EINTR - as the timer's (introduced in the earlier patch in
  this set) alarm triggers. Am I right that this check is to find out
  if the syscall is correctly executed by the kernel?

  Or is there any other issue?

> +}
>  
> +static int
> +do_test (void)
> +{
> +  clock_nanosleep_test ();
> +  clock_nanosleep_large_timeout ();
>    return 0;
>  }
>  
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/test-driver.c>



Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 00/18] More y2038 fixes
  2021-06-17 14:20 ` [PATCH 00/18] More y2038 fixes Lukasz Majewski
@ 2021-06-17 17:41   ` Adhemerval Zanella
  2021-06-17 20:58     ` Joseph Myers
  0 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 17:41 UTC (permalink / raw)
  To: Lukasz Majewski; +Cc: libc-alpha, Carlos O'Donell



On 17/06/2021 11:20, Lukasz Majewski wrote:
> Hi Adhemerval,
> 
>> Hi Carlos and Lukasz,
>>
>> This patchset adds more y2038 fixes that I would like to push for
>> 2.34. The first two patches enable more internal y2038 usage on glibc
>> and also for the installed programs.  Making glibc the first consumer
>> of these newer interfaces should improve coverage.
>>
> 
> Those two patches were already available for review for some time.
> Indeed, by using 64-bit time internally we may have more testing
> (sooner).

Yes, but I changed slight the one that enabled the y2038 symbol on
installed program to use apply the CFLAGS on module, instead of
setting in each sub Makefile.

> 
>> The next 6 patches removes an optimization I added on some specific
>> syscall, where a global variable it atomically set once glibc detects
>> that kernel supports 64-bit time.  The problem with this approach
>> breaks the usage case of live migration like CRIU or similar.
> 
> I do recall that this optimization was to avoid performance regression
> on legacy systems - to avoid issuing two syscalls (64 bit one and then
> 32 bit one).

Yes, but as I noted some interfaces don't really need to use the newer
syscall in the compatibility mode (where glibc is build to support older
kernels). This optimization is really tricky, since it incurs in some
data races (I think to fully avoid it would require seq-cst atomic instead
of relaxed ones) and it might break live migration.

> 
>>  Also
>> for some interfaces that do not query information from kernel, most
>> usages can be optimized away by either building glibc with a minimum
>> 5.1 kernel or by using the 32-bit syscall for the common case.
> 
> I do think that this approach (with classification of use cases based
> on specified kernel version) aligns with how people will build setups
> for those systems (at least I do it in this way for OE/Yocto).

I think there will be specific cases where kernel update is not an
option, but I think these will be really niches. 

> 
>>
>> So the following patch implement this optimization for the interfaces
>> that allows it.  If the provided timeout can be fit in old 32-bit
>> time_t, the old syscall is used instead.  This optimization is only
>> used for !__ASSUME_TIME64_SYSCALLS, otherwise the newer 64-bit
>> syscall are used.
> 
> Ok.
> 
>>
>> I checked this with 3 different configation which should cover most
>> usages:
>>
>>   - i686-linux-gnu on a 4.15 kernel and default --enable-kernel=3.2.
>>     This uses the 32-bit optimization to avoid calling the newer
>>     64-bit syscall when possible.  It also triggers and EOVERFLOW
>>     when 64-bit inputs are used without proper kernel support.
> 
> Ok.
> 
>>   - i686-linux-gnu on a 5.11 kernel and default --enable-kernel=3.2.
>>     This will also use the 32-bit optimization, but it will always
>>     succeded due proper kernel support.
> 
> Ok.
> 
>>   - i686-linux-gnu on a 5.11 kernel and with --enable-kernel=5.1.
>>     This enables __ASSUME_TIME64_SYSCALLS and only uses 64-bit
>>     time_t syscalls.
> 
> Ok.
> 
> BTW: I'm wondering when the minimal, supported Linux kernel version is
> going to be moved forward?

We usually follow the minimum LTS supported by Linux kernel developers.

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

* Re: [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep
  2021-06-17 15:11   ` Lukasz Majewski
@ 2021-06-17 17:45     ` Adhemerval Zanella
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-17 17:45 UTC (permalink / raw)
  To: Lukasz Majewski; +Cc: libc-alpha, Carlos O'Donell



On 17/06/2021 12:11, Lukasz Majewski wrote:
> Hi Adhemerval,
> 
>> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
>> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
>> usage should be rare since the timeout is a relative one.
> 
> I'm not sure if the above description is correct.
> 
> As fair as I understand this patch set - we check if timeout fits into
> 32-bit if:
> 
> - We want to use legacy (32 bit) syscall when __ASSUME_TIME64_SYSCALLS
>   is not defined to avoid calling syscalls twice.
> 
> The problem with relative 64 bit timeouts will be apparent after we
> pass Y2038 year threshold. 

Yes, but 64-bit relative timeout means that caller is passing a *very*
large timeout.  It is possible indeed, but I don't think it the usual
way.

> 
>>
>> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
>> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
>> ---
>>  sysdeps/unix/sysv/linux/clock_nanosleep.c | 47
>> +++++++++++++---------- time/Makefile                             |
>> 9 +++++ time/tst-clock_nanosleep.c                | 40
>> +++++++++++-------- 3 files changed, 60 insertions(+), 36 deletions(-)
>>
>> diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c
>> b/sysdeps/unix/sysv/linux/clock_nanosleep.c index
>> 007f1736cb..46b0f1e269 100644 ---
>> a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++
>> b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -27,8 +27,9 @@
>>  /* We can simply use the syscall.  The CPU clocks are not supported
>>     with this function.  */
>>  int
>> -__clock_nanosleep_time64 (clockid_t clock_id, int flags, const
>> struct __timespec64 *req,
>> -                          struct __timespec64 *rem)
>> +__clock_nanosleep_time64 (clockid_t clock_id, int flags,
>> +			  const struct __timespec64 *req,
>> +			  struct __timespec64 *rem)
>>  {
>>    if (clock_id == CLOCK_THREAD_CPUTIME_ID)
>>      return EINVAL;
>> @@ -37,33 +38,37 @@ __clock_nanosleep_time64 (clockid_t clock_id, int
>> flags, const struct __timespec 
>>    /* If the call is interrupted by a signal handler or encounters an
>> error, it returns a positive value similar to errno.  */
>> +
>>  #ifndef __NR_clock_nanosleep_time64
>>  # define __NR_clock_nanosleep_time64 __NR_clock_nanosleep
>>  #endif
>> -  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
>> -				   flags, req, rem);
>> -
>> -#ifndef __ASSUME_TIME64_SYSCALLS
>> -  if (r == 0 || r != -ENOSYS)
>> -    return -r;
>>  
>> -  if (! in_time_t_range (req->tv_sec))
>> +  int r;
>> +#ifdef __ASSUME_TIME64_SYSCALLS
>> +  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
>> flags, req,
>> +			       rem);
>> +#else
>> +  bool is32bit = in_time_t_range (req->tv_sec);
>> +  if (!is32bit)
>>      {
>> -      __set_errno (EOVERFLOW);
>> -      return -1;
>> +      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
>> flags,
>> +				   req, rem);
>> +      if (r == -ENOSYS)
>> +	r = -EOVERFLOW;
>>      }
>> -
>> -  struct timespec tr32;
>> -  struct timespec ts32 = valid_timespec64_to_timespec (*req);
>> -  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
>> -                               &ts32, &tr32);
>> -  if (INTERNAL_SYSCALL_ERROR_P (r))
>> +  else
>>      {
>> -      if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0)
>> -	*rem = valid_timespec_to_timespec64 (tr32);
>> +      struct timespec tr32;
>> +      struct timespec ts32 = valid_timespec64_to_timespec (*req);
>> +      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
>> &ts32,
>> +				   &tr32);
>> +      if (INTERNAL_SYSCALL_ERROR_P (r))
>> +	{
>> +	  if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME)
>> == 0)
>> +	    *rem = valid_timespec_to_timespec64 (tr32);
>> +	}
>>      }
>> -#endif /* __ASSUME_TIME64_SYSCALLS */
>> -
>> +#endif
>>    return -r;
>>  }
>>  
>> diff --git a/time/Makefile b/time/Makefile
>> index c84bd5d3ec..0bea84966c 100644
>> --- a/time/Makefile
>> +++ b/time/Makefile
>> @@ -86,6 +86,15 @@ $(objpfx)tst-strftime2.out: $(gen-locales)
>>  $(objpfx)tst-strftime3.out: $(gen-locales)
>>  endif
>>  
>> +ifeq (yes,$(build-shared))
>> +librt = $(common-objpfx)rt/librt.so
>> +else
>> +librt = $(common-objpfx)rt/librt.a
>> +endif
>> +
>> +$(objpfx)tst-clock_nanosleep: $(librt)
>> +$(objpfx)tst-clock_nanosleep-time64: $(librt)
>> +
>>  tz-cflags = -DTZDIR='"$(zonedir)"' \
>>  	    -DTZDEFAULT='"$(localtime-file)"' \
>>  	    -DTZDEFRULES='"$(posixrules-file)"'
>> diff --git a/time/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c
>> index 47537435c1..a5a7f9430a 100644
>> --- a/time/tst-clock_nanosleep.c
>> +++ b/time/tst-clock_nanosleep.c
>> @@ -20,38 +20,48 @@
>>  #include <unistd.h>
>>  #include <sys/time.h>
>>  #include <time.h>
>> -
>> +#include <intprops.h>
>> +#include <support/support.h>
>> +#include <support/check.h>
>>  
>>  /* Test that clock_nanosleep() does sleep.  */
>> -static int
>> -do_test (void)
>> +static void
>> +clock_nanosleep_test (void)
>>  {
>>    /* Current time.  */
>>    struct timeval tv1;
>> -  (void) gettimeofday (&tv1, NULL);
>> +  gettimeofday (&tv1, NULL);
>>  
>> -  struct timespec ts;
>> -  ts.tv_sec = 1;
>> -  ts.tv_nsec = 0;
>> +  struct timespec ts = { 1, 0 };
>>    TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts));
>>  
>>    /* At least one second must have passed.  */
>>    struct timeval tv2;
>> -  (void) gettimeofday (&tv2, NULL);
>> +  gettimeofday (&tv2, NULL);
>>  
>>    tv2.tv_sec -= tv1.tv_sec;
>>    tv2.tv_usec -= tv1.tv_usec;
>>    if (tv2.tv_usec < 0)
>>      --tv2.tv_sec;
>>  
>> -  if (tv2.tv_sec < 1)
>> -    {
>> -      puts ("clock_nanosleep didn't sleep long enough");
>> -      return 1;
>> -    }
>> +  TEST_VERIFY (tv2.tv_sec >= 1);
>> +}
>> +
>> +static void
>> +clock_nanosleep_large_timeout (void)
>> +{
> 
> Please correct me if I'm wrong:
> 
>> +  support_create_timer (0, 100000000, false, NULL);
> 
> You create timer with 100ms timeout
> 
>> +  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
> 
> ts is created to have maximal value for time_t seconds.
> 
>> +  int r = clock_nanosleep (CLOCK_REALTIME, 0, &ts, NULL);
> 
> The clock_nanosleep is called (64 or 32 bit version - with proper
> in-glibc aliasing).
> 
>> +  TEST_VERIFY (r == EINTR || r == EOVERFLOW);
> 
> We check if:
> 
> - return is EOVERFLOW - this means that we want to use 64 bit time on
>   machine which is only supporting 64 bit time.

We want to use a 64-bit relative timeout on a machine where 
__NR_clock_nanosleep_time64 failed with ENOSYS, meaning a pre v5.1 kernel
without 64-bit time_t support.

> 
> - return is EINTR - as the timer's (introduced in the earlier patch in
>   this set) alarm triggers. Am I right that this check is to find out
>   if the syscall is correctly executed by the kernel?

Yes, the EINTR means that syscall was interrupted by the alarm.

> 
>   Or is there any other issue?

I think these are the two possible situations. 

> 
>> +}
>>  
>> +static int
>> +do_test (void)
>> +{
>> +  clock_nanosleep_test ();
>> +  clock_nanosleep_large_timeout ();
>>    return 0;
>>  }
>>  
>> -#define TEST_FUNCTION do_test ()
>> -#include "../test-skeleton.c"
>> +#include <support/test-driver.c>
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
> 

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

* Re: [PATCH 02/18] Use LFS and 64 bit time for installed programs
  2021-06-17 11:50 ` [PATCH 02/18] Use LFS and 64 bit time for installed programs Adhemerval Zanella
  2021-06-17 12:19   ` Andreas Schwab
@ 2021-06-17 20:49   ` Joseph Myers
  2021-06-18 18:14     ` Adhemerval Zanella
  1 sibling, 1 reply; 48+ messages in thread
From: Joseph Myers @ 2021-06-17 20:49 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Lukasz Majewski, Carlos O'Donell

On Thu, 17 Jun 2021, Adhemerval Zanella via Libc-alpha wrote:

> The installed programs are built with a combination of different
> values for MODULE_NAME, as below.  To enable both Long File Support
> and 64 bt time, -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 is added for
> nonlib, nscd, lddlibc4, ldconfig, locale_programs, and iconvprogs
> modules.

Using 64-bit filesystem interfaces in installed programs is bug 15333.

Does this patch fix all instances where an installed program, on a 32-bit 
system, might end up using 32-bit filesystem or time interfaces (including 
any cases where APIs used in the programs need to change to fix things, 
e.g. any uses of fseek/ftell that need to become fseeko / ftello with use 
of off_t instead of long), or are there further cases left to be fixed?

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH 00/18] More y2038 fixes
  2021-06-17 17:41   ` Adhemerval Zanella
@ 2021-06-17 20:58     ` Joseph Myers
  0 siblings, 0 replies; 48+ messages in thread
From: Joseph Myers @ 2021-06-17 20:58 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Lukasz Majewski, libc-alpha

On Thu, 17 Jun 2021, Adhemerval Zanella via Libc-alpha wrote:

> > BTW: I'm wondering when the minimal, supported Linux kernel version is
> > going to be moved forward?
> 
> We usually follow the minimum LTS supported by Linux kernel developers.

However, updates are usually only done when they actually allow 
significant cleanups in glibc.  And given there isn't much benefit on 
x86_64 to increasing the minimum version, it seems like a good idea to 
first implement Carlos's proposal to remove the error at glibc startup for 
an old kernel version number (so people trying to use new glibc in 
containers on old kernels don't automatically get everything failing at 
startup, and may well have things work especially if a few syscalls have 
been backported to the old kernel).

Once Carlos's proposal is implemented, a 4.4 minimum *would* allow 
significant cleanups, such as removing most of the socketcall support.  
But it would be important to *check* the kernel support in 4.4 for each 
feature carefully before assuming it to be present globally.  (For 
example, when removing the socketcall support, we can't do so for 
getpeername or getsockname until the minimum kernel version is 4.20 or 
later (so not until 2025 based on the current EOL dates at 
<https://www.kernel.org/category/releases.html>), because that's when 
those syscalls were added to the compat syscall table for 32-bit SPARC 
programs running on 64-bit kernels.)

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH 02/18] Use LFS and 64 bit time for installed programs
  2021-06-17 20:49   ` Joseph Myers
@ 2021-06-18 18:14     ` Adhemerval Zanella
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-18 18:14 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha, Lukasz Majewski, Carlos O'Donell



On 17/06/2021 17:49, Joseph Myers wrote:
> On Thu, 17 Jun 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> The installed programs are built with a combination of different
>> values for MODULE_NAME, as below.  To enable both Long File Support
>> and 64 bt time, -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 is added for
>> nonlib, nscd, lddlibc4, ldconfig, locale_programs, and iconvprogs
>> modules.
> 
> Using 64-bit filesystem interfaces in installed programs is bug 15333.
> 
> Does this patch fix all instances where an installed program, on a 32-bit 
> system, might end up using 32-bit filesystem or time interfaces (including 
> any cases where APIs used in the programs need to change to fix things, 
> e.g. any uses of fseek/ftell that need to become fseeko / ftello with use 
> of off_t instead of long), or are there further cases left to be fixed?
> 

It seems that this patch still misses some non LFS usages:

time32:  : /lib/libmemusage.so: setitimer
non-lfs: : /lib/libnss_files-2.33.9000.so: fsetpos
non-lfs: : /lib/libnss_files-2.33.9000.so: fgetpos
non-lfs: : /lib/libutil-2.33.9000.so: open
non-lfs: : /lib/libmemusage.so: mmap
non-lfs: : /lib/libmemusage.so: lseek
non-lfs: : /lib/libnss_compat-2.33.9000.so: fsetpos
non-lfs: : /lib/libnss_compat-2.33.9000.so: fgetpos
non-lfs: : /lib/libSegFault.so: open
non-lfs: : /lib/libnss_db-2.33.9000.so: mmap
non-lfs: : /lib/libpcprofile.so: open
non-lfs: : /lib/libnss_hesiod-2.33.9000.so: fopen
non-lfs: : /lib/libresolv-2.33.9000.so: fopen
non-lfs: : /usr/lib/audit/sotruss-lib.so: fcntl
non-lfs: : /usr/lib/audit/sotruss-lib.so: open

I will send an updated version.

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

* Re: [PATCH 02/18] Use LFS and 64 bit time for installed programs
  2021-06-17 12:19   ` Andreas Schwab
@ 2021-06-18 18:50     ` Adhemerval Zanella
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-18 18:50 UTC (permalink / raw)
  To: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 17/06/2021 09:19, Andreas Schwab wrote:
> On Jun 17 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> diff --git a/Makeconfig b/Makeconfig
>> index 6482a43025..de30ba3fa6 100644
>> --- a/Makeconfig
>> +++ b/Makeconfig
>> @@ -851,6 +851,10 @@ endif
>>  # -fno-math-errno.
>>  +extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno)
>>  
>> +# Use 64 bit time_t support for installed programs
>> ++extra-time-flags = $(if $(filter nonlib nscd lddlibc4 ldconfig locale_programs iconvprogs,\
> 
> I'd suggest to put the list of module names in a variable, to make it
> easier to shorten the line.

I will add it.

> 
>> diff --git a/Makerules b/Makerules
>> index 12f1a5cb50..770a573134 100644
>> --- a/Makerules
>> +++ b/Makerules
>> @@ -1313,14 +1313,22 @@ lib := testsuite
>>  include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
>>  endif
>>  
>> -all-nonlib := $(strip $(tests-internal) $(test-internal-extras) \
>> -		      $(others) $(others-extras))
>> +all-nonlib := $(strip $(others) $(others-extras))
>>  ifneq (,$(all-nonlib))
>>  cpp-srcs-left = $(all-nonlib)
>>  lib := nonlib
>>  include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
>>  endif
>>  
>> +# All internal tests use testsuite-internal module since for 64 bit time
>> +# support is set as default for MODULE_NAME=nonlib (which include some
>> +# installed programs.
> 
> Missing close paren.

Ack.

> 
>> diff --git a/locale/localeinfo.h b/locale/localeinfo.h
>> index b3d4da0185..9e53681829 100644
>> --- a/locale/localeinfo.h
>> +++ b/locale/localeinfo.h
>> @@ -50,7 +50,7 @@ struct __locale_data
>>  {
>>    const char *name;
>>    const char *filedata;		/* Region mapping the file data.  */
>> -  off_t filesize;		/* Size of the file (and the region).  */
>> +  __off_t filesize;		/* Size of the file (and the region).  */
> 
> Why is that needed?

It is a leftover from development, I will remove it.

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

* Re: [PATCH 01/18] Use 64 bit time_t stat internally
  2021-06-17 11:50 ` [PATCH 01/18] Use 64 bit time_t stat internally Adhemerval Zanella
@ 2021-06-21  7:42   ` Lukasz Majewski
  2021-06-22 19:37   ` Florian Weimer
  1 sibling, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:42 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 36761 bytes --]

On Thu, 17 Jun 2021 08:50:47 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For the legacy ABI with supports 32 bit time_t it calls the 64 bit
> time directly, since the LFS symbols calls the 64 bit time_t ones
> internally.
> 
> Checked on i686-linux-gnu and x86_64-linux-gnu.
> ---
>  csu/check_fds.c                     |  8 ++++----
>  elf/dl-load.c                       |  8 ++++----
>  elf/dl-misc.c                       |  4 ++--
>  elf/dl-profile.c                    |  4 ++--
>  iconv/gconv_cache.c                 |  4 ++--
>  include/dirent.h                    |  2 +-
>  include/file_change_detection.h     |  6 +++---
>  inet/rcmd.c                         |  6 +++---
>  intl/loadmsgcat.c                   |  4 ++--
>  io/Makefile                         |  4 ++--
>  io/file_change_detection.c          | 16 +++++++++-------
>  io/getdirname.c                     |  6 +++---
>  libio/filedoalloc.c                 |  2 +-
>  libio/fileops.c                     |  8 ++++----
>  libio/oldfileops.c                  |  2 +-
>  libio/wfileops.c                    |  2 +-
>  locale/loadarchive.c                |  8 ++++----
>  locale/loadlocale.c                 |  6 +++---
>  nscd/nscd_helper.c                  |  4 ++--
>  nss/nss_database.c                  |  4 ++--
>  sysdeps/posix/dl-fileid.h           |  4 ++--
>  sysdeps/posix/euidaccess.c          |  4 ++--
>  sysdeps/posix/getaddrinfo.c         | 21 +++++++++++----------
>  sysdeps/posix/getcwd.c              | 15 ++++++++-------
>  sysdeps/posix/pathconf.c            |  4 ++--
>  sysdeps/posix/sysconf.c             |  4 ++--
>  sysdeps/posix/tempname.c            |  8 ++++----
>  sysdeps/unix/sysv/linux/fdopendir.c |  4 ++--
>  sysdeps/unix/sysv/linux/fexecve.c   |  4 ++--
>  sysdeps/unix/sysv/linux/opendir.c   |  7 ++++---
>  sysdeps/unix/sysv/linux/pathconf.c  |  5 +++--
>  sysdeps/unix/sysv/linux/ttyname.h   | 10 ++--------
>  sysdeps/unix/sysv/linux/ttyname_r.c | 16 ++++++++--------
>  sysvipc/ftok.c                      |  4 ++--
>  time/tzfile.c                       |  6 +++---
>  35 files changed, 112 insertions(+), 112 deletions(-)
> 
> diff --git a/csu/check_fds.c b/csu/check_fds.c
> index fbab28c284..6dc67334af 100644
> --- a/csu/check_fds.c
> +++ b/csu/check_fds.c
> @@ -69,10 +69,10 @@ check_one_fd (int fd, int mode)
>  	 Note that the following code assumes that STDIN_FILENO,
>  	 STDOUT_FILENO, STDERR_FILENO are the three lowest file
>  	 decsriptor numbers, in this order.  */
> -      struct stat64 st;
> -      if (__builtin_expect (nullfd != fd, 0)
> -	  || __builtin_expect (__fstat64 (fd, &st), 0) != 0
> -	  || __builtin_expect (S_ISCHR (st.st_mode), 1) == 0
> +      struct __stat64_t64 st;
> +      if (__glibc_unlikely (nullfd != fd)
> +	  || __glibc_likely (__fstat64_time64 (fd, &st) != 0)
> +	  || __glibc_unlikely (S_ISCHR (st.st_mode) == 0)
>  	  || st.st_rdev != dev)
>  	/* We cannot even give an error message here since it would
>  	   run into the same problems.  */
> diff --git a/elf/dl-load.c b/elf/dl-load.c
> index 918ec7546c..a08df001af 100644
> --- a/elf/dl-load.c
> +++ b/elf/dl-load.c
> @@ -1946,11 +1946,11 @@ open_path (const char *name, size_t namelen,
> int mode, {
>  		  /* We failed to open machine dependent library.
> Let's test whether there is any directory at all.  */
> -		  struct stat64 st;
> +		  struct __stat64_t64 st;
>  
>  		  buf[buflen - namelen - 1] = '\0';
>  
> -		  if (__stat64 (buf, &st) != 0
> +		  if (__stat64_time64 (buf, &st) != 0
>  		      || ! S_ISDIR (st.st_mode))
>  		    /* The directory does not exist or it is no
> directory.  */ this_dir->status[cnt] = nonexisting;
> @@ -1968,9 +1968,9 @@ open_path (const char *name, size_t namelen,
> int mode, /* This is an extra security effort to make sure nobody can
>  		 preload broken shared objects which are in the
> trusted directories and so exploit the bugs.  */
> -	      struct stat64 st;
> +	      struct __stat64_t64 st;
>  
> -	      if (__fstat64 (fd, &st) != 0
> +	      if (__fstat64_time64 (fd, &st) != 0
>  		  || (st.st_mode & S_ISUID) == 0)
>  		{
>  		  /* The shared object cannot be tested for being
> SUID diff --git a/elf/dl-misc.c b/elf/dl-misc.c
> index d4803bba4e..b256d792c6 100644
> --- a/elf/dl-misc.c
> +++ b/elf/dl-misc.c
> @@ -43,11 +43,11 @@ void *
>  _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int
> prot) {
>    void *result = MAP_FAILED;
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    int fd = __open64_nocancel (file, O_RDONLY | O_CLOEXEC);
>    if (fd >= 0)
>      {
> -      if (__fstat64 (fd, &st) >= 0)
> +      if (__fstat64_time64 (fd, &st) >= 0)
>  	{
>  	  *sizep = st.st_size;
>  
> diff --git a/elf/dl-profile.c b/elf/dl-profile.c
> index 35b03959bc..088c023d95 100644
> --- a/elf/dl-profile.c
> +++ b/elf/dl-profile.c
> @@ -185,7 +185,7 @@ _dl_start_profile (void)
>  {
>    char *filename;
>    int fd;
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    const ElfW(Phdr) *ph;
>    ElfW(Addr) mapstart = ~((ElfW(Addr)) 0);
>    ElfW(Addr) mapend = 0;
> @@ -342,7 +342,7 @@ _dl_start_profile (void)
>        return;
>      }
>  
> -  if (__fstat64 (fd, &st) < 0 || !S_ISREG (st.st_mode))
> +  if (__fstat64_time64 (fd, &st) < 0 || !S_ISREG (st.st_mode))
>      {
>        /* Not stat'able or not a regular file => don't use it.  */
>        errstr = "%s: cannot stat file: %s\n";
> diff --git a/iconv/gconv_cache.c b/iconv/gconv_cache.c
> index 642cc731eb..68d6386d01 100644
> --- a/iconv/gconv_cache.c
> +++ b/iconv/gconv_cache.c
> @@ -48,7 +48,7 @@ int
>  __gconv_load_cache (void)
>  {
>    int fd;
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    struct gconvcache_header *header;
>  
>    /* We cannot use the cache if the GCONV_PATH environment variable
> is @@ -64,7 +64,7 @@ __gconv_load_cache (void)
>      return -1;
>  
>    /* Get information about the file.  */
> -  if (__builtin_expect (__fstat64 (fd, &st), 0) < 0
> +  if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0)
>        /* We do not have to start looking at the file if it cannot
> contain at least the cache header.  */
>        || (size_t) st.st_size < sizeof (struct gconvcache_header))
> diff --git a/include/dirent.h b/include/dirent.h
> index f1d7e8359c..d7567f5e86 100644
> --- a/include/dirent.h
> +++ b/include/dirent.h
> @@ -49,7 +49,7 @@ extern int __versionsort64 (const struct dirent64
> **a, const struct dirent64 **b)
>       __attribute_pure__;
>  extern DIR *__alloc_dir (int fd, bool close_fd, int flags,
> -			 const struct stat64 *statp)
> +			 const struct __stat64_t64 *statp)
>       __nonnull (4) attribute_hidden;
>  extern __typeof (rewinddir) __rewinddir;
>  extern __typeof (seekdir) __seekdir;
> diff --git a/include/file_change_detection.h
> b/include/file_change_detection.h index 9de2bd0b79..953de7c7fd 100644
> --- a/include/file_change_detection.h
> +++ b/include/file_change_detection.h
> @@ -33,8 +33,8 @@ struct file_change_detection
>    off64_t size;
>  
>    ino64_t ino;
> -  struct timespec mtime;
> -  struct timespec ctime;
> +  struct __timespec64 mtime;
> +  struct __timespec64 ctime;
>  };
>  
>  /* Returns true if *LEFT and *RIGHT describe the same version of the
> @@ -45,7 +45,7 @@ bool __file_is_unchanged (const struct
> file_change_detection *left, /* Extract file change information to
> *FILE from the stat buffer *ST.  */
>  void __file_change_detection_for_stat (struct file_change_detection
> *file,
> -                                       const struct stat64 *st);
> +                                       const struct __stat64_t64
> *st); 
>  /* Writes file change information for PATH to *FILE.  Returns true on
>     success.  For benign errors, *FILE is cleared, and true is
> diff --git a/inet/rcmd.c b/inet/rcmd.c
> index 0cfdaee15e..0d6b595572 100644
> --- a/inet/rcmd.c
> +++ b/inet/rcmd.c
> @@ -468,14 +468,14 @@ ruserok (const char *rhost, int superuser,
> const char *ruser, static FILE *
>  iruserfopen (const char *file, uid_t okuser)
>  {
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    char *cp = NULL;
>    FILE *res = NULL;
>  
>    /* If not a regular file, if owned by someone other than user or
>       root, if writeable by anyone but the owner, or if hardlinked
>       anywhere, quit.  */
> -  if (__lstat64 (file, &st))
> +  if (__lstat64_time64 (file, &st))
>      cp = _("lstat failed");
>    else if (!S_ISREG (st.st_mode))
>      cp = _("not regular file");
> @@ -484,7 +484,7 @@ iruserfopen (const char *file, uid_t okuser)
>        res = fopen (file, "rce");
>        if (!res)
>  	cp = _("cannot open");
> -      else if (__fstat64 (fileno (res), &st) < 0)
> +      else if (__fstat64_time64 (fileno (res), &st) < 0)
>  	cp = _("fstat failed");
>        else if (st.st_uid && st.st_uid != okuser)
>  	cp = _("bad owner");
> diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
> index 4fda9b0219..30588e9996 100644
> --- a/intl/loadmsgcat.c
> +++ b/intl/loadmsgcat.c
> @@ -756,7 +756,7 @@ _nl_load_domain (struct loaded_l10nfile
> *domain_file, int fd = -1;
>    size_t size;
>  #ifdef _LIBC
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>  #else
>    struct stat st;
>  #endif
> @@ -804,7 +804,7 @@ _nl_load_domain (struct loaded_l10nfile
> *domain_file, /* We must know about the size of the file.  */
>    if (
>  #ifdef _LIBC
> -      __builtin_expect (__fstat64 (fd, &st) != 0, 0)
> +      __builtin_expect (__fstat64_time64 (fd, &st) != 0, 0)
>  #else
>        __builtin_expect (fstat (fd, &st) != 0, 0)
>  #endif
> diff --git a/io/Makefile b/io/Makefile
> index ba8bd37355..1a16990205 100644
> --- a/io/Makefile
> +++ b/io/Makefile
> @@ -69,7 +69,7 @@ tests		:= test-utime test-stat
> test-stat2 test-lfs tst-getcwd \ tst-posix_fallocate
> tst-posix_fallocate64 \ tst-fts tst-fts-lfs tst-open-tmpfile \
>  		   tst-copy_file_range tst-getcwd-abspath tst-lockf \
> -		   tst-ftw-lnk tst-file_change_detection tst-lchmod \
> +		   tst-ftw-lnk tst-lchmod \
>  		   tst-ftw-bz26353 tst-stat tst-stat-lfs \
>  		   tst-utime \
>  		   tst-utimes \
> @@ -90,7 +90,7 @@ tests-time64 := \
>    tst-utimes-time64 \
>  
>  # Likewise for statx, but we do not need static linking here.
> -tests-internal += tst-statx
> +tests-internal += tst-statx tst-file_change_detection
>  tests-static += tst-statx
>  
>  ifeq ($(run-built-tests),yes)
> diff --git a/io/file_change_detection.c b/io/file_change_detection.c
> index 9871bc9166..ac5e451513 100644
> --- a/io/file_change_detection.c
> +++ b/io/file_change_detection.c
> @@ -44,7 +44,7 @@ libc_hidden_def (__file_is_unchanged)
>  
>  void
>  __file_change_detection_for_stat (struct file_change_detection *file,
> -                                  const struct stat64 *st)
> +                                  const struct __stat64_t64 *st)
>  {
>    if (S_ISDIR (st->st_mode))
>      /* Treat as empty file.  */
> @@ -56,8 +56,10 @@ __file_change_detection_for_stat (struct
> file_change_detection *file, {
>        file->size = st->st_size;
>        file->ino = st->st_ino;
> -      file->mtime = st->st_mtim;
> -      file->ctime = st->st_ctim;
> +      file->mtime = (struct __timespec64 ) { .tv_sec  =
> st->st_mtim.tv_sec,
> +					     .tv_nsec =
> st->st_mtim.tv_nsec };
> +      file->ctime = (struct __timespec64 ) { .tv_sec  =
> st->st_ctim.tv_sec,
> +					     .tv_nsec =
> st->st_mtim.tv_nsec }; }
>  }
>  libc_hidden_def (__file_change_detection_for_stat)
> @@ -66,8 +68,8 @@ bool
>  __file_change_detection_for_path (struct file_change_detection *file,
>                                    const char *path)
>  {
> -  struct stat64 st;
> -  if (__stat64 (path, &st) != 0)
> +  struct __stat64_t64 st;
> +  if (__stat64_time64 (path, &st) != 0)
>      switch (errno)
>        {
>        case EACCES:
> @@ -104,8 +106,8 @@ __file_change_detection_for_fp (struct
> file_change_detection *file, }
>    else
>      {
> -      struct stat64 st;
> -      if (__fstat64 (__fileno (fp), &st) != 0)
> +      struct __stat64_t64 st;
> +      if (__fstat64_time64 (__fileno (fp), &st) != 0)
>          /* If we already have a file descriptor, all errors are
> fatal.  */ return false;
>        else
> diff --git a/io/getdirname.c b/io/getdirname.c
> index 32b5ab4b6c..f29e910b37 100644
> --- a/io/getdirname.c
> +++ b/io/getdirname.c
> @@ -28,12 +28,12 @@ char *
>  get_current_dir_name (void)
>  {
>    char *pwd;
> -  struct stat64 dotstat, pwdstat;
> +  struct __stat64_t64 dotstat, pwdstat;
>  
>    pwd = getenv ("PWD");
>    if (pwd != NULL
> -      && __stat64 (".", &dotstat) == 0
> -      && __stat64 (pwd, &pwdstat) == 0
> +      && __stat64_time64 (".", &dotstat) == 0
> +      && __stat64_time64 (pwd, &pwdstat) == 0
>        && pwdstat.st_dev == dotstat.st_dev
>        && pwdstat.st_ino == dotstat.st_ino)
>      /* The PWD value is correct.  Use it.  */
> diff --git a/libio/filedoalloc.c b/libio/filedoalloc.c
> index 7afa3cb683..c792eec88f 100644
> --- a/libio/filedoalloc.c
> +++ b/libio/filedoalloc.c
> @@ -78,7 +78,7 @@ _IO_file_doallocate (FILE *fp)
>  {
>    size_t size;
>    char *p;
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>  
>    size = BUFSIZ;
>    if (fp->_fileno >= 0 && __builtin_expect (_IO_SYSSTAT (fp, &st),
> 0) >= 0) diff --git a/libio/fileops.c b/libio/fileops.c
> index a71a567547..e8ee374821 100644
> --- a/libio/fileops.c
> +++ b/libio/fileops.c
> @@ -545,7 +545,7 @@ libc_hidden_ver (_IO_new_file_underflow,
> _IO_file_underflow) static int
>  mmap_remap_check (FILE *fp)
>  {
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>  
>    if (_IO_SYSSTAT (fp, &st) == 0
>        && S_ISREG (st.st_mode) && st.st_size != 0
> @@ -663,7 +663,7 @@ decide_maybe_mmap (FILE *fp)
>       file descriptors are for mmap-able objects and on 32-bit
>       machines we don't want to map files which are too large since
>       this would require too much virtual memory.  */
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>  
>    if (_IO_SYSSTAT (fp, &st) == 0
>        && S_ISREG (st.st_mode) && st.st_size != 0
> @@ -962,7 +962,7 @@ _IO_new_file_seekoff (FILE *fp, off64_t offset,
> int dir, int mode) break;
>      case _IO_seek_end:
>        {
> -	struct stat64 st;
> +	struct __stat64_t64 st;
>  	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
>  	  {
>  	    offset += st.st_size;
> @@ -1145,7 +1145,7 @@ libc_hidden_def (_IO_file_seek)
>  int
>  _IO_file_stat (FILE *fp, void *st)
>  {
> -  return __fstat64 (fp->_fileno, (struct stat64 *) st);
> +  return __fstat64_time64 (fp->_fileno, (struct __stat64_t64 *) st);
>  }
>  libc_hidden_def (_IO_file_stat)
>  
> diff --git a/libio/oldfileops.c b/libio/oldfileops.c
> index ed235360ad..ed3c98bd6d 100644
> --- a/libio/oldfileops.c
> +++ b/libio/oldfileops.c
> @@ -487,7 +487,7 @@ _IO_old_file_seekoff (FILE *fp, off64_t offset,
> int dir, int mode) break;
>      case _IO_seek_end:
>        {
> -	struct stat64 st;
> +	struct __stat64_t64 st;
>  	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
>  	  {
>  	    offset += st.st_size;
> diff --git a/libio/wfileops.c b/libio/wfileops.c
> index 5d23566171..37f44780f8 100644
> --- a/libio/wfileops.c
> +++ b/libio/wfileops.c
> @@ -840,7 +840,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int
> dir, int mode) break;
>      case _IO_seek_end:
>        {
> -	struct stat64 st;
> +	struct __stat64_t64 st;
>  	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
>  	  {
>  	    offset += st.st_size;
> diff --git a/locale/loadarchive.c b/locale/loadarchive.c
> index 4177fc8972..512769eaec 100644
> --- a/locale/loadarchive.c
> +++ b/locale/loadarchive.c
> @@ -78,7 +78,7 @@ static struct archmapped *archmapped;
>     ARCHMAPPED points to this; if mapping the archive header failed,
>     then headmap.ptr is null.  */
>  static struct archmapped headmap;
> -static struct stat64 archive_stat; /* stat of archive when header
> mapped.  */ +static struct __stat64_t64 archive_stat; /* stat of
> archive when header mapped.  */ 
>  /* Record of locales that we have already loaded from the archive.
> */ struct locale_in_archive
> @@ -207,7 +207,7 @@ _nl_load_locale_from_archive (int category, const
> char **namep) /* Cannot open the archive, for whatever reason.  */
>  	return NULL;
>  
> -      if (__fstat64 (fd, &archive_stat) == -1)
> +      if (__fstat64_time64 (fd, &archive_stat) == -1)
>  	{
>  	  /* stat failed, very strange.  */
>  	close_and_out:
> @@ -396,7 +396,7 @@ _nl_load_locale_from_archive (int category, const
> char **namep) /* Open the file if it hasn't happened yet.  */
>  	  if (fd == -1)
>  	    {
> -	      struct stat64 st;
> +	      struct __stat64_t64 st;
>  	      fd = __open_nocancel (archfname,
>  				    O_RDONLY|O_LARGEFILE|O_CLOEXEC);
>  	      if (fd == -1)
> @@ -405,7 +405,7 @@ _nl_load_locale_from_archive (int category, const
> char **namep) /* Now verify we think this is really the same archive
> file we opened before.  If it has been changed we cannot trust
>  		 the header we read previously.  */
> -	      if (__fstat64 (fd, &st) < 0
> +	      if (__fstat64_time64 (fd, &st) < 0
>  		  || st.st_size != archive_stat.st_size
>  		  || st.st_mtime != archive_stat.st_mtime
>  		  || st.st_dev != archive_stat.st_dev
> diff --git a/locale/loadlocale.c b/locale/loadlocale.c
> index 9c03490883..f4e6cc9fc2 100644
> --- a/locale/loadlocale.c
> +++ b/locale/loadlocale.c
> @@ -167,7 +167,7 @@ _nl_load_locale (struct loaded_l10nfile *file,
> int category) {
>    int fd;
>    void *filedata;
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    struct __locale_data *newdata;
>    int save_err;
>    int alloc = ld_mapped;
> @@ -180,7 +180,7 @@ _nl_load_locale (struct loaded_l10nfile *file,
> int category) /* Cannot open the file.  */
>      return;
>  
> -  if (__builtin_expect (__fstat64 (fd, &st), 0) < 0)
> +  if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0))
>      {
>      puntfd:
>        __close_nocancel_nostatus (fd);
> @@ -206,7 +206,7 @@ _nl_load_locale (struct loaded_l10nfile *file,
> int category) if (__builtin_expect (fd, 0) < 0)
>  	return;
>  
> -      if (__builtin_expect (__fstat64 (fd, &st), 0) < 0)
> +      if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0))
>  	goto puntfd;
>      }
>  
> diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
> index 462504d828..06ba7476e5 100644
> --- a/nscd/nscd_helper.c
> +++ b/nscd/nscd_helper.c
> @@ -324,8 +324,8 @@ __nscd_get_mapping (request_type type, const char
> *key, 
>    if (__glibc_unlikely (n == keylen))
>      {
> -      struct stat64 st;
> -      if (__builtin_expect (__fstat64 (mapfd, &st) != 0, 0)
> +      struct __stat64_t64 st;
> +      if (__glibc_unlikely (__fstat64_time64 (mapfd, &st) != 0)
>  	  || __builtin_expect (st.st_size < sizeof (struct
> database_pers_head), 0))
>  	goto out_close;
> diff --git a/nss/nss_database.c b/nss/nss_database.c
> index 1e11294406..ab121cb371 100644
> --- a/nss/nss_database.c
> +++ b/nss/nss_database.c
> @@ -394,7 +394,7 @@ nss_database_check_reload_and_get (struct
> nss_database_state *local, nss_action_list *result,
>                                     enum nss_database database_index)
>  {
> -  struct stat64 str;
> +  struct __stat64_t64 str;
>  
>    /* Acquire MO is needed because the thread that sets
> reload_disabled may have loaded the configuration first, so
> synchronize with the @@ -424,7 +424,7 @@
> nss_database_check_reload_and_get (struct nss_database_state *local,
> errors here are very unlikely, but the chance that we're entering a
> container is also very unlikely, so we err on the side of both very
> unlikely things not happening at the same time.  */
> -  if (__stat64 ("/", &str) != 0
> +  if (__stat64_time64 ("/", &str) != 0
>        || (local->root_ino != 0
>  	  && (str.st_ino != local->root_ino
>  	      ||  str.st_dev != local->root_dev)))
> diff --git a/sysdeps/posix/dl-fileid.h b/sysdeps/posix/dl-fileid.h
> index 0bb6794dbe..bf437f3d71 100644
> --- a/sysdeps/posix/dl-fileid.h
> +++ b/sysdeps/posix/dl-fileid.h
> @@ -32,9 +32,9 @@ struct r_file_id
>  static inline bool
>  _dl_get_file_id (int fd, struct r_file_id *id)
>  {
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>  
> -  if (__glibc_unlikely (__fstat64 (fd, &st) < 0))
> +  if (__glibc_unlikely (__fstat64_time64 (fd, &st) < 0))
>      return false;
>  
>    id->dev = st.st_dev;
> diff --git a/sysdeps/posix/euidaccess.c b/sysdeps/posix/euidaccess.c
> index 26ebb432a2..86f3285471 100644
> --- a/sysdeps/posix/euidaccess.c
> +++ b/sysdeps/posix/euidaccess.c
> @@ -119,7 +119,7 @@ int group_member ();
>  int
>  euidaccess (const char *path, int mode)
>  {
> -  struct stat64 stats;
> +  struct __stat64_t64 stats;
>    int granted;
>  
>  #ifdef	_LIBC
> @@ -140,7 +140,7 @@ euidaccess (const char *path, int mode)
>      return access (path, mode);
>  #endif
>  
> -  if (__stat64 (path, &stats))
> +  if (__stat64_time64 (path, &stats))
>      return -1;
>  
>    mode &= (X_OK | W_OK | R_OK);	/* Clear any bogus bits. */
> diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
> index b7e1aee80f..b2831508c4 100644
> --- a/sysdeps/posix/getaddrinfo.c
> +++ b/sysdeps/posix/getaddrinfo.c
> @@ -1636,16 +1636,17 @@ static int gaiconf_reload_flag_ever_set;
>  /* Last modification time.  */
>  #ifdef _STATBUF_ST_NSEC
>  
> -static struct timespec gaiconf_mtime;
> +static struct __timespec64 gaiconf_mtime;
>  
>  static inline void
> -save_gaiconf_mtime (const struct stat64 *st)
> +save_gaiconf_mtime (const struct __stat64_t64 *st)
>  {
> -  gaiconf_mtime = st->st_mtim;
> +  gaiconf_mtime = (struct __timespec64) { .tv_sec  =
> st->st_mtim.tv_sec,
> +					  .tv_nsec =
> st->st_mtim.tv_nsec }; }
>  
>  static inline bool
> -check_gaiconf_mtime (const struct stat64 *st)
> +check_gaiconf_mtime (const struct __stat64_t64 *st)
>  {
>    return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
>            && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
> @@ -1656,13 +1657,13 @@ check_gaiconf_mtime (const struct stat64 *st)
>  static time_t gaiconf_mtime;
>  
>  static inline void
> -save_gaiconf_mtime (const struct stat64 *st)
> +save_gaiconf_mtime (const struct __stat64_t64 *st)
>  {
>    gaiconf_mtime = st->st_mtime;
>  }
>  
>  static inline bool
> -check_gaiconf_mtime (const struct stat64 *st)
> +check_gaiconf_mtime (const struct __stat64_t64 *st)
>  {
>    return st->st_mtime == gaiconf_mtime;
>  }
> @@ -1777,8 +1778,8 @@ gaiconf_init (void)
>    FILE *fp = fopen (GAICONF_FNAME, "rce");
>    if (fp != NULL)
>      {
> -      struct stat64 st;
> -      if (__fstat64 (fileno (fp), &st) != 0)
> +      struct __stat64_t64 st;
> +      if (__fstat64_time64 (fileno (fp), &st) != 0)
>  	{
>  	  fclose (fp);
>  	  goto no_file;
> @@ -2130,8 +2131,8 @@ gaiconf_init (void)
>  static void
>  gaiconf_reload (void)
>  {
> -  struct stat64 st;
> -  if (__stat64 (GAICONF_FNAME, &st) != 0
> +  struct __stat64_t64 st;
> +  if (__stat64_time64 (GAICONF_FNAME, &st) != 0
>        || !check_gaiconf_mtime (&st))
>      gaiconf_init ();
>  }
> diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
> index f11644aae7..13680026ff 100644
> --- a/sysdeps/posix/getcwd.c
> +++ b/sysdeps/posix/getcwd.c
> @@ -183,7 +183,7 @@ __getcwd_generic (char *buf, size_t size)
>    ino_t rootino, thisino;
>    char *dir;
>    register char *dirp;
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    size_t allocated = size;
>    size_t used;
>  
> @@ -249,12 +249,12 @@ __getcwd_generic (char *buf, size_t size)
>    dirp = dir + allocated;
>    *--dirp = '\0';
>  
> -  if (__lstat64 (".", &st) < 0)
> +  if (__lstat64_time64 (".", &st) < 0)
>      goto lose;
>    thisdev = st.st_dev;
>    thisino = st.st_ino;
>  
> -  if (__lstat64 ("/", &st) < 0)
> +  if (__lstat64_time64 ("/", &st) < 0)
>      goto lose;
>    rootdev = st.st_dev;
>    rootino = st.st_ino;
> @@ -276,12 +276,12 @@ __getcwd_generic (char *buf, size_t size)
>        if (fd < 0)
>          goto lose;
>        fd_needs_closing = true;
> -      parent_status = __fstat64 (fd, &st);
> +      parent_status = __fstat64_time64 (fd, &st);
>  #else
>        dotlist[dotlen++] = '.';
>        dotlist[dotlen++] = '.';
>        dotlist[dotlen] = '\0';
> -      parent_status = __lstat64 (dotlist, &st);
> +      parent_status = __lstat64_time64 (dotlist, &st);
>  #endif
>        if (parent_status != 0)
>          goto lose;
> @@ -353,7 +353,8 @@ __getcwd_generic (char *buf, size_t size)
>            {
>              int entry_status;
>  #if HAVE_OPENAT_SUPPORT
> -            entry_status = __fstatat64 (fd, d->d_name, &st,
> AT_SYMLINK_NOFOLLOW);
> +            entry_status = __fstatat64_time64 (fd, d->d_name, &st,
> +					       AT_SYMLINK_NOFOLLOW);
>  #else
>              /* Compute size needed for this file name, or for the
> file name ".." in the same directory, whichever is larger.
> @@ -390,7 +391,7 @@ __getcwd_generic (char *buf, size_t size)
>                }
>  
>              memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN
> (d));
> -            entry_status = __lstat64 (dotlist, &st);
> +            entry_status = __lstat64_time64 (dotlist, &st);
>  #endif
>              /* We don't fail here if we cannot stat() a directory
> entry. This can happen when (network) file systems fail.  If this
> diff --git a/sysdeps/posix/pathconf.c b/sysdeps/posix/pathconf.c
> index 9eb17d1536..89fcfad49d 100644
> --- a/sysdeps/posix/pathconf.c
> +++ b/sysdeps/posix/pathconf.c
> @@ -129,9 +129,9 @@ __pathconf (const char *path, int name)
>  #ifdef	_POSIX_ASYNC_IO
>        {
>  	/* AIO is only allowed on regular files and block devices.
> */
> -	struct stat64 st;
> +	struct __stat64_t64 st;
>  
> -	if (__stat64 (path, &st) < 0
> +	if (__stat64_time64 (path, &st) < 0
>  	    || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode)))
>  	  return -1;
>  	else
> diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c
> index 54d6046d00..3e8ec5cd51 100644
> --- a/sysdeps/posix/sysconf.c
> +++ b/sysdeps/posix/sysconf.c
> @@ -1215,8 +1215,8 @@ __sysconf_check_spec (const char *spec)
>  		   "/POSIX_V6_", sizeof ("/POSIX_V6_") - 1),
>  	  spec, speclen + 1);
>  
> -  struct stat64 st;
> -  long int ret = __stat64 (name, &st) >= 0 ? 1 : -1;
> +  struct __stat64_t64 st;
> +  long int ret = __stat64_time64 (name, &st) >= 0 ? 1 : -1;
>  
>    __set_errno (save_errno);
>    return ret;
> diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
> index 5f804b38d7..ff38f1e31f 100644
> --- a/sysdeps/posix/tempname.c
> +++ b/sysdeps/posix/tempname.c
> @@ -55,14 +55,14 @@
>  #include <time.h>
>  
>  #if _LIBC
> -# define struct_stat64 struct stat64
> +# define struct_stat64 struct __stat64_t64
>  # define __secure_getenv __libc_secure_getenv
>  #else
>  # define struct_stat64 struct stat
>  # define __gen_tempname gen_tempname
>  # define __mkdir mkdir
>  # define __open open
> -# define __lstat64(file, buf) lstat (file, buf)
> +# define __lstat64_time64(file, buf) lstat (file, buf)
>  # define __stat64(file, buf) stat (file, buf)
>  # define __getrandom getrandom
>  # define __clock_gettime64 clock_gettime
> @@ -99,7 +99,7 @@ static int
>  direxists (const char *dir)
>  {
>    struct_stat64 buf;
> -  return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
> +  return __stat64_time64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
>  }
>  
>  /* Path search algorithm, for tmpnam, tmpfile, etc.  If DIR is
> @@ -191,7 +191,7 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
>  {
>    struct_stat64 st;
>  
> -  if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW)
> +  if (__lstat64_time64 (tmpl, &st) == 0 || errno == EOVERFLOW)
>      __set_errno (EEXIST);
>    return errno == ENOENT ? 0 : -1;
>  }
> diff --git a/sysdeps/unix/sysv/linux/fdopendir.c
> b/sysdeps/unix/sysv/linux/fdopendir.c index ede43f2485..32ec10e206
> 100644 --- a/sysdeps/unix/sysv/linux/fdopendir.c
> +++ b/sysdeps/unix/sysv/linux/fdopendir.c
> @@ -27,9 +27,9 @@
>  DIR *
>  __fdopendir (int fd)
>  {
> -  struct stat64 statbuf;
> +  struct __stat64_t64 statbuf;
>  
> -  if (__builtin_expect (__fstat64 (fd, &statbuf), 0) < 0)
> +  if (__glibc_unlikely (__fstat64_time64 (fd, &statbuf) < 0))
>      return NULL;
>    if (__glibc_unlikely (! S_ISDIR (statbuf.st_mode)))
>      {
> diff --git a/sysdeps/unix/sysv/linux/fexecve.c
> b/sysdeps/unix/sysv/linux/fexecve.c index df25c2acb8..4dfcaeedc1
> 100644 --- a/sysdeps/unix/sysv/linux/fexecve.c
> +++ b/sysdeps/unix/sysv/linux/fexecve.c
> @@ -58,8 +58,8 @@ fexecve (int fd, char *const argv[], char *const
> envp[]) 
>    /* We come here only if the 'execve' call fails.  Determine whether
>       /proc is mounted.  If not we return ENOSYS.  */
> -  struct stat64 st;
> -  if (__stat64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
> +  struct __stat64_t64 st;
> +  if (__stat64_time64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
>      save = ENOSYS;
>  
>    __set_errno (save);
> diff --git a/sysdeps/unix/sysv/linux/opendir.c
> b/sysdeps/unix/sysv/linux/opendir.c index 4020a826f9..48f254d169
> 100644 --- a/sysdeps/unix/sysv/linux/opendir.c
> +++ b/sysdeps/unix/sysv/linux/opendir.c
> @@ -49,8 +49,8 @@ opendir_tail (int fd)
>    /* Now make sure this really is a directory and nothing changed
> since the `stat' call.  The S_ISDIR check is superfluous if
> O_DIRECTORY works, but it's cheap and we need the stat call for
> st_blksize anyway.  */
> -  struct stat64 statbuf;
> -  if (__glibc_unlikely (__fstat64 (fd, &statbuf) < 0))
> +  struct __stat64_t64 statbuf;
> +  if (__glibc_unlikely (__fstat64_time64 (fd, &statbuf) < 0))
>      goto lose;
>    if (__glibc_unlikely (! S_ISDIR (statbuf.st_mode)))
>      {
> @@ -88,7 +88,8 @@ __opendir (const char *name)
>  weak_alias (__opendir, opendir)
>  
>  DIR *
> -__alloc_dir (int fd, bool close_fd, int flags, const struct stat64
> *statp) +__alloc_dir (int fd, bool close_fd, int flags,
> +	     const struct __stat64_t64 *statp)
>  {
>    /* We have to set the close-on-exit flag if the user provided the
>       file descriptor.  */
> diff --git a/sysdeps/unix/sysv/linux/pathconf.c
> b/sysdeps/unix/sysv/linux/pathconf.c index f37e8aaf68..b599a66c93
> 100644 --- a/sysdeps/unix/sysv/linux/pathconf.c
> +++ b/sysdeps/unix/sysv/linux/pathconf.c
> @@ -65,9 +65,10 @@ distinguish_extX (const struct statfs *fsbuf,
> const char *file, int fd) {
>    char buf[64];
>    char path[PATH_MAX];
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>  
> -  if ((file == NULL ? __fstat64 (fd, &st) : __stat64 (file, &st)) !=
> 0)
> +  if ((file == NULL ? __fstat64_time64 (fd, &st)
> +		    : __stat64_time64 (file, &st)) != 0)
>      /* Strange.  The statfd call worked, but stat fails.  Default to
>         the more pessimistic value.  */
>      return EXT2_LINK_MAX;
> diff --git a/sysdeps/unix/sysv/linux/ttyname.h
> b/sysdeps/unix/sysv/linux/ttyname.h index 0a0048cc02..5dcbfef973
> 100644 --- a/sysdeps/unix/sysv/linux/ttyname.h
> +++ b/sysdeps/unix/sysv/linux/ttyname.h
> @@ -25,24 +25,18 @@
>     linux/Documentation/devices.txt (on linux < 4.10) or
>     linux/Documentation/admin-guide/devices.txt (on linux >= 4.10).
> */ static inline bool
> -is_pty (struct stat64 *sb)
> +is_pty (struct __stat64_t64 *sb)
>  {
> -#ifdef _STATBUF_ST_RDEV
>    int m = __gnu_dev_major (sb->st_rdev);
>    return (136 <= m && m <= 143);
> -#else
> -  return false;
> -#endif
>  }
>  
>  static inline bool
> -is_mytty (const struct stat64 *mytty, const struct stat64 *maybe)
> +is_mytty (const struct __stat64_t64 *mytty, const struct
> __stat64_t64 *maybe) {
>    return (maybe->st_ino == mytty->st_ino
>  	  && maybe->st_dev == mytty->st_dev
> -#ifdef _STATBUF_ST_RDEV
>  	  && S_ISCHR (maybe->st_mode)
>  	  && maybe->st_rdev == mytty->st_rdev
> -#endif
>  	  );
>  }
> diff --git a/sysdeps/unix/sysv/linux/ttyname_r.c
> b/sysdeps/unix/sysv/linux/ttyname_r.c index 899a851a83..9ef9f42883
> 100644 --- a/sysdeps/unix/sysv/linux/ttyname_r.c
> +++ b/sysdeps/unix/sysv/linux/ttyname_r.c
> @@ -31,15 +31,15 @@
>  #include "ttyname.h"
>  
>  static int getttyname_r (char *buf, size_t buflen,
> -			 const struct stat64 *mytty, int save,
> +			 const struct __stat64_t64 *mytty, int save,
>  			 int *dostat);
>  
>  static int
>  attribute_compat_text_section
> -getttyname_r (char *buf, size_t buflen, const struct stat64 *mytty,
> +getttyname_r (char *buf, size_t buflen, const struct __stat64_t64
> *mytty, int save, int *dostat)
>  {
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    DIR *dirstream;
>    struct dirent64 *d;
>    size_t devlen = strlen (buf);
> @@ -71,7 +71,7 @@ getttyname_r (char *buf, size_t buflen, const
> struct stat64 *mytty, cp = __stpncpy (buf + devlen, d->d_name,
> needed); cp[0] = '\0';
>  
> -	if (__stat64 (buf, &st) == 0
> +	if (__stat64_time64 (buf, &st) == 0
>  	    && is_mytty (mytty, &st))
>  	  {
>  	    (void) __closedir (dirstream);
> @@ -93,7 +93,7 @@ int
>  __ttyname_r (int fd, char *buf, size_t buflen)
>  {
>    struct fd_to_filename filename;
> -  struct stat64 st, st1;
> +  struct __stat64_t64 st, st1;
>    int dostat = 0;
>    int doispty = 0;
>    int save = errno;
> @@ -118,7 +118,7 @@ __ttyname_r (int fd, char *buf, size_t buflen)
>    if (__glibc_unlikely (__tcgetattr (fd, &term) < 0))
>      return errno;
>  
> -  if (__fstat64 (fd, &st) < 0)
> +  if (__fstat64_time64 (fd, &st) < 0)
>      return errno;
>  
>    /* We try using the /proc filesystem.  */
> @@ -144,7 +144,7 @@ __ttyname_r (int fd, char *buf, size_t buflen)
>  
>        /* Verify readlink result, fall back on iterating through
> devices.  */ if (buf[0] == '/'
> -	  && __stat64 (buf, &st1) == 0
> +	  && __stat64_time64 (buf, &st1) == 0
>  	  && is_mytty (&st, &st1))
>  	return 0;
>  
> @@ -155,7 +155,7 @@ __ttyname_r (int fd, char *buf, size_t buflen)
>    memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/"));
>    buflen -= sizeof ("/dev/pts/") - 1;
>  
> -  if (__stat64 (buf, &st1) == 0 && S_ISDIR (st1.st_mode))
> +  if (__stat64_time64 (buf, &st1) == 0 && S_ISDIR (st1.st_mode))
>      {
>        ret = getttyname_r (buf, buflen, &st, save,
>  			  &dostat);
> diff --git a/sysvipc/ftok.c b/sysvipc/ftok.c
> index 2e39c74415..bd633bd395 100644
> --- a/sysvipc/ftok.c
> +++ b/sysvipc/ftok.c
> @@ -22,10 +22,10 @@
>  key_t
>  ftok (const char *pathname, int proj_id)
>  {
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    key_t key;
>  
> -  if (__stat64 (pathname, &st) < 0)
> +  if (__stat64_time64 (pathname, &st) < 0)
>      return (key_t) -1;
>  
>    key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16)
> diff --git a/time/tzfile.c b/time/tzfile.c
> index 040a5e341f..4377018a55 100644
> --- a/time/tzfile.c
> +++ b/time/tzfile.c
> @@ -150,9 +150,9 @@ __tzfile_read (const char *file, size_t extra,
> char **extrap) }
>  
>    /* If we were already using tzfile, check whether the file
> changed.  */
> -  struct stat64 st;
> +  struct __stat64_t64 st;
>    if (was_using_tzfile
> -      && __stat64 (file, &st) == 0
> +      && __stat64_time64 (file, &st) == 0
>        && tzfile_ino == st.st_ino && tzfile_dev == st.st_dev
>        && tzfile_mtime == st.st_mtime)
>      goto done;  /* Nothing to do.  */
> @@ -164,7 +164,7 @@ __tzfile_read (const char *file, size_t extra,
> char **extrap) goto ret_free_transitions;
>  
>    /* Get information about the file we are actually using.  */
> -  if (__fstat64 (__fileno (f), &st) != 0)
> +  if (__fstat64_time64 (__fileno (f), &st) != 0)
>      goto lose;
>  
>    free ((void *) transitions);

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 03/18] support: Add support_create_timer
  2021-06-17 11:50 ` [PATCH 03/18] support: Add support_create_timer Adhemerval Zanella
@ 2021-06-21  7:42   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:42 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 4785 bytes --]

On Thu, 17 Jun 2021 08:50:49 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> It is a simple wrapper over timer_create, timer_settime, and
> sigaction.  It will be used to check for large timeout to trigger an
> EINTR.
> ---
>  support/Makefile               |  1 +
>  support/support.h              | 11 ++++++
>  support/support_create_timer.c | 69
> ++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+)
>  create mode 100644 support/support_create_timer.c
> 
> diff --git a/support/Makefile b/support/Makefile
> index f3ebaa8d2e..278f4627d8 100644
> --- a/support/Makefile
> +++ b/support/Makefile
> @@ -50,6 +50,7 @@ libsupport-routines = \
>    support_chroot \
>    support_copy_file \
>    support_copy_file_range \
> +  support_create_timer \
>    support_descriptor_supports_holes \
>    support_descriptors \
>    support_enter_mount_namespace \
> diff --git a/support/support.h b/support/support.h
> index 874204b7fc..9ec8ecb8d7 100644
> --- a/support/support.h
> +++ b/support/support.h
> @@ -24,6 +24,7 @@
>  #define SUPPORT_H
>  
>  #include <stdbool.h>
> +#include <stdint.h>
>  #include <stddef.h>
>  #include <sys/cdefs.h>
>  /* For mode_t.  */
> @@ -153,6 +154,16 @@ extern bool support_select_modifies_timeout
> (void); tv_usec larger than 1000000.  */
>  extern bool support_select_normalizes_timeout (void);
>  
> +/* Create a timer that trigger after SEC seconds and NSEC
> nanoseconds.  If
> +   REPEAT is true the timer will repeat indefinitely.  If CALLBACK
> is not
> +   NULL, the function will be called when the timer expires;
> otherwise a
> +   dummy empty function is used instead.
> +   This is implemented with POSIX per-process timer with
> SIGEV_SIGNAL.  */ +timer_t support_create_timer (uint64_t sec, long
> int nsec, bool repeat,
> +			      void (*callback)(int));
> +/* Disable the timer TIMER.  */
> +void support_delete_timer (timer_t timer);
> +
>  __END_DECLS
>  
>  #endif /* SUPPORT_H */
> diff --git a/support/support_create_timer.c
> b/support/support_create_timer.c new file mode 100644
> index 0000000000..c93aaa5c6b
> --- /dev/null
> +++ b/support/support_create_timer.c
> @@ -0,0 +1,69 @@
> +/* Create a periodic timer.
> +   Copyright (C) 2021 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 <support/check.h>
> +#include <support/support.h>
> +#include <support/xsignal.h>
> +#include <time.h>
> +
> +static void
> +dummy_alrm_handler (int sig)
> +{
> +}
> +
> +timer_t
> +support_create_timer (uint64_t sec, long int nsec, bool repeat,
> +		      void (*callback)(int))
> +{
> +  struct sigaction sa;
> +  sa.sa_handler = callback != NULL ? callback : dummy_alrm_handler;
> +  sigemptyset (&sa.sa_mask);
> +  sa.sa_flags = 0;
> +  xsigaction (SIGALRM, &sa, NULL);
> +
> +  struct sigevent ev = {
> +    .sigev_notify = SIGEV_SIGNAL,
> +    .sigev_signo = SIGALRM
> +  };
> +  timer_t timerid;
> +  int r = timer_create (CLOCK_REALTIME, &ev, &timerid);
> +  if (r == -1)
> +    FAIL_EXIT1 ("timer_create: %m");
> +
> +  /* Single timer with 0.1s.  */
> +  struct itimerspec its =
> +    {
> +      { .tv_sec = repeat ? sec : 0, .tv_nsec = repeat ? nsec : 0 },
> +      { .tv_sec = sec, .tv_nsec = nsec }
> +    };
> +  r = timer_settime (timerid, 0, &its, NULL);
> +  if (r == -1)
> +    FAIL_EXIT1 ("timer_settime: %m");
> +
> +  return timerid;
> +}
> +
> +/* Disable the timer TIMER.  */
> +void
> +support_delete_timer (timer_t timer)
> +{
> +  int r = timer_delete (timer);
> +  if (r == -1)
> +    FAIL_EXIT1 ("timer_delete: %m");
> +  xsignal (SIGALRM, SIG_DFL);
> +}

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 04/18] linux: Only use 64-bit syscall if required for ppoll
  2021-06-17 11:50 ` [PATCH 04/18] linux: Only use 64-bit syscall if required for ppoll Adhemerval Zanella
@ 2021-06-21  7:42   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:42 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 5105 bytes --]

On Thu, 17 Jun 2021 08:50:50 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.  This also
> avoids the need to use supports_time64() (which breaks the usage case
> of live migration like CRIU or similar).
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/Makefile    |  9 +++++++
>  sysdeps/unix/sysv/linux/ppoll.c     | 41
> +++++++++++------------------ sysdeps/unix/sysv/linux/tst-ppoll.c |
> 15 +++++++++++ 3 files changed, 40 insertions(+), 25 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index 294c366e3b..c36ea0e494 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -137,6 +137,15 @@ tests-time64 += \
>  
>  CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
>  
> +ifeq (yes,$(build-shared))
> +librt = $(common-objpfx)rt/librt.so
> +else
> +librt = $(common-objpfx)rt/librt.a
> +endif
> +
> +$(objpfx)tst-ppoll: $(librt)
> +$(objpfx)tst-ppoll-time64: $(librt)
> +
>  # Generate the list of SYS_* macros for the system calls (__NR_*
>  # macros).  The file syscall-names.list contains all possible system
>  # call names, and the generated header file produces SYS_* macros for
> diff --git a/sysdeps/unix/sysv/linux/ppoll.c
> b/sysdeps/unix/sysv/linux/ppoll.c index 624f14f517..e1ad316e2e 100644
> --- a/sysdeps/unix/sysv/linux/ppoll.c
> +++ b/sysdeps/unix/sysv/linux/ppoll.c
> @@ -21,9 +21,6 @@
>  #include <time.h>
>  #include <sys/poll.h>
>  #include <sysdep-cancel.h>
> -#include <kernel-features.h>
> -#include <time64-support.h>
> -
>  
>  int
>  __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct
> __timespec64 *timeout, @@ -38,40 +35,34 @@ __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
> +
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  return SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
> +			 __NSIG_BYTES);
> +#else
> +  bool is32bit = timeout != NULL
> +		 ? in_time_t_range (timeout->tv_sec) : true;
> +  int ret;
> +  if (!is32bit)
> +    {
>        ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout,
> sigmask, __NSIG_BYTES);
> -
>        if (ret == 0 || errno != ENOSYS)
>  	return ret;
> -
> -      mark_time64_unsupported ();
> +      __set_errno (EOVERFLOW);
> +      return -1;
>      }
>  
> -#ifndef __ASSUME_TIME64_SYSCALLS
>    struct timespec ts32;
> -  if (timeout)
> -    {
> -      if (! in_time_t_range (timeout->tv_sec))
> -        {
> -          __set_errno (EOVERFLOW);
> -          return -1;
> -        }
> -
> -      ts32 = valid_timespec64_to_timespec (*timeout);
> -    }
> +  if (timeout != NULL)
> +    ts32 = valid_timespec64_to_timespec (*timeout);
>  
> -  ret = SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL,
> sigmask,
> -			__NSIG_BYTES);
> +  return SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL,
> sigmask,
> +			 __NSIG_BYTES);
>  #endif
> -
> -  return ret;
>  }
>  
>  #if __TIMESIZE != 64
> diff --git a/sysdeps/unix/sysv/linux/tst-ppoll.c
> b/sysdeps/unix/sysv/linux/tst-ppoll.c index 9fe6ad07ce..e21e2fcc72
> 100644 --- a/sysdeps/unix/sysv/linux/tst-ppoll.c
> +++ b/sysdeps/unix/sysv/linux/tst-ppoll.c
> @@ -19,9 +19,11 @@
>  #include <time.h>
>  #include <poll.h>
>  #include <errno.h>
> +#include <intprops.h>
>  #include <support/check.h>
>  #include <support/xtime.h>
>  #include <support/timespec.h>
> +#include <support/support.h>
>  #include <stdbool.h>
>  
>  static int test_ppoll_timeout (bool zero_tmo)
> @@ -41,6 +43,16 @@ static int test_ppoll_timeout (bool zero_tmo)
>    return 0;
>  }
>  
> +static void
> +test_ppoll_large_timeout (void)
> +{
> +  support_create_timer (0, 100000000, false, NULL);
> +  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
> +  struct pollfd fds = { -1, 0, 0 };
> +  TEST_COMPARE (ppoll (&fds, 1, &ts, 0), -1);
> +  TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
> +}
> +
>  static int
>  do_test (void)
>  {
> @@ -50,6 +62,9 @@ do_test (void)
>    /* Check if ppoll exits after specified timeout.  */
>    test_ppoll_timeout (false);
>  
> +  /* Check if ppoll with large timeout.  */
> +  test_ppoll_large_timeout ();
> +
>    return 0;
>  }
>  

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 05/18] linux: Only use 64-bit syscall if required for pselect
  2021-06-17 11:50 ` [PATCH 05/18] linux: Only use 64-bit syscall if required for pselect Adhemerval Zanella
@ 2021-06-21  7:42   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:42 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 10320 bytes --]

On Thu, 17 Jun 2021 08:50:51 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.  This also
> avoids the need to use supports_time64() (which breaks the usage case
> of live migration like CRIU or similar).
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  misc/Makefile                                 |   9 ++
>  misc/tst-pselect.c                            | 120
> ++++++++---------- .../unix/sysv/linux/microblaze/pselect32.c    |
> 3 +- sysdeps/unix/sysv/linux/pselect.c             |  47 ++++---
>  sysdeps/unix/sysv/linux/pselect32.c           |   6 -
>  5 files changed, 95 insertions(+), 90 deletions(-)
> 
> diff --git a/misc/Makefile b/misc/Makefile
> index f34ab09fe3..fa40bf0e11 100644
> --- a/misc/Makefile
> +++ b/misc/Makefile
> @@ -148,6 +148,12 @@ CFLAGS-brk.op = $(no-stack-protector)
>  
>  include ../Rules
>  
> +ifeq (yes,$(build-shared))
> +librt = $(common-objpfx)rt/librt.so
> +else
> +librt = $(common-objpfx)rt/librt.a
> +endif
> +
>  $(objpfx)libg.a: $(dep-dummy-lib); $(make-dummy-lib)
>  
>  $(objpfx)tst-tsearch: $(libm)
> @@ -162,3 +168,6 @@ tst-allocate_once-ENV =
> MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace
> $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
> $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@;
> \ $(evaluate-test) +
> +$(objpfx)tst-pselect: $(librt)
> +$(objpfx)tst-pselect-time64: $(librt)
> diff --git a/misc/tst-pselect.c b/misc/tst-pselect.c
> index c89176b058..f8c404c275 100644
> --- a/misc/tst-pselect.c
> +++ b/misc/tst-pselect.c
> @@ -16,14 +16,14 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <errno.h>
> -#include <signal.h>
> -#include <stdio.h>
> -#include <unistd.h>
> -#include <sys/select.h>
> -#include <sys/wait.h>
> +#include <intprops.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/xsignal.h>
> +#include <support/xunistd.h>
> +#include <support/xtime.h>
>  #include <stdlib.h>
>  
> -
>  static volatile int handler_called;
>  
>  static void
> @@ -33,59 +33,43 @@ handler (int sig)
>  }
>  
>  
> -static int
> -do_test (void)
> +static void
> +test_pselect_basic (void)
>  {
>    struct sigaction sa;
>    sa.sa_handler = handler;
>    sa.sa_flags = 0;
>    sigemptyset (&sa.sa_mask);
>  
> -  if (sigaction (SIGUSR1, &sa, NULL) != 0)
> -    {
> -      puts ("sigaction failed");
> -      return 1;
> -    }
> +  xsigaction (SIGUSR1, &sa, NULL);
>  
>    sa.sa_handler = SIG_IGN;
> -  if (sigaction (SIGCHLD, &sa, NULL) != 0)
> -    {
> -      puts ("2nd sigaction failed");
> -      return 1;
> -    }
> +  xsigaction (SIGCHLD, &sa, NULL);
>  
>    sigset_t ss_usr1;
>    sigemptyset (&ss_usr1);
>    sigaddset (&ss_usr1, SIGUSR1);
> -  if (sigprocmask (SIG_BLOCK, &ss_usr1, NULL) != 0)
> -    {
> -      puts ("sigprocmask failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (sigprocmask (SIG_BLOCK, &ss_usr1, NULL), 0);
>  
>    int fds[2][2];
> -
> -  if (pipe (fds[0]) != 0 || pipe (fds[1]) != 0)
> -    {
> -      puts ("pipe failed");
> -      return 1;
> -    }
> +  xpipe (fds[0]);
> +  xpipe (fds[1]);
>  
>    fd_set rfds;
>    FD_ZERO (&rfds);
>  
>    sigset_t ss;
> -  sigprocmask (SIG_SETMASK, NULL, &ss);
> +  TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0);
>    sigdelset (&ss, SIGUSR1);
>  
>    struct timespec to = { .tv_sec = 0, .tv_nsec = 500000000 };
>  
>    pid_t parent = getpid ();
> -  pid_t p = fork ();
> +  pid_t p = xfork ();
>    if (p == 0)
>      {
> -      close (fds[0][1]);
> -      close (fds[1][0]);
> +      xclose (fds[0][1]);
> +      xclose (fds[1][0]);
>  
>        FD_SET (fds[0][0], &rfds);
>  
> @@ -93,55 +77,63 @@ do_test (void)
>        do
>  	{
>  	  if (getppid () != parent)
> -	    exit (2);
> +	    FAIL_EXIT1 ("getppid()=%d != parent=%d", getppid(),
> parent); 
>  	  errno = 0;
>  	  e = pselect (fds[0][0] + 1, &rfds, NULL, NULL, &to, &ss);
>  	}
>        while (e == 0);
>  
> -      if (e != -1)
> -	{
> -	  puts ("child: pselect did not fail");
> -	  return 0;
> -	}
> -      if (errno != EINTR)
> -	{
> -	  puts ("child: pselect did not set errno to EINTR");
> -	  return 0;
> -	}
> +      TEST_COMPARE (e, -1);
> +      TEST_COMPARE (errno, EINTR);
>  
>        TEMP_FAILURE_RETRY (write (fds[1][1], "foo", 3));
>  
>        exit (0);
>      }
>  
> -  close (fds[0][0]);
> -  close (fds[1][1]);
> +  xclose (fds[0][0]);
> +  xclose (fds[1][1]);
>  
>    FD_SET (fds[1][0], &rfds);
>  
> -  kill (p, SIGUSR1);
> +  TEST_COMPARE (kill (p, SIGUSR1), 0);
>  
>    int e = pselect (fds[1][0] + 1, &rfds, NULL, NULL, NULL, &ss);
> -  if (e == -1)
> -    {
> -      puts ("parent: pselect failed");
> -      return 1;
> -    }
> -  if (e != 1)
> -    {
> -      puts ("parent: pselect did not report readable fd");
> -      return 1;
> -    }
> -  if (!FD_ISSET (fds[1][0], &rfds))
> -    {
> -      puts ("parent: pselect reports wrong fd");
> -      return 1;
> -    }
> +  TEST_COMPARE (e, 1);
> +  TEST_VERIFY (FD_ISSET (fds[1][0], &rfds));
> +}
> +
> +static void
> +test_pselect_large_timeout (void)
> +{
> +  support_create_timer (0, 100000000, false, NULL);
> +
> +  int fds[2];
> +  xpipe (fds);
> +
> +  fd_set rfds;
> +  FD_ZERO (&rfds);
> +  FD_SET (fds[0], &rfds);
> +
> +  sigset_t ss;
> +  TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0);
> +  sigdelset (&ss, SIGALRM);
> +
> +  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
> +
> +  TEST_COMPARE (pselect (fds[0] + 1, &rfds, NULL, NULL, &ts, &ss),
> -1);
> +  TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
> +}
> +
> +static int
> +do_test (void)
> +{
> +  test_pselect_basic ();
> +
> +  test_pselect_large_timeout ();
>  
>    return 0;
>  }
>  
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/microblaze/pselect32.c
> b/sysdeps/unix/sysv/linux/microblaze/pselect32.c index
> a4f436462b..70b7b52a48 100644 ---
> a/sysdeps/unix/sysv/linux/microblaze/pselect32.c +++
> b/sysdeps/unix/sysv/linux/microblaze/pselect32.c @@ -35,8 +35,7 @@
> __pselect32 (int nfds, fd_set *readfds, fd_set *writefds, struct
> timeval tv32, *ptv32 = NULL; if (timeout != NULL)
>      {
> -      if (! in_time_t_range (timeout->tv_sec)
> -	  || ! valid_nanoseconds (timeout->tv_nsec))
> +      if (! valid_nanoseconds (timeout->tv_nsec))
>  	{
>  	  __set_errno (EINVAL);
>  	  return -1;
> diff --git a/sysdeps/unix/sysv/linux/pselect.c
> b/sysdeps/unix/sysv/linux/pselect.c index 5e8a0cc2dc..79e8584ea7
> 100644 --- a/sysdeps/unix/sysv/linux/pselect.c
> +++ b/sysdeps/unix/sysv/linux/pselect.c
> @@ -18,7 +18,23 @@
>  
>  #include <sys/select.h>
>  #include <sysdep-cancel.h>
> -#include <time64-support.h>
> +
> +static int
> +pselect64_syscall (int nfds, fd_set *readfds, fd_set *writefds,
> +		   fd_set *exceptfds, const struct __timespec64
> *timeout,
> +		   const sigset_t *sigmask)
> +{
> +#ifndef __NR_pselect6_time64
> +# define __NR_pselect6_time64 __NR_pselect6
> +#endif
> +  /* NB: This is required by ARGIFY used in x32 internal_syscallN.
> */
> +  __syscall_ulong_t data[2] =
> +    {
> +      (uintptr_t) sigmask, __NSIG_BYTES
> +    };
> +  return SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds,
> exceptfds,
> +			 timeout, data);
> +}
>  
>  int
>  __pselect64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set
> *exceptfds, @@ -37,30 +53,25 @@ __pselect64 (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.  */
> -
> -#ifndef __NR_pselect6_time64
> -# define __NR_pselect6_time64 __NR_pselect6
> -#endif
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  return pselect64_syscall (nfds, readfds, writefds, exceptfds,
> timeout,
> +			    sigmask);
> +#else
> +  bool is32bit = timeout != NULL
> +		 ? in_time_t_range (timeout->tv_sec) : true;
>    int r;
> -  if (supports_time64 ())
> +  if (!is32bit)
>      {
> -      /* NB: This is required by ARGIFY used in x32
> internal_syscallN.  */
> -      __syscall_ulong_t data[2] =
> -	{
> -	  (uintptr_t) sigmask, __NSIG_BYTES
> -	};
> -      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds,
> exceptfds,
> -			  timeout, data);
> +      r = pselect64_syscall (nfds, readfds, writefds, exceptfds,
> timeout,
> +			     sigmask);
>        if (r == 0 || errno != ENOSYS)
>  	return r;
> -
> -      mark_time64_unsupported ();
> +      __set_errno (EOVERFLOW);
> +      return -1;
>      }
>  
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  r = __pselect32 (nfds, readfds, writefds, exceptfds, timeout,
> sigmask);
> +  return __pselect32 (nfds, readfds, writefds, exceptfds, timeout,
> sigmask); #endif
> -  return r;
>  }
>  
>  #if __TIMESIZE != 64
> diff --git a/sysdeps/unix/sysv/linux/pselect32.c
> b/sysdeps/unix/sysv/linux/pselect32.c index eb59b51cdf..48724d8727
> 100644 --- a/sysdeps/unix/sysv/linux/pselect32.c
> +++ b/sysdeps/unix/sysv/linux/pselect32.c
> @@ -29,12 +29,6 @@ __pselect32 (int nfds, fd_set *readfds, fd_set
> *writefds, 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;
>      }

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 06/18] linux: Only use 64-bit syscall if required for select
  2021-06-17 11:50 ` [PATCH 06/18] linux: Only use 64-bit syscall if required for select Adhemerval Zanella
@ 2021-06-21  7:43   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:43 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 11054 bytes --]

On Thu, 17 Jun 2021 08:50:52 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.  This also
> avoids the need to use supports_time64() (which breaks the usage case
> of live migration like CRIU or similar).
> 
> It also fixes an issue on 32-bit select call for !__ASSUME_PSELECT
> (microblase with older kernels only) where the expected timeout
> is a 'struct timeval' instead of 'struct timespec'.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  include/sys/select.h               |  5 +++
>  misc/Makefile                      |  2 +
>  misc/tst-select.c                  | 39 +++++++++++--------
>  sysdeps/unix/sysv/linux/Makefile   |  2 +-
>  sysdeps/unix/sysv/linux/select.c   | 60
> ++++++++++-------------------- sysdeps/unix/sysv/linux/select32.c |
> 58 +++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+),
> 57 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/select32.c
> 
> diff --git a/include/sys/select.h b/include/sys/select.h
> index ec073deeba..a8961afbed 100644
> --- a/include/sys/select.h
> +++ b/include/sys/select.h
> @@ -21,6 +21,11 @@ extern int __pselect32 (int __nfds, fd_set
> *__readfds, const struct __timespec64 *__timeout,
>  			const __sigset_t *__sigmask)
>    attribute_hidden;
> +extern int __select32 (int __nfds, fd_set *__readfds,
> +		       fd_set *__writefds, fd_set *__exceptfds,
> +		       const struct __timespec64 *ts64,
> +		       struct __timeval64 *timeout)
> +  attribute_hidden;
>  
>  extern int __select64 (int __nfds, fd_set *__readfds,
>  		       fd_set *__writefds, fd_set *__exceptfds,
> diff --git a/misc/Makefile b/misc/Makefile
> index fa40bf0e11..66586bcc7e 100644
> --- a/misc/Makefile
> +++ b/misc/Makefile
> @@ -169,5 +169,7 @@ $(objpfx)tst-allocate_once-mem.out:
> $(objpfx)tst-allocate_once.out $(common-objpfx)malloc/mtrace
> $(objpfx)tst-allocate_once.mtrace > $@; \ $(evaluate-test)
>  
> +$(objpfx)tst-select: $(librt)
> +$(objpfx)tst-select-time64: $(librt)
>  $(objpfx)tst-pselect: $(librt)
>  $(objpfx)tst-pselect-time64: $(librt)
> diff --git a/misc/tst-select.c b/misc/tst-select.c
> index 52aa26651f..134eed99be 100644
> --- a/misc/tst-select.c
> +++ b/misc/tst-select.c
> @@ -17,6 +17,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <errno.h>
> +#include <intprops.h>
>  #include <support/capture_subprocess.h>
>  #include <support/check.h>
>  #include <support/support.h>
> @@ -31,12 +32,6 @@ struct child_args
>    struct timeval tmo;
>  };
>  
> -static void
> -alarm_handler (int signum)
> -{
> -  /* Do nothing.  */
> -}
> -
>  static void
>  do_test_child (void *clousure)
>  {
> @@ -69,17 +64,20 @@ do_test_child (void *clousure)
>  static void
>  do_test_child_alarm (void *clousure)
>  {
> -  struct sigaction act = { .sa_handler = alarm_handler };
> -  xsigaction (SIGALRM, &act, NULL);
> -  alarm (1);
> +  struct child_args *args = (struct child_args *) clousure;
>  
> -  struct timeval tv = { .tv_sec = 10, .tv_usec = 0 };
> +  support_create_timer (0, 100000000, false, NULL);
> +  struct timeval tv = { .tv_sec = args->tmo.tv_sec, .tv_usec = 0 };
>    int r = select (0, NULL, NULL, NULL, &tv);
>    TEST_COMPARE (r, -1);
> -  TEST_COMPARE (errno, EINTR);
> -
> -  if (support_select_modifies_timeout ())
> -    TEST_VERIFY (tv.tv_sec < 10);
> +  if (args->tmo.tv_sec > INT_MAX)
> +    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
> +  else
> +    {
> +      TEST_COMPARE (errno, EINTR);
> +      if (support_select_modifies_timeout ())
> +       TEST_VERIFY (tv.tv_sec < args->tmo.tv_sec);
> +    }
>  }
>  
>  static int
> @@ -121,13 +119,24 @@ do_test (void)
>    xclose (args.fds[0][0]);
>    xclose (args.fds[1][1]);
>  
> +  args.tmo = (struct timeval) { .tv_sec = 10, .tv_usec = 0 };
> +  {
> +    struct support_capture_subprocess result;
> +    result = support_capture_subprocess (do_test_child_alarm, &args);
> +    support_capture_subprocess_check (&result, "tst-select-child", 0,
> +				      sc_allow_none);
> +  }
> +
> +  args.tmo = (struct timeval) { .tv_sec = TYPE_MAXIMUM (time_t),
> +				.tv_usec = 0 };
>    {
>      struct support_capture_subprocess result;
> -    result = support_capture_subprocess (do_test_child_alarm, NULL);
> +    result = support_capture_subprocess (do_test_child_alarm, &args);
>      support_capture_subprocess_check (&result, "tst-select-child", 0,
>  				      sc_allow_none);
>    }
>  
> +  args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
>    {
>      fd_set rfds;
>      FD_ZERO (&rfds);
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index c36ea0e494..710169a454 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 pselect32 \
> +		   time64-support pselect32 select32 \
>  		   xstat fxstat lxstat xstat64 fxstat64 lxstat64 \
>  		   fxstatat fxstatat64 \
>  		   xmknod xmknodat convert_scm_timestamps
> diff --git a/sysdeps/unix/sysv/linux/select.c
> b/sysdeps/unix/sysv/linux/select.c index dc16a816ed..2d2a7fa720 100644
> --- a/sysdeps/unix/sysv/linux/select.c
> +++ b/sysdeps/unix/sysv/linux/select.c
> @@ -21,7 +21,6 @@
>  #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 @@ -65,53 +64,32 @@ __select64 (int nfds, fd_set
> *readfds, fd_set *writefds, fd_set *exceptfds, #ifndef
> __NR_pselect6_time64 # define __NR_pselect6_time64 __NR_pselect6
>  #endif
> +
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  int r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds,
> exceptfds,
> +			  pts64, NULL);
> +  if (timeout != NULL)
> +    TIMESPEC_TO_TIMEVAL (timeout, pts64);
> +  return r;
> +#else
> +  bool is32bit = timeout != NULL
> +		 ? in_time_t_range (timeout->tv_sec) : true;
>    int r;
> -  if (supports_time64 ())
> +  if (!is32bit)
>      {
> -      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.  */
> -      if (r >= 0 || errno != ENOSYS)
> +      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds,
> +			      exceptfds, pts64, NULL);
> +      if ((r >= 0 || errno != ENOSYS) && timeout != NULL)
>  	{
> -	  if (timeout != NULL)
> -	    TIMESPEC_TO_TIMEVAL (timeout, &ts64);
> -	  return r;
> +	  TIMESPEC_TO_TIMEVAL (timeout, &ts64);
>  	}
> -
> -      mark_time64_unsupported ();
> +      else
> +	__set_errno (EOVERFLOW);
> +      return r;
>      }
>  
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  struct timespec ts32, *pts32 = NULL;
> -  if (pts64 != NULL)
> -    {
> -      if (! in_time_t_range (pts64->tv_sec))
> -	{
> -	  __set_errno (EINVAL);
> -	  return -1;
> -	}
> -      ts32.tv_sec = s;
> -      ts32.tv_nsec = ns;
> -      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 (timeout != NULL)
> -    *timeout = valid_timespec_to_timeval64 (ts32);
> +  return __select32 (nfds, readfds, writefds, exceptfds, pts64,
> timeout); #endif
> -
> -  return r;
>  }
>  
>  #if __TIMESIZE != 64
> diff --git a/sysdeps/unix/sysv/linux/select32.c
> b/sysdeps/unix/sysv/linux/select32.c new file mode 100644
> index 0000000000..b7e122fe2c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/select32.c
> @@ -0,0 +1,58 @@
> +/* Synchronous I/O multiplexing.  Linux 32-bit time fallback.
> +   Copyright (C) 2020-2021 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
> +__select32 (int nfds, fd_set *readfds, fd_set *writefds,
> +	    fd_set *exceptfds, const struct __timespec64 *ts64,
> +	    struct __timeval64 *timeout)
> +{
> +#ifdef __ASSUME_PSELECT
> +  struct timespec ts32, *pts32 = NULL;
> +  if (ts64 != NULL)
> +    {
> +      ts32.tv_sec = ts64->tv_sec;
> +      ts32.tv_nsec = ts64->tv_nsec;
> +      pts32 = &ts32;
> +    }
> +
> +  int r = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds,
> exceptfds, pts32,
> +			  NULL);
> +  if (timeout != NULL)
> +    TIMESPEC_TO_TIMEVAL (timeout, pts32);
> +  return r;
> +#else
> +  struct timeval tv32, *ptv32 = NULL;
> +  if (ts64 != NULL)
> +    {
> +      tv32 = valid_timespec64_to_timeval (*ts64);
> +      ptv32 = &tv32;
> +    }
> +
> +  int r = SYSCALL_CANCEL (select, nfds, readfds, writefds,
> exceptfds, ptv32);
> +  if (timeout != NULL)
> +    *timeout = valid_timeval_to_timeval64 (tv32);
> +  return r;
> +#endif /* __ASSUME_PSELECT  */
> +}
> +
> +#endif

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 07/18] linux: Remove supports_time64 () from clock_getres
  2021-06-17 11:50 ` [PATCH 07/18] linux: Remove supports_time64 () from clock_getres Adhemerval Zanella
@ 2021-06-21  7:43   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:43 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 2102 bytes --]

On Thu, 17 Jun 2021 08:50:53 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> It breaks the usage case of live migration like CRIU or similar.
> The performance drawback is it would require an extra syscall
> on older kernels without 64-bit time support.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/clock_getres.c | 16 +++++-----------
>  1 file changed, 5 insertions(+), 11 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/clock_getres.c
> b/sysdeps/unix/sysv/linux/clock_getres.c index a9edec93e6..83f0593074
> 100644 --- a/sysdeps/unix/sysv/linux/clock_getres.c
> +++ b/sysdeps/unix/sysv/linux/clock_getres.c
> @@ -21,7 +21,6 @@
>  #include <time.h>
>  
>  #include <sysdep-vdso.h>
> -#include <time64-support.h>
>  #include <shlib-compat.h>
>  #include <kernel-features.h>
>  
> @@ -34,19 +33,14 @@ __clock_getres64 (clockid_t clock_id, struct
> __timespec64 *res) #ifndef __NR_clock_getres_time64
>  # define __NR_clock_getres_time64 __NR_clock_getres
>  #endif
> -  if (supports_time64 ())
> -    {
> +
>  #ifdef HAVE_CLOCK_GETRES64_VSYSCALL
> -      r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
> +  r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
>  #else
> -      r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
> +  r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
>  #endif
> -
> -      if (r == 0 || errno != ENOSYS)
> -	return r;
> -
> -      mark_time64_unsupported ();
> -    }
> +  if (r == 0 || errno != ENOSYS)
> +    return r;
>  
>  #ifndef __ASSUME_TIME64_SYSCALLS
>    /* Fallback code that uses 32-bit support.  */

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 08/18] linux: Remove supports_time64 () from clock_gettime
  2021-06-17 11:50 ` [PATCH 08/18] linux: Remove supports_time64 () from clock_gettime Adhemerval Zanella
@ 2021-06-21  7:43   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:43 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 2106 bytes --]

On Thu, 17 Jun 2021 08:50:54 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> It breaks the usage case of live migration like CRIU or similar.
> The performance drawback is it would require an extra syscall
> on older kernels without 64-bit time support.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/clock_gettime.c | 14 ++++----------
>  1 file changed, 4 insertions(+), 10 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c
> b/sysdeps/unix/sysv/linux/clock_gettime.c index
> 781d05c2fd..cfe9370455 100644 ---
> a/sysdeps/unix/sysv/linux/clock_gettime.c +++
> b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -22,7 +22,6 @@
>  #include <time.h>
>  #include "kernel-posix-cpu-timers.h"
>  #include <sysdep-vdso.h>
> -#include <time64-support.h>
>  #include <shlib-compat.h>
>  
>  /* Get current value of CLOCK and store it in TP.  */
> @@ -35,19 +34,14 @@ __clock_gettime64 (clockid_t clock_id, struct
> __timespec64 *tp) # define __NR_clock_gettime64 __NR_clock_gettime
>  #endif
>  
> -  if (supports_time64 ())
> -    {
>  #ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
> -      r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
> +  r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
>  #else
> -      r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
> +  r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
>  #endif
>  
> -      if (r == 0 || errno != ENOSYS)
> -	return r;
> -
> -      mark_time64_unsupported ();
> -   }
> +  if (r == 0 || errno != ENOSYS)
> +    return r;
>  
>  #ifndef __ASSUME_TIME64_SYSCALLS
>    /* Fallback code that uses 32-bit support.  */

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 09/18] linux: Remove time64-support
  2021-06-17 11:50 ` [PATCH 09/18] linux: Remove time64-support Adhemerval Zanella
@ 2021-06-21  7:43   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:43 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 5785 bytes --]

On Thu, 17 Jun 2021 08:50:55 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> It breaks the usage case of live migration like CRIU or similar
> and most usages can be optimized away by either building glibc with
> a minimum 5.1 kernel or by using the 32-bit syscall for the common
> case.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/Makefile         |  2 +-
>  sysdeps/unix/sysv/linux/time64-support.c | 23 --------
>  sysdeps/unix/sysv/linux/time64-support.h | 70
> ------------------------ 3 files changed, 1 insertion(+), 94
> deletions(-) delete mode 100644
> sysdeps/unix/sysv/linux/time64-support.c delete mode 100644
> sysdeps/unix/sysv/linux/time64-support.h
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index 710169a454..982755f980 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 pselect32 select32 \
> +		   pselect32 select32 \
>  		   xstat fxstat lxstat xstat64 fxstat64 lxstat64 \
>  		   fxstatat fxstatat64 \
>  		   xmknod xmknodat convert_scm_timestamps
> diff --git a/sysdeps/unix/sysv/linux/time64-support.c
> b/sysdeps/unix/sysv/linux/time64-support.c deleted file mode 100644
> index 0718e7421b..0000000000
> --- a/sysdeps/unix/sysv/linux/time64-support.c
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -/* Auxiliary definitions for 64-bit time_t support.
> -   Copyright (C) 2020-2021 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 <time64-support.h>
> -
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -int __time64_support = 1;
> -#endif
> diff --git a/sysdeps/unix/sysv/linux/time64-support.h
> b/sysdeps/unix/sysv/linux/time64-support.h deleted file mode 100644
> index 8466d37f8f..0000000000
> --- a/sysdeps/unix/sysv/linux/time64-support.h
> +++ /dev/null
> @@ -1,70 +0,0 @@
> -/* Auxiliary definitions for 64-bit time_t support.
> -   Copyright (C) 2020-2021 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 <stdbool.h>
> -#include <atomic.h>
> -
> -/* These helper functions are used to optimize the 64-bit time_t
> support on
> -   configurations that requires support for 32-bit time_t fallback
> -   (!__ASSUME_TIME64_SYSCALLS).  The idea is once the kernel
> advertises that
> -   it does not have 64-bit time_t support, glibc will stop to try
> issue the
> -   64-bit time_t syscall altogether.
> -
> -   For instance:
> -
> -     #ifndef __NR_symbol_time64
> -     # define __NR_symbol_time64 __NR_symbol
> -     #endif
> -     int r;
> -     if (supports_time64 ())
> -       {
> -         r = INLINE_SYSCALL_CALL (symbol, ...);
> -         if (r == 0 || errno != ENOSYS)
> -	   return r;
> -
> -         mark_time64_unsupported ();
> -       }
> -     #ifndef __ASSUME_TIME64_SYSCALLS
> -     <32-bit fallback syscall>
> -     #endif
> -     return r;
> -
> -   On configuration with default 64-bit time_t this optimization
> should be
> -   optimized away by the compiler resulting in no overhead.  */
> -
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -extern int __time64_support attribute_hidden;
> -#endif
> -
> -static inline bool
> -supports_time64 (void)
> -{
> -#ifdef __ASSUME_TIME64_SYSCALLS
> -  return true;
> -#else
> -  return atomic_load_relaxed (&__time64_support) != 0;
> -#endif
> -}
> -
> -static inline void
> -mark_time64_unsupported (void)
> -{
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  atomic_store_relaxed (&__time64_support, 0);
> -#endif
> -}

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 10/18] linux: timerfd_gettime minor cleanup
  2021-06-17 11:50 ` [PATCH 10/18] linux: timerfd_gettime minor cleanup Adhemerval Zanella
@ 2021-06-21  7:43   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:43 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 1552 bytes --]

On Thu, 17 Jun 2021 08:50:56 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> The __NR_timerfd_gettime64 is always defined.
> ---
>  sysdeps/unix/sysv/linux/timerfd_gettime.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/timerfd_gettime.c
> b/sysdeps/unix/sysv/linux/timerfd_gettime.c index
> 89f8066b91..5f668257c4 100644 ---
> a/sysdeps/unix/sysv/linux/timerfd_gettime.c +++
> b/sysdeps/unix/sysv/linux/timerfd_gettime.c @@ -25,17 +25,17 @@
>  int
>  __timerfd_gettime64 (int fd, struct __itimerspec64 *value)
>  {
> +#ifndef __NR_timerfd_gettime64
> +# define __NR_timerfd_gettime64 __NR_timerfd_gettime
> +#endif
> +
>  #ifdef __ASSUME_TIME64_SYSCALLS
> -# ifndef __NR_timerfd_gettime64
> -#  define __NR_timerfd_gettime64 __NR_timerfd_gettime
> -# endif
>    return INLINE_SYSCALL_CALL (timerfd_gettime64, fd, value);
>  #else
> -# ifdef __NR_timerfd_gettime64
>    int ret = INLINE_SYSCALL_CALL (timerfd_gettime64, fd, value);
>    if (ret == 0 || errno != ENOSYS)
>      return ret;
> -# endif
> +
>    struct itimerspec its32;
>    int retval = INLINE_SYSCALL_CALL (timerfd_gettime, fd, &its32);
>    if (retval == 0)

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 11/18] linux: Only use 64-bit syscall if required for semtimedop
  2021-06-17 11:50 ` [PATCH 11/18] linux: Only use 64-bit syscall if required for semtimedop Adhemerval Zanella
@ 2021-06-21  7:43   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:43 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 6164 bytes --]

On Thu, 17 Jun 2021 08:50:57 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/semtimedop.c | 54
> ++++++++++++++++------------ sysvipc/Makefile                     |
> 9 +++++ sysvipc/test-sysvsem.c               | 22 +++++++++---
>  3 files changed, 57 insertions(+), 28 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/semtimedop.c
> b/sysdeps/unix/sysv/linux/semtimedop.c index b732b6db48..65a8c080f7
> 100644 --- a/sysdeps/unix/sysv/linux/semtimedop.c
> +++ b/sysdeps/unix/sysv/linux/semtimedop.c
> @@ -21,44 +21,52 @@
>  #include <sysdep.h>
>  #include <errno.h>
>  
> +static int
> +semtimedop_syscall (int semid, struct sembuf *sops, size_t nsops,
> +		    const struct __timespec64 *timeout)
> +{
> +#ifdef __NR_semtimedop_time64
> +  return INLINE_SYSCALL_CALL (semtimedop_time64, semid, sops, nsops,
> timeout); +#elif 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
> +}
> +
>  /* Perform user-defined atomical operation of array of semaphores.
> */ int
>  __semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
>  		const struct __timespec64 *timeout)
>  {
> -  int r;
> -#if defined __NR_semtimedop_time64
> -  r = INLINE_SYSCALL_CALL (semtimedop_time64, semid, sops, nsops,
> timeout); -#elif defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS && defined
> __NR_semtimedop
> -  r = INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, timeout);
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  return semtimedop_syscall (semid, sops, nsops, timeout);
>  #else
> -  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;
> +  bool is32bit = timeout != NULL
> +		 ? in_time_t_range (timeout->tv_sec) : true;
> +  if (!is32bit)
> +    {
> +      int r = semtimedop_syscall (semid, sops, nsops, timeout);
> +      if (r == 0 || errno != ENOSYS)
> +	return r;
> +      __set_errno (EOVERFLOW);
> +      return -1;
> +    }
>  
>    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);
> +# ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> +  return INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, pts32);
>  # else
> -  r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
> -			   SEMTIMEDOP_IPC_ARGS (nsops, sops, pts32));
> +  return INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
> +			      SEMTIMEDOP_IPC_ARGS (nsops, sops,
> pts32)); # endif
> -#endif /* __ASSUME_TIME64_SYSCALLS  */
> -  return r;
> +#endif
>  }
>  #if __TIMESIZE != 64
>  libc_hidden_def (__semtimedop64)
> diff --git a/sysvipc/Makefile b/sysvipc/Makefile
> index 86911803b5..d2acb6a70b 100644
> --- a/sysvipc/Makefile
> +++ b/sysvipc/Makefile
> @@ -38,3 +38,12 @@ include ../Rules
>  
>  CFLAGS-msgrcv.c += -fexceptions -fasynchronous-unwind-tables
>  CFLAGS-msgsnd.c += -fexceptions -fasynchronous-unwind-tables
> +
> +ifeq (yes,$(build-shared))
> +librt = $(common-objpfx)rt/librt.so
> +else
> +librt = $(common-objpfx)rt/librt.a
> +endif
> +
> +$(objpfx)test-sysvsem: $(librt)
> +$(objpfx)test-sysvsem-time64: $(librt)
> diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c
> index 092418205d..d9034c3dae 100644
> --- a/sysvipc/test-sysvsem.c
> +++ b/sysvipc/test-sysvsem.c
> @@ -16,6 +16,7 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> +#include <intprops.h>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <errno.h>
> @@ -30,6 +31,8 @@
>  #include <support/support.h>
>  #include <support/check.h>
>  #include <support/temp_file.h>
> +#include <support/xtime.h>
> +#include <support/xsignal.h>
>  
>  /* These are for the temporary file we generate.  */
>  static char *name;
> @@ -112,11 +115,20 @@ do_test (void)
>  #ifdef _GNU_SOURCE
>    /* Set a time for half a second.  The semaphore operation should
> timeout with EAGAIN.  */
> -  struct timespec ts = { 0 /* sec */, 500000000 /* nsec */ };
> -  if (semtimedop (semid, &sb2, 1, &ts) != -1
> -      || (errno != EAGAIN && errno != ENOSYS))
> -    FAIL_EXIT1 ("semtimedop succeed or returned errno !=
> {EAGAIN,ENOSYS} "
> -		"(errno=%i)", errno);
> +  {
> +    struct timespec ts = { 0 /* sec */, 500000000 /* nsec */ };
> +    if (semtimedop (semid, &sb2, 1, &ts) != -1
> +        || (errno != EAGAIN && errno != ENOSYS))
> +      FAIL_EXIT1 ("semtimedop succeed or returned errno !=
> {EAGAIN,ENOSYS} "
> +		  "(errno=%i)", errno);
> +  }
> +
> +  {
> +    support_create_timer (0, 100000000, false, NULL);
> +    struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
> +    TEST_COMPARE (semtimedop (semid, &sb2, 1, &ts), -1);
> +    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
> +  }
>  #endif
>  
>    /* Finally free up the semnaphore resource.  */

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 12/18] linux: Only use 64-bit syscall if required for timerfd_settime
  2021-06-17 11:50 ` [PATCH 12/18] linux: Only use 64-bit syscall if required for timerfd_settime Adhemerval Zanella
@ 2021-06-21  7:44   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:44 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 5200 bytes --]

On Thu, 17 Jun 2021 08:50:58 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/Makefile          |  2 ++
>  sysdeps/unix/sysv/linux/timerfd_settime.c | 25 ++++++++++---------
>  sysdeps/unix/sysv/linux/tst-timerfd.c     | 29
> +++++++++++++++++++++-- 3 files changed, 43 insertions(+), 13
> deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index 982755f980..2e5b5e1dc4 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -145,6 +145,8 @@ endif
>  
>  $(objpfx)tst-ppoll: $(librt)
>  $(objpfx)tst-ppoll-time64: $(librt)
> +$(objpfx)tst-timerfd: $(librt)
> +$(objpfx)tst-timerfd-time64: $(librt)
>  
>  # Generate the list of SYS_* macros for the system calls (__NR_*
>  # macros).  The file syscall-names.list contains all possible system
> diff --git a/sysdeps/unix/sysv/linux/timerfd_settime.c
> b/sysdeps/unix/sysv/linux/timerfd_settime.c index
> 0dd6fa026e..8f08133a73 100644 ---
> a/sysdeps/unix/sysv/linux/timerfd_settime.c +++
> b/sysdeps/unix/sysv/linux/timerfd_settime.c @@ -29,31 +29,34 @@
> __timerfd_settime64 (int fd, int flags, const struct __itimerspec64
> *value, #ifndef __NR_timerfd_settime64 # define
> __NR_timerfd_settime64 __NR_timerfd_settime #endif
> -  int ret = INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags,
> value, ovalue); -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (ret == 0 || errno != ENOSYS)
> -    return ret;
>  
> -  if (! in_time_t_range ((value->it_value).tv_sec)
> -      || ! in_time_t_range ((value->it_interval).tv_sec))
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  return INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags, value,
> ovalue); +#else
> +  bool is32bit_value = in_time_t_range (value->it_value.tv_sec);
> +  bool is32bit_interval = in_time_t_range
> (value->it_interval.tv_sec);
> +  if (!is32bit_value || !is32bit_interval)
>      {
> +      int r = INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags,
> value,
> +				   ovalue);
> +      if (r == 0 || errno != ENOSYS)
> +	return r;
>        __set_errno (EOVERFLOW);
> -      return -1;
> +      return r;
>      }
>  
>    struct itimerspec its32, oits32;
>    its32.it_interval = valid_timespec64_to_timespec
> (value->it_interval); its32.it_value = valid_timespec64_to_timespec
> (value->it_value); -
> -  ret = INLINE_SYSCALL_CALL (timerfd_settime, fd, flags,
> -			     &its32, ovalue ? &oits32 : NULL);
> +  int ret = INLINE_SYSCALL_CALL (timerfd_settime, fd, flags,
> +				 &its32, ovalue != NULL ? &oits32 :
> NULL); if (ret == 0 && ovalue != NULL)
>      {
>        ovalue->it_interval = valid_timespec_to_timespec64
> (oits32.it_interval); ovalue->it_value = valid_timespec_to_timespec64
> (oits32.it_value); }
> -#endif
>    return ret;
> +#endif
>  }
>  
>  #if __TIMESIZE != 64
> diff --git a/sysdeps/unix/sysv/linux/tst-timerfd.c
> b/sysdeps/unix/sysv/linux/tst-timerfd.c index 8828399119..27f1263ac6
> 100644 --- a/sysdeps/unix/sysv/linux/tst-timerfd.c
> +++ b/sysdeps/unix/sysv/linux/tst-timerfd.c
> @@ -16,15 +16,18 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> +#include <errno.h>
> +#include <intprops.h>
>  #include <time.h>
>  #include <support/check.h>
> +#include <support/support.h>
>  #include <support/xunistd.h>
>  #include <support/timespec.h>
>  #include <sys/time.h>
>  #include <sys/timerfd.h>
>  
> -static int
> -do_test (void)
> +static void
> +timerfd_test (void)
>  {
>    struct itimerspec settings = { { 0, 0 }, { 2, 0 } };
>    struct itimerspec val;
> @@ -52,6 +55,28 @@ do_test (void)
>    /* Check difference between timerfd_gettime calls.  */
>    TEST_COMPARE (support_timespec_check_in_range
>                  ((struct timespec) { 1, 0 }, val.it_value, 0.9,
> 1.0), 1); +
> +  xclose (fd);
> +}
> +
> +static void
> +timerfd_large_timeout (void)
> +{
> +  int fd = timerfd_create (CLOCK_REALTIME, 0);
> +  TEST_VERIFY (fd != -1);
> +  support_create_timer (0, 100000000, false, NULL);
> +  struct itimerspec it = { { 0, 0 }, { TYPE_MAXIMUM (time_t), 0 } };
> +  TEST_COMPARE (timerfd_settime (fd, 0, &it, NULL), 0);
> +  uint64_t buf;
> +  TEST_COMPARE (read (fd, &buf, sizeof (buf)), -1);
> +  TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
> +}
> +
> +static int
> +do_test (void)
> +{
> +  timerfd_test ();
> +  timerfd_large_timeout ();
>    return 0;
>  }
>  

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 13/18] linux: Only use 64-bit syscall if required for mq_timedreceive
  2021-06-17 11:50 ` [PATCH 13/18] linux: Only use 64-bit syscall if required for mq_timedreceive Adhemerval Zanella
@ 2021-06-21  7:44   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:44 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 6242 bytes --]

On Thu, 17 Jun 2021 08:50:59 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  rt/Makefile                               |  4 +-
>  rt/tst-mqueue10-time64.c                  |  1 +
>  rt/tst-mqueue10.c                         | 62
> +++++++++++++++++++++++ sysdeps/unix/sysv/linux/mq_timedreceive.c |
> 35 +++++++------ 4 files changed, 85 insertions(+), 17 deletions(-)
>  create mode 100644 rt/tst-mqueue10-time64.c
>  create mode 100644 rt/tst-mqueue10.c
> 
> diff --git a/rt/Makefile b/rt/Makefile
> index 797f2da51e..3382c7a1d2 100644
> --- a/rt/Makefile
> +++ b/rt/Makefile
> @@ -48,7 +48,8 @@ tests := tst-shm tst-timer tst-timer2 \
>  	 tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9
> \ tst-timer3 tst-timer4 tst-timer5 \
>  	 tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
> -	 tst-shm-cancel
> +	 tst-shm-cancel \
> +	 tst-mqueue10
>  tests-internal := tst-timer-sigmask
>  
>  tests-time64 := \
> @@ -58,6 +59,7 @@ tests-time64 := \
>    tst-mqueue2-time64 \
>    tst-mqueue4-time64 \
>    tst-mqueue8-time64 \
> +  tst-mqueue10-time64 \
>    tst-timer4-time64
>  
>  extra-libs := librt
> diff --git a/rt/tst-mqueue10-time64.c b/rt/tst-mqueue10-time64.c
> new file mode 100644
> index 0000000000..2c8a4ae372
> --- /dev/null
> +++ b/rt/tst-mqueue10-time64.c
> @@ -0,0 +1 @@
> +#include "tst-mqueue10.c"
> diff --git a/rt/tst-mqueue10.c b/rt/tst-mqueue10.c
> new file mode 100644
> index 0000000000..7fb53a1cae
> --- /dev/null
> +++ b/rt/tst-mqueue10.c
> @@ -0,0 +1,62 @@
> +/* Check for large timeout with mq_timedsend and mq_timedreceive.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <intprops.h>
> +#include <mqueue.h>
> +#include <stdio.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <unistd.h>
> +
> +static char name[sizeof "/tst-mqueue2-" + INT_BUFSIZE_BOUND (pid_t)];
> +
> +static void
> +do_cleanup (void)
> +{
> +  mq_unlink (name);
> +}
> +#define CLEANUP_HANDLER	do_cleanup
> +
> +static int
> +do_test (void)
> +{
> +  snprintf (name, sizeof (name), "/tst-mqueue2-%u", getpid ());
> +
> +  char msg[8] = { 0x55 };
> +
> +  struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = sizeof (msg)
> };
> +  mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
> +  TEST_VERIFY_EXIT (q != (mqd_t) -1);
> +
> +  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
> +
> +  {
> +    timer_t timer = support_create_timer (0, 100000000, false, NULL);
> +    TEST_COMPARE (mq_timedreceive (q, msg, sizeof (msg), NULL, &ts),
> -1);
> +    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
> +    support_delete_timer (timer);
> +  }
> +
> +  mq_unlink (name);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c
> b/sysdeps/unix/sysv/linux/mq_timedreceive.c index
> eb948ccc18..8776977daf 100644 ---
> a/sysdeps/unix/sysv/linux/mq_timedreceive.c +++
> b/sysdeps/unix/sysv/linux/mq_timedreceive.c @@ -29,30 +29,33 @@
> __mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr,
> size_t msg_len, #ifndef __NR_mq_timedreceive_time64 # define
> __NR_mq_timedreceive_time64 __NR_mq_timedreceive #endif
> -  int ret = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr,
> msg_len,
> -                            msg_prio, abs_timeout);
>  
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (ret == 0 || errno != ENOSYS)
> -    return ret;
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  return SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr,
> msg_len,
> +			 msg_prio, abs_timeout);
> +#else
> +  bool is32bit = abs_timeout != NULL
> +		 ? in_time_t_range (abs_timeout->tv_sec) : true;
> +  if (!is32bit)
> +    {
> +      int r = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes,
> msg_ptr, msg_len,
> +			      msg_prio, abs_timeout);
> +      if (r == 0 || errno != ENOSYS)
> +	return r;
> +      __set_errno (EOVERFLOW);
> +      return -1;
> +    }
>  
> -  struct timespec ts32;
> +  struct timespec ts32, *pts32 = NULL;
>    if (abs_timeout != NULL)
>      {
> -      if (! in_time_t_range (abs_timeout->tv_sec))
> -        {
> -          __set_errno (EOVERFLOW);
> -          return -1;
> -        }
> -
>        ts32 = valid_timespec64_to_timespec (*abs_timeout);
> +      pts32 = &ts32;
>      }
>  
> -  ret = SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len,
> msg_prio,
> -			abs_timeout != NULL ? &ts32 : NULL);
> +  return SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len,
> msg_prio,
> +			 pts32);
>  #endif
> -
> -  return ret;
>  }
>  
>  #if __TIMESIZE != 64

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 14/18] linux: Only use 64-bit syscall if required for mq_timedsend
  2021-06-17 11:51 ` [PATCH 14/18] linux: Only use 64-bit syscall if required for mq_timedsend Adhemerval Zanella
@ 2021-06-21  7:44   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:44 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 3474 bytes --]

On Thu, 17 Jun 2021 08:51:00 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  rt/tst-mqueue10.c                      | 10 ++++++++
>  sysdeps/unix/sysv/linux/mq_timedsend.c | 35
> ++++++++++++++------------ 2 files changed, 29 insertions(+), 16
> deletions(-)
> 
> diff --git a/rt/tst-mqueue10.c b/rt/tst-mqueue10.c
> index 7fb53a1cae..18795808e0 100644
> --- a/rt/tst-mqueue10.c
> +++ b/rt/tst-mqueue10.c
> @@ -54,6 +54,16 @@ do_test (void)
>      support_delete_timer (timer);
>    }
>  
> +  {
> +    timer_t timer = support_create_timer (0, 100000000, false, NULL);
> +    /* Fill the internal buffer first.  */
> +    TEST_COMPARE (mq_timedsend (q, msg, sizeof (msg), 0,
> +				&(struct timespec) { 0, 0 }), 0);
> +    TEST_COMPARE (mq_timedsend (q, msg, sizeof (msg), 0, &ts), -1);
> +    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
> +    support_delete_timer (timer);
> +  }
> +
>    mq_unlink (name);
>  
>    return 0;
> diff --git a/sysdeps/unix/sysv/linux/mq_timedsend.c
> b/sysdeps/unix/sysv/linux/mq_timedsend.c index 5f14ecb0bf..8fa8c010ad
> 100644 --- a/sysdeps/unix/sysv/linux/mq_timedsend.c
> +++ b/sysdeps/unix/sysv/linux/mq_timedsend.c
> @@ -29,30 +29,33 @@ __mq_timedsend_time64 (mqd_t mqdes, const char
> *msg_ptr, size_t msg_len, # ifndef __NR_mq_timedsend_time64
>  #  define __NR_mq_timedsend_time64 __NR_mq_timedsend
>  # endif
> -  int ret = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr,
> msg_len,
> -			    msg_prio, abs_timeout);
>  
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (ret == 0 || errno != ENOSYS)
> -    return ret;
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  return SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr,
> msg_len,
> +			 msg_prio, abs_timeout);
> +#else
> +  bool is32bit = abs_timeout != NULL
> +		 ? in_time_t_range (abs_timeout->tv_sec) : true;
> +  if (!is32bit)
> +    {
> +      int r = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr,
> msg_len,
> +			      msg_prio, abs_timeout);
> +      if (r == 0 || errno != ENOSYS)
> +	return r;
> +      __set_errno (EOVERFLOW);
> +      return -1;
> +    }
>  
> -  struct timespec ts32;
> +  struct timespec ts32, *pts32 = NULL;
>    if (abs_timeout != NULL)
>      {
> -      if (! in_time_t_range (abs_timeout->tv_sec))
> -        {
> -          __set_errno (EOVERFLOW);
> -          return -1;
> -        }
> -
>        ts32 = valid_timespec64_to_timespec (*abs_timeout);
> +      pts32 = &ts32;
>      }
>  
> -  ret = SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len,
> msg_prio,
> -			abs_timeout != NULL ? &ts32 : NULL);
> +  return SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len,
> msg_prio,
> +			 pts32);
>  #endif
> -
> -  return ret;
>  }
>  
>  #if __TIMESIZE != 64

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 16/18] linux: Only use 64-bit syscall if required for utimensat family
  2021-06-17 11:51 ` [PATCH 16/18] linux: Only use 64-bit syscall if required for utimensat family Adhemerval Zanella
@ 2021-06-21  7:45   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:45 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 3160 bytes --]

On Thu, 17 Jun 2021 08:51:02 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.
> 
> The large timeout are already tests by io/tst-utimensat-skeleton.c.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/utimensat.c | 35
> ++++++++++++++++++----------- 1 file changed, 22 insertions(+), 13
> deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/utimensat.c
> b/sysdeps/unix/sysv/linux/utimensat.c index 909a29762b..e79e4351d6
> 100644 --- a/sysdeps/unix/sysv/linux/utimensat.c
> +++ b/sysdeps/unix/sysv/linux/utimensat.c
> @@ -31,34 +31,43 @@ __utimensat64_helper (int fd, const char *file,
>  #ifndef __NR_utimensat_time64
>  # define __NR_utimensat_time64 __NR_utimensat
>  #endif
> -  int ret = INLINE_SYSCALL_CALL (utimensat_time64, fd, file,
> &tsp64[0], flags); -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (ret == 0 || errno != ENOSYS)
> -    return ret;
>  
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  return INLINE_SYSCALL_CALL (utimensat_time64, fd, file, &tsp64[0],
> flags); +#else
>    /* For UTIME_NOW and UTIME_OMIT the value of tv_sec field is
> ignored.  */ -# define TS_VALID(ns) \
> -  ((((ns).tv_nsec == UTIME_NOW || (ns).tv_nsec == UTIME_OMIT) \
> -   || in_time_t_range ((ns).tv_sec)))
> +# define TS_SPECIAL(ts) \
> +  ((ts).tv_nsec == UTIME_NOW || (ts).tv_nsec == UTIME_OMIT)
>  
> -  if (tsp64 != NULL
> -      && (!TS_VALID (tsp64[0]) || !TS_VALID (tsp64[1])))
> +  bool is32bit_t0 = tsp64 != NULL
> +		    ? TS_SPECIAL (tsp64[0])
> +		      || in_time_t_range (tsp64[0].tv_sec)
> +	            : true;
> +  bool is32bit_t1 = tsp64 != NULL
> +		    ? TS_SPECIAL (tsp64[1])
> +		      || in_time_t_range (tsp64[1].tv_sec)
> +	            : true;
> +
> +  if (!is32bit_t0 || !is32bit_t1)
>      {
> +      int r = INLINE_SYSCALL_CALL (utimensat_time64, fd, file,
> &tsp64[0],
> +				   flags);
> +      if (r == 0 || errno != ENOSYS)
> +	return r;
>        __set_errno (EOVERFLOW);
>        return -1;
>      }
>  
> -  struct timespec tsp32[2];
> +  struct timespec tsp32[2], *ptsp32 = NULL;
>    if (tsp64)
>      {
>        tsp32[0] = valid_timespec64_to_timespec (tsp64[0]);
>        tsp32[1] = valid_timespec64_to_timespec (tsp64[1]);
> +      ptsp32 = tsp32;
>      }
>  
> -  ret = INLINE_SYSCALL_CALL (utimensat, fd, file, tsp64 ? &tsp32[0]
> : NULL,
> -			     flags);
> +  return INLINE_SYSCALL_CALL (utimensat, fd, file, ptsp32, flags);
>  #endif
> -  return ret;
>  }
>  libc_hidden_def (__utimensat64_helper)
>  

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 17/18] linux: Only use 64-bit syscall if required for internal futex
  2021-06-17 11:51 ` [PATCH 17/18] linux: Only use 64-bit syscall if required for internal futex Adhemerval Zanella
@ 2021-06-21  7:45   ` Lukasz Majewski
  0 siblings, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:45 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 6523 bytes --]

On Thu, 17 Jun 2021 08:51:03 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  nptl/futex-internal.c         | 52
> +++++++++++++++++++++++------------ sysdeps/nptl/futex-internal.h |
> 24 ++++++++++------ 2 files changed, 50 insertions(+), 26 deletions(-)
> 
> diff --git a/nptl/futex-internal.c b/nptl/futex-internal.c
> index 850bf4fd83..277e60986e 100644
> --- a/nptl/futex-internal.c
> +++ b/nptl/futex-internal.c
> @@ -32,9 +32,6 @@ __futex_abstimed_wait_common32 (unsigned int*
> futex_word, struct timespec ts32, *pts32 = NULL;
>    if (abstime != NULL)
>      {
> -      if (! in_time_t_range (abstime->tv_sec))
> -	return -EOVERFLOW;
> -
>        ts32 = valid_timespec64_to_timespec (*abstime);
>        pts32 = &ts32;
>      }
> @@ -52,12 +49,28 @@ __futex_abstimed_wait_common32 (unsigned int*
> futex_word, 
>  static int
>  __futex_abstimed_wait_common64 (unsigned int* futex_word,
> -                                unsigned int expected, clockid_t
> clockid,
> +                                unsigned int expected, int op,
>                                  const struct __timespec64* abstime,
>                                  int private, bool cancel)
>  {
> -  unsigned int clockbit;
> +  if (cancel)
> +    return INTERNAL_SYSCALL_CANCEL (futex_time64, futex_word, op,
> expected,
> +				    abstime, NULL /* Unused.  */,
> +				    FUTEX_BITSET_MATCH_ANY);
> +  else
> +    return INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op,
> expected,
> +				  abstime, NULL /* Ununsed.  */,
> +				  FUTEX_BITSET_MATCH_ANY);
> +}
> +
> +static int
> +__futex_abstimed_wait_common (unsigned int* futex_word,
> +                              unsigned int expected, clockid_t
> clockid,
> +                              const struct __timespec64* abstime,
> +                              int private, bool cancel)
> +{
>    int err;
> +  unsigned int clockbit;
>  
>    /* Work around the fact that the kernel rejects negative timeout
> values despite them being valid.  */
> @@ -70,16 +83,19 @@ __futex_abstimed_wait_common64 (unsigned int*
> futex_word, clockbit = (clockid == CLOCK_REALTIME) ?
> FUTEX_CLOCK_REALTIME : 0; int op = __lll_private_flag
> (FUTEX_WAIT_BITSET | clockbit, private); 
> -  if (cancel)
> -    err = INTERNAL_SYSCALL_CANCEL (futex_time64, futex_word, op,
> expected,
> -                                   abstime, NULL /* Unused.  */,
> -                                   FUTEX_BITSET_MATCH_ANY);
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  err = __futex_abstimed_wait_common64 (futex_word, expected, op,
> abstime,
> +					private, cancel);
> +#else
> +  bool is32bit = abstime != NULL ? in_time_t_range (abstime->tv_sec)
> : true;
> +  if (!is32bit)
> +    {
> +      err = __futex_abstimed_wait_common64 (futex_word, expected,
> op, abstime,
> +					    private, cancel);
> +      if (err == -ENOSYS)
> +	err = -EOVERFLOW;
> +    }
>    else
> -    err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op,
> expected,
> -                                 abstime, NULL /* Ununsed.  */,
> -                                 FUTEX_BITSET_MATCH_ANY);
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (err == -ENOSYS)
>      err = __futex_abstimed_wait_common32 (futex_word, expected, op,
> abstime, private, cancel);
>  #endif
> @@ -109,8 +125,8 @@ __futex_abstimed_wait64 (unsigned int*
> futex_word, unsigned int expected, clockid_t clockid,
>                           const struct __timespec64* abstime, int
> private) {
> -  return __futex_abstimed_wait_common64 (futex_word, expected,
> clockid,
> -                                         abstime, private, false);
> +  return __futex_abstimed_wait_common (futex_word, expected, clockid,
> +                                       abstime, private, false);
>  }
>  libc_hidden_def (__futex_abstimed_wait64)
>  
> @@ -120,7 +136,7 @@ __futex_abstimed_wait_cancelable64 (unsigned int*
> futex_word, const struct __timespec64* abstime,
>                                      int private)
>  {
> -  return __futex_abstimed_wait_common64 (futex_word, expected,
> clockid,
> -                                         abstime, private, true);
> +  return __futex_abstimed_wait_common (futex_word, expected, clockid,
> +                                       abstime, private, true);
>  }
>  libc_hidden_def (__futex_abstimed_wait_cancelable64)
> diff --git a/sysdeps/nptl/futex-internal.h
> b/sysdeps/nptl/futex-internal.h index 969ab2bf4b..b54fdd44c1 100644
> --- a/sysdeps/nptl/futex-internal.h
> +++ b/sysdeps/nptl/futex-internal.h
> @@ -254,15 +254,23 @@ static __always_inline int
>  futex_lock_pi64 (int *futex_word, const struct __timespec64 *abstime,
>                   int private)
>  {
> -  int err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
> -                                   __lll_private_flag
> -                                   (FUTEX_LOCK_PI, private), 0,
> abstime); -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (err == -ENOSYS)
> +  int err;
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
> +			       __lll_private_flag (FUTEX_LOCK_PI,
> private), 0,
> +			       abstime);
> +#else
> +  bool is32bit = abstime != NULL ? in_time_t_range (abstime->tv_sec)
> : true;
> +  if (!is32bit)
> +    {
> +      err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
> +				   __lll_private_flag
> (FUTEX_LOCK_PI, private),
> +				   0, abstime);
> +      if (err == -ENOSYS)
> +	err = -EOVERFLOW;
> +    }
> +  else
>      {
> -      if (abstime != NULL && ! in_time_t_range (abstime->tv_sec))
> -        return EOVERFLOW;
> -
>        struct timespec ts32;
>        if (abstime != NULL)
>          ts32 = valid_timespec64_to_timespec (*abstime);

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep
  2021-06-17 11:51 ` [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep Adhemerval Zanella
  2021-06-17 15:11   ` Lukasz Majewski
@ 2021-06-21  7:46   ` Lukasz Majewski
  1 sibling, 0 replies; 48+ messages in thread
From: Lukasz Majewski @ 2021-06-21  7:46 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 6153 bytes --]

On Thu, 17 Jun 2021 08:51:04 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit
> syscall if the provided timeout fits in a 32-bit one.  The 64-bit
> usage should be rare since the timeout is a relative one.
> 
> Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel
> (with and without --enable-kernel=5.1) and on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/clock_nanosleep.c | 47
> +++++++++++++---------- time/Makefile                             |
> 9 +++++ time/tst-clock_nanosleep.c                | 40
> +++++++++++-------- 3 files changed, 60 insertions(+), 36 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c
> b/sysdeps/unix/sysv/linux/clock_nanosleep.c index
> 007f1736cb..46b0f1e269 100644 ---
> a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++
> b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -27,8 +27,9 @@
>  /* We can simply use the syscall.  The CPU clocks are not supported
>     with this function.  */
>  int
> -__clock_nanosleep_time64 (clockid_t clock_id, int flags, const
> struct __timespec64 *req,
> -                          struct __timespec64 *rem)
> +__clock_nanosleep_time64 (clockid_t clock_id, int flags,
> +			  const struct __timespec64 *req,
> +			  struct __timespec64 *rem)
>  {
>    if (clock_id == CLOCK_THREAD_CPUTIME_ID)
>      return EINVAL;
> @@ -37,33 +38,37 @@ __clock_nanosleep_time64 (clockid_t clock_id, int
> flags, const struct __timespec 
>    /* If the call is interrupted by a signal handler or encounters an
> error, it returns a positive value similar to errno.  */
> +
>  #ifndef __NR_clock_nanosleep_time64
>  # define __NR_clock_nanosleep_time64 __NR_clock_nanosleep
>  #endif
> -  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
> -				   flags, req, rem);
> -
> -#ifndef __ASSUME_TIME64_SYSCALLS
> -  if (r == 0 || r != -ENOSYS)
> -    return -r;
>  
> -  if (! in_time_t_range (req->tv_sec))
> +  int r;
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
> flags, req,
> +			       rem);
> +#else
> +  bool is32bit = in_time_t_range (req->tv_sec);
> +  if (!is32bit)
>      {
> -      __set_errno (EOVERFLOW);
> -      return -1;
> +      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
> flags,
> +				   req, rem);
> +      if (r == -ENOSYS)
> +	r = -EOVERFLOW;
>      }
> -
> -  struct timespec tr32;
> -  struct timespec ts32 = valid_timespec64_to_timespec (*req);
> -  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
> -                               &ts32, &tr32);
> -  if (INTERNAL_SYSCALL_ERROR_P (r))
> +  else
>      {
> -      if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0)
> -	*rem = valid_timespec_to_timespec64 (tr32);
> +      struct timespec tr32;
> +      struct timespec ts32 = valid_timespec64_to_timespec (*req);
> +      r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
> &ts32,
> +				   &tr32);
> +      if (INTERNAL_SYSCALL_ERROR_P (r))
> +	{
> +	  if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME)
> == 0)
> +	    *rem = valid_timespec_to_timespec64 (tr32);
> +	}
>      }
> -#endif /* __ASSUME_TIME64_SYSCALLS */
> -
> +#endif
>    return -r;
>  }
>  
> diff --git a/time/Makefile b/time/Makefile
> index c84bd5d3ec..0bea84966c 100644
> --- a/time/Makefile
> +++ b/time/Makefile
> @@ -86,6 +86,15 @@ $(objpfx)tst-strftime2.out: $(gen-locales)
>  $(objpfx)tst-strftime3.out: $(gen-locales)
>  endif
>  
> +ifeq (yes,$(build-shared))
> +librt = $(common-objpfx)rt/librt.so
> +else
> +librt = $(common-objpfx)rt/librt.a
> +endif
> +
> +$(objpfx)tst-clock_nanosleep: $(librt)
> +$(objpfx)tst-clock_nanosleep-time64: $(librt)
> +
>  tz-cflags = -DTZDIR='"$(zonedir)"' \
>  	    -DTZDEFAULT='"$(localtime-file)"' \
>  	    -DTZDEFRULES='"$(posixrules-file)"'
> diff --git a/time/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c
> index 47537435c1..a5a7f9430a 100644
> --- a/time/tst-clock_nanosleep.c
> +++ b/time/tst-clock_nanosleep.c
> @@ -20,38 +20,48 @@
>  #include <unistd.h>
>  #include <sys/time.h>
>  #include <time.h>
> -
> +#include <intprops.h>
> +#include <support/support.h>
> +#include <support/check.h>
>  
>  /* Test that clock_nanosleep() does sleep.  */
> -static int
> -do_test (void)
> +static void
> +clock_nanosleep_test (void)
>  {
>    /* Current time.  */
>    struct timeval tv1;
> -  (void) gettimeofday (&tv1, NULL);
> +  gettimeofday (&tv1, NULL);
>  
> -  struct timespec ts;
> -  ts.tv_sec = 1;
> -  ts.tv_nsec = 0;
> +  struct timespec ts = { 1, 0 };
>    TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts));
>  
>    /* At least one second must have passed.  */
>    struct timeval tv2;
> -  (void) gettimeofday (&tv2, NULL);
> +  gettimeofday (&tv2, NULL);
>  
>    tv2.tv_sec -= tv1.tv_sec;
>    tv2.tv_usec -= tv1.tv_usec;
>    if (tv2.tv_usec < 0)
>      --tv2.tv_sec;
>  
> -  if (tv2.tv_sec < 1)
> -    {
> -      puts ("clock_nanosleep didn't sleep long enough");
> -      return 1;
> -    }
> +  TEST_VERIFY (tv2.tv_sec >= 1);
> +}
> +
> +static void
> +clock_nanosleep_large_timeout (void)
> +{
> +  support_create_timer (0, 100000000, false, NULL);
> +  struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
> +  int r = clock_nanosleep (CLOCK_REALTIME, 0, &ts, NULL);
> +  TEST_VERIFY (r == EINTR || r == EOVERFLOW);
> +}
>  
> +static int
> +do_test (void)
> +{
> +  clock_nanosleep_test ();
> +  clock_nanosleep_large_timeout ();
>    return 0;
>  }
>  
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/test-driver.c>

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 15/18] linux: Only use 64-bit syscall if required for sigtimedwait
  2021-06-17 12:25   ` Andreas Schwab
@ 2021-06-22 14:58     ` Adhemerval Zanella
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-22 14:58 UTC (permalink / raw)
  To: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 17/06/2021 09:25, Andreas Schwab wrote:
> 
>      bool need_time64 = timeout != NULL && !in_time_t_range (timeout->tv_sec);

This is indeed better, I adjusted all the patches to follow this.

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

* Re: [PATCH 01/18] Use 64 bit time_t stat internally
  2021-06-17 11:50 ` [PATCH 01/18] Use 64 bit time_t stat internally Adhemerval Zanella
  2021-06-21  7:42   ` Lukasz Majewski
@ 2021-06-22 19:37   ` Florian Weimer
  2021-06-22 19:51     ` Adhemerval Zanella
  1 sibling, 1 reply; 48+ messages in thread
From: Florian Weimer @ 2021-06-22 19:37 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
> index b7e1aee80f..b2831508c4 100644
> --- a/sysdeps/posix/getaddrinfo.c
> +++ b/sysdeps/posix/getaddrinfo.c
> @@ -1636,16 +1636,17 @@ static int gaiconf_reload_flag_ever_set;
>  /* Last modification time.  */
>  #ifdef _STATBUF_ST_NSEC
>  
> -static struct timespec gaiconf_mtime;
> +static struct __timespec64 gaiconf_mtime;
>  
>  static inline void
> -save_gaiconf_mtime (const struct stat64 *st)
> +save_gaiconf_mtime (const struct __stat64_t64 *st)
>  {
> -  gaiconf_mtime = st->st_mtim;
> +  gaiconf_mtime = (struct __timespec64) { .tv_sec  = st->st_mtim.tv_sec,
> +					  .tv_nsec = st->st_mtim.tv_nsec };
>  }
>  
>  static inline bool
> -check_gaiconf_mtime (const struct stat64 *st)
> +check_gaiconf_mtime (const struct __stat64_t64 *st)
>  {
>    return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
>            && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
> @@ -1656,13 +1657,13 @@ check_gaiconf_mtime (const struct stat64 *st)
>  static time_t gaiconf_mtime;
>  
>  static inline void
> -save_gaiconf_mtime (const struct stat64 *st)
> +save_gaiconf_mtime (const struct __stat64_t64 *st)
>  {
>    gaiconf_mtime = st->st_mtime;
>  }
>  

Apparently this caused:

../sysdeps/posix/getaddrinfo.c: In function ‘save_gaiconf_mtime’:
../sysdeps/posix/getaddrinfo.c:1644:19: error: incompatible types when assigning to type ‘struct __timespec64’ from type ‘struct timespec’
 1644 |   gaiconf_mtime = st->st_mtim;
      |                   ^~

I do not know the state of 64-bit time_t on Hurd.

Thanks,
Florian


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

* Re: [PATCH 01/18] Use 64 bit time_t stat internally
  2021-06-22 19:37   ` Florian Weimer
@ 2021-06-22 19:51     ` Adhemerval Zanella
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella @ 2021-06-22 19:51 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 22/06/2021 16:37, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
>> index b7e1aee80f..b2831508c4 100644
>> --- a/sysdeps/posix/getaddrinfo.c
>> +++ b/sysdeps/posix/getaddrinfo.c
>> @@ -1636,16 +1636,17 @@ static int gaiconf_reload_flag_ever_set;
>>  /* Last modification time.  */
>>  #ifdef _STATBUF_ST_NSEC
>>  
>> -static struct timespec gaiconf_mtime;
>> +static struct __timespec64 gaiconf_mtime;
>>  
>>  static inline void
>> -save_gaiconf_mtime (const struct stat64 *st)
>> +save_gaiconf_mtime (const struct __stat64_t64 *st)
>>  {
>> -  gaiconf_mtime = st->st_mtim;
>> +  gaiconf_mtime = (struct __timespec64) { .tv_sec  = st->st_mtim.tv_sec,
>> +					  .tv_nsec = st->st_mtim.tv_nsec };
>>  }
>>  
>>  static inline bool
>> -check_gaiconf_mtime (const struct stat64 *st)
>> +check_gaiconf_mtime (const struct __stat64_t64 *st)
>>  {
>>    return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
>>            && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
>> @@ -1656,13 +1657,13 @@ check_gaiconf_mtime (const struct stat64 *st)
>>  static time_t gaiconf_mtime;
>>  
>>  static inline void
>> -save_gaiconf_mtime (const struct stat64 *st)
>> +save_gaiconf_mtime (const struct __stat64_t64 *st)
>>  {
>>    gaiconf_mtime = st->st_mtime;
>>  }
>>  
> 
> Apparently this caused:
> 
> ../sysdeps/posix/getaddrinfo.c: In function ‘save_gaiconf_mtime’:
> ../sysdeps/posix/getaddrinfo.c:1644:19: error: incompatible types when assigning to type ‘struct __timespec64’ from type ‘struct timespec’
>  1644 |   gaiconf_mtime = st->st_mtim;
>       |                   ^~
> 
> I do not know the state of 64-bit time_t on Hurd.

It should have re-checked against Hurd... I will fix it (hurd does not
have 64-bit time_t support afaik).

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

end of thread, other threads:[~2021-06-22 19:51 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-17 11:50 [PATCH 00/18] More y2038 fixes Adhemerval Zanella
2021-06-17 11:50 ` [PATCH 01/18] Use 64 bit time_t stat internally Adhemerval Zanella
2021-06-21  7:42   ` Lukasz Majewski
2021-06-22 19:37   ` Florian Weimer
2021-06-22 19:51     ` Adhemerval Zanella
2021-06-17 11:50 ` [PATCH 02/18] Use LFS and 64 bit time for installed programs Adhemerval Zanella
2021-06-17 12:19   ` Andreas Schwab
2021-06-18 18:50     ` Adhemerval Zanella
2021-06-17 20:49   ` Joseph Myers
2021-06-18 18:14     ` Adhemerval Zanella
2021-06-17 11:50 ` [PATCH 03/18] support: Add support_create_timer Adhemerval Zanella
2021-06-21  7:42   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 04/18] linux: Only use 64-bit syscall if required for ppoll Adhemerval Zanella
2021-06-21  7:42   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 05/18] linux: Only use 64-bit syscall if required for pselect Adhemerval Zanella
2021-06-21  7:42   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 06/18] linux: Only use 64-bit syscall if required for select Adhemerval Zanella
2021-06-21  7:43   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 07/18] linux: Remove supports_time64 () from clock_getres Adhemerval Zanella
2021-06-21  7:43   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 08/18] linux: Remove supports_time64 () from clock_gettime Adhemerval Zanella
2021-06-21  7:43   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 09/18] linux: Remove time64-support Adhemerval Zanella
2021-06-21  7:43   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 10/18] linux: timerfd_gettime minor cleanup Adhemerval Zanella
2021-06-21  7:43   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 11/18] linux: Only use 64-bit syscall if required for semtimedop Adhemerval Zanella
2021-06-21  7:43   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 12/18] linux: Only use 64-bit syscall if required for timerfd_settime Adhemerval Zanella
2021-06-21  7:44   ` Lukasz Majewski
2021-06-17 11:50 ` [PATCH 13/18] linux: Only use 64-bit syscall if required for mq_timedreceive Adhemerval Zanella
2021-06-21  7:44   ` Lukasz Majewski
2021-06-17 11:51 ` [PATCH 14/18] linux: Only use 64-bit syscall if required for mq_timedsend Adhemerval Zanella
2021-06-21  7:44   ` Lukasz Majewski
2021-06-17 11:51 ` [PATCH 15/18] linux: Only use 64-bit syscall if required for sigtimedwait Adhemerval Zanella
2021-06-17 12:25   ` Andreas Schwab
2021-06-22 14:58     ` Adhemerval Zanella
2021-06-17 11:51 ` [PATCH 16/18] linux: Only use 64-bit syscall if required for utimensat family Adhemerval Zanella
2021-06-21  7:45   ` Lukasz Majewski
2021-06-17 11:51 ` [PATCH 17/18] linux: Only use 64-bit syscall if required for internal futex Adhemerval Zanella
2021-06-21  7:45   ` Lukasz Majewski
2021-06-17 11:51 ` [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep Adhemerval Zanella
2021-06-17 15:11   ` Lukasz Majewski
2021-06-17 17:45     ` Adhemerval Zanella
2021-06-21  7:46   ` Lukasz Majewski
2021-06-17 14:20 ` [PATCH 00/18] More y2038 fixes Lukasz Majewski
2021-06-17 17:41   ` Adhemerval Zanella
2021-06-17 20:58     ` Joseph Myers

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).