From patchwork Thu Jun 17 11:50:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 43865 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0DB6A3894412 for ; Thu, 17 Jun 2021 11:55:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0DB6A3894412 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1623930951; bh=y7lgduzDHGHJDqB2CtyXV6ZAiND8IVp+3qRksuODL8w=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=gxW/KnCb6ivc75C2ydZYx34xn60WVKh8rEpJ+DPhlQM0qEadwqIhzmYXvMakiuk+t 93hsKbM/KPP6HKW8bXPRp4ACMqg76/uIqypZHlt+CzpXXtR2LfZNXFegrWqY2MNt6h 6Ec0R4IpRc3FbnNfoKQSHE09gPv239y83gbaPgNg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x731.google.com (mail-qk1-x731.google.com [IPv6:2607:f8b0:4864:20::731]) by sourceware.org (Postfix) with ESMTPS id C2C793894430 for ; Thu, 17 Jun 2021 11:51:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C2C793894430 Received: by mail-qk1-x731.google.com with SMTP id g142so2770299qke.4 for ; Thu, 17 Jun 2021 04:51:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=y7lgduzDHGHJDqB2CtyXV6ZAiND8IVp+3qRksuODL8w=; b=HykSugU3MqzmXtsZf4nVv20iRKoEV0o6sqDYT4iJuBsFkG9+3zVXfbttgfnHma/7kc bCbHqFn7l0qUv+b4DcTRpXUl8VT4JU9k2WqSaiFpTFkS4L7IOID2rEDsLRd08YPYajRL FuN6+UaYqBLPtybxZ6XP91JMdaiv57Yxqy9MpuyE2ec/YrWBMJY7/sZTSFevQLWfHhZk d4F09aHp6UcecsUfuZae0D4h++nCFKujopnRLncHoq6Rkt3lyHOY5rKnmgmW77CVc5vA Jfr7B6oZ+mlXPb3Hy/i03ixDbD2TXuv2d23V0zcA8P8HmKhC7luk6rNwDhnVZS4BOQam 5Jvw== X-Gm-Message-State: AOAM530Itbgkt29/e+Q5SPmY0qVyVv217nrwUEpNianwW3dWibWl6YYC xKAzMmKgi/RuEl7LgEI6e8dph9elXEUEjw== X-Google-Smtp-Source: ABdhPJyPCXOVJR07C6k6x3XGtBfKeoctF/H+cpH76b1kUfpCLdna/94LMK+KSOSNuMud+8/ufkNSwg== X-Received: by 2002:a05:620a:1424:: with SMTP id k4mr3277461qkj.299.1623930678081; Thu, 17 Jun 2021 04:51:18 -0700 (PDT) Received: from birita.. ([177.194.59.218]) by smtp.googlemail.com with ESMTPSA id p12sm3016435qtw.61.2021.06.17.04.51.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Jun 2021 04:51:17 -0700 (PDT) To: libc-alpha@sourceware.org, Lukasz Majewski , Carlos O'Donell Subject: [PATCH 05/18] linux: Only use 64-bit syscall if required for pselect Date: Thu, 17 Jun 2021 08:50:51 -0300 Message-Id: <20210617115104.1359598-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210617115104.1359598-1-adhemerval.zanella@linaro.org> References: <20210617115104.1359598-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, 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-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" 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 --- 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 @@ . */ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include - 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 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 #include -#include + +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; }