1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00

linux: Only use 64-bit syscall if required for pselect

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>
This commit is contained in:
Adhemerval Zanella
2021-06-15 16:59:50 -03:00
parent ecf2661281
commit 91cf411ad3
5 changed files with 94 additions and 91 deletions

View File

@ -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,23 @@ __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
int r;
if (supports_time64 ())
#ifdef __ASSUME_TIME64_SYSCALLS
return pselect64_syscall (nfds, readfds, writefds, exceptfds, timeout,
sigmask);
#else
bool need_time64 = timeout != NULL && !in_time_t_range (timeout->tv_sec);
if (need_time64)
{
/* 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);
int 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