From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) by sourceware.org (Postfix) with ESMTPS id 94E773886C41 for ; Mon, 21 Jun 2021 07:43:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 94E773886C41 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=denx.de Received: from ktm (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: lukma@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 70E89801FD; Mon, 21 Jun 2021 09:43:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1624261387; bh=o9NkuCbjk7FB7v5flEpOeo3l/YcCbQGKCvXodqaVtYc=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=ACd8gzbYviQ4GByldxiJDKrmZm39LlTLN0F8vnozMd7dksiGcldCBnLpjoMk9pzuy rttaOhU/PhzrfbTZCv1+PBX1xXb5U5dYGEJ4ZsqFMWuXy3CXZZT6MMnWlv/e9RcCf+ v5JBBrKYONxic471MS7Zaze9V7FbGGGYkj0QSxgXHb5BBwsUUoWJsTwYRK8GJpIJKt I3OYSANiCpjTjM2tOZBGgNCUUJ60c2Ix3jrO/7MfxGgHLoZOmwF9yRc6tW9UIS5+AP 1T/3yj051zyY7bwxsof4uurdmDf9RJC0r0Ihya4mXZ4FN4W9ZBO3hW+1aYfpBbMHXa zIUMkHmgTHnGg== Date: Mon, 21 Jun 2021 09:43:06 +0200 From: Lukasz Majewski To: Adhemerval Zanella Cc: libc-alpha@sourceware.org, Carlos O'Donell Subject: Re: [PATCH 06/18] linux: Only use 64-bit syscall if required for select Message-ID: <20210621094306.4b48cbf2@ktm> In-Reply-To: <20210617115104.1359598-7-adhemerval.zanella@linaro.org> References: <20210617115104.1359598-1-adhemerval.zanella@linaro.org> <20210617115104.1359598-7-adhemerval.zanella@linaro.org> Organization: denx.de X-Mailer: Claws Mail 3.17.8 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; boundary="Sig_/Ejp9.E.k0RfcE9UT7IRHMzP"; protocol="application/pgp-signature" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jun 2021 07:43:10 -0000 --Sig_/Ejp9.E.k0RfcE9UT7IRHMzP Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable On Thu, 17 Jun 2021 08:50:52 -0300 Adhemerval Zanella 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). >=20 > 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'. >=20 > Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel > (with and without --enable-kernel=3D5.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 >=20 > 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; > =20 > 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) > =20 > +$(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 @@ > . */ > =20 > #include > +#include > #include > #include > #include > @@ -31,12 +32,6 @@ struct child_args > struct timeval tmo; > }; > =20 > -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 =3D { .sa_handler =3D alarm_handler }; > - xsigaction (SIGALRM, &act, NULL); > - alarm (1); > + struct child_args *args =3D (struct child_args *) clousure; > =20 > - struct timeval tv =3D { .tv_sec =3D 10, .tv_usec =3D 0 }; > + support_create_timer (0, 100000000, false, NULL); > + struct timeval tv =3D { .tv_sec =3D args->tmo.tv_sec, .tv_usec =3D 0 }; > int r =3D 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 =3D=3D EINTR || errno =3D=3D EOVERFLOW); > + else > + { > + TEST_COMPARE (errno, EINTR); > + if (support_select_modifies_timeout ()) > + TEST_VERIFY (tv.tv_sec < args->tmo.tv_sec); > + } > } > =20 > static int > @@ -121,13 +119,24 @@ do_test (void) > xclose (args.fds[0][0]); > xclose (args.fds[1][1]); > =20 > + args.tmo =3D (struct timeval) { .tv_sec =3D 10, .tv_usec =3D 0 }; > + { > + struct support_capture_subprocess result; > + result =3D support_capture_subprocess (do_test_child_alarm, &args); > + support_capture_subprocess_check (&result, "tst-select-child", 0, > + sc_allow_none); > + } > + > + args.tmo =3D (struct timeval) { .tv_sec =3D TYPE_MAXIMUM (time_t), > + .tv_usec =3D 0 }; > { > struct support_capture_subprocess result; > - result =3D support_capture_subprocess (do_test_child_alarm, NULL); > + result =3D support_capture_subprocess (do_test_child_alarm, &args); > support_capture_subprocess_check (&result, "tst-select-child", 0, > sc_allow_none); > } > =20 > + args.tmo =3D (struct timeval) { .tv_sec =3D 0, .tv_usec =3D 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 +=3D 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 > #include > #include > -#include > =20 > /* 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 =3D SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, > exceptfds, > + pts64, NULL); > + if (timeout !=3D NULL) > + TIMESPEC_TO_TIMEVAL (timeout, pts64); > + return r; > +#else > + bool is32bit =3D timeout !=3D NULL > + ? in_time_t_range (timeout->tv_sec) : true; > int r; > - if (supports_time64 ()) > + if (!is32bit) > { > - r =3D 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 >=3D 0 || errno !=3D ENOSYS) > + r =3D SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, > + exceptfds, pts64, NULL); > + if ((r >=3D 0 || errno !=3D ENOSYS) && timeout !=3D NULL) > { > - if (timeout !=3D NULL) > - TIMESPEC_TO_TIMEVAL (timeout, &ts64); > - return r; > + TIMESPEC_TO_TIMEVAL (timeout, &ts64); > } > - > - mark_time64_unsupported (); > + else > + __set_errno (EOVERFLOW); > + return r; > } > =20 > -#ifndef __ASSUME_TIME64_SYSCALLS > - struct timespec ts32, *pts32 =3D NULL; > - if (pts64 !=3D NULL) > - { > - if (! in_time_t_range (pts64->tv_sec)) > - { > - __set_errno (EINVAL); > - return -1; > - } > - ts32.tv_sec =3D s; > - ts32.tv_nsec =3D ns; > - pts32 =3D &ts32; > - } > -# ifndef __ASSUME_PSELECT > -# ifdef __NR__newselect > -# undef __NR_select > -# define __NR_select __NR__newselect > -# endif > - r =3D SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, > pts32); -# else > - r =3D SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, > pts32, > - NULL); > -# endif > - if (timeout !=3D NULL) > - *timeout =3D valid_timespec_to_timeval64 (ts32); > + return __select32 (nfds, readfds, writefds, exceptfds, pts64, > timeout); #endif > - > - return r; > } > =20 > #if __TIMESIZE !=3D 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 > + . */ > + > +#include > +#include > + > +#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 =3D NULL; > + if (ts64 !=3D NULL) > + { > + ts32.tv_sec =3D ts64->tv_sec; > + ts32.tv_nsec =3D ts64->tv_nsec; > + pts32 =3D &ts32; > + } > + > + int r =3D SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, > exceptfds, pts32, > + NULL); > + if (timeout !=3D NULL) > + TIMESPEC_TO_TIMEVAL (timeout, pts32); > + return r; > +#else > + struct timeval tv32, *ptv32 =3D NULL; > + if (ts64 !=3D NULL) > + { > + tv32 =3D valid_timespec64_to_timeval (*ts64); > + ptv32 =3D &tv32; > + } > + > + int r =3D SYSCALL_CANCEL (select, nfds, readfds, writefds, > exceptfds, ptv32); > + if (timeout !=3D NULL) > + *timeout =3D valid_timeval_to_timeval64 (tv32); > + return r; > +#endif /* __ASSUME_PSELECT */ > +} > + > +#endif Reviewed-by: Lukasz Majewski 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 --Sig_/Ejp9.E.k0RfcE9UT7IRHMzP Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- iQEzBAEBCgAdFiEEgAyFJ+N6uu6+XupJAR8vZIA0zr0FAmDQQwoACgkQAR8vZIA0 zr1ljQf/V1/T/lxs/yEuXd+m4ekDiVUaG4F2GX4t6tjlkw1b4iPIhG/E2cnv+NyF 17Fap/8+8xeswEBFKK8INbzDrngOPFsTEzkkBsHTYKSeiWD9SErGaNFENb5s9+mW rp78aMkf3WvPR656NVQY4P7IuJM3v/FY6EzzyreaJzdbNjaBbwpXrZr2ejJcXpPf D1RE5YT+kYTvEURYtIqZ9R4Dp6NKP2OFBViJqF3Ixdd2isc/tifdA/XOEDHBBGwZ +QfejPD+LdiBt5czH9OAbMDpM6vVVJUFOPhxOSClO06eq8jtBf1AHpLx2XVx+p31 3pZWlYXSMa+bPgqT/6Ng7vGCDSl5Qg== =sHzg -----END PGP SIGNATURE----- --Sig_/Ejp9.E.k0RfcE9UT7IRHMzP--