diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-15 15:41:00 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-22 12:09:52 -0300 |
commit | ecf2661281c71a9752c7238ab93bc12b16cfff23 (patch) | |
tree | 4adb5c607a25b04e7e3aff43e1eba5f26823140f /sysdeps/unix/sysv/linux/ppoll.c | |
parent | 92f7b465101c23e45f66c6ad25ba243df49556a0 (diff) | |
download | glibc-ecf2661281c71a9752c7238ab93bc12b16cfff23.tar.gz glibc-ecf2661281c71a9752c7238ab93bc12b16cfff23.tar.xz glibc-ecf2661281c71a9752c7238ab93bc12b16cfff23.zip |
linux: Only use 64-bit syscall if required for ppoll
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. Reviewed-by: Lukasz Majewski <lukma@denx.de>
Diffstat (limited to 'sysdeps/unix/sysv/linux/ppoll.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/ppoll.c | 40 |
1 files changed, 15 insertions, 25 deletions
diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c index 624f14f517..8ca133b1fa 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,33 @@ __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 + int ret; + bool need_time64 = timeout != NULL && !in_time_t_range (timeout->tv_sec); + if (need_time64) + { 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 |