From patchwork Wed Jan 19 09:13:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Cervesato X-Patchwork-Id: 1581716 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=Mh7g1z4L; dkim=fail reason="signature verification failed" header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=3Su+Ls7W; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jf0LY09wCz9tD5 for ; Wed, 19 Jan 2022 20:13:40 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 07B633C9690 for ; Wed, 19 Jan 2022 10:13:39 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-3.smtp.seeweb.it (in-3.smtp.seeweb.it [217.194.8.3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by picard.linux.it (Postfix) with ESMTPS id AFF803C96A7 for ; Wed, 19 Jan 2022 10:13:18 +0100 (CET) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by in-3.smtp.seeweb.it (Postfix) with ESMTPS id 3FBC81A00CA0 for ; Wed, 19 Jan 2022 10:13:14 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id B6D871F3BA; Wed, 19 Jan 2022 09:13:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1642583593; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vihEyHuRO0oFkvtvycHGSaW0i3wHUEbei2iRf0dR0YU=; b=Mh7g1z4L6LGoiAFt2tUleDqrPIQlRCRA+/Mx2HODpvkpzqaFlaWcw5vlGM43DB92/vY8Km hlGq+Yj0Igl4fccW1sxxnzRDdQVAHWTbEVg5i3G3jprxva1t1lbqI1b+iXQIQk2aZER9lz rXjpVIoYJGHpjZrkB3O8XPamOGKvuDQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1642583593; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vihEyHuRO0oFkvtvycHGSaW0i3wHUEbei2iRf0dR0YU=; b=3Su+Ls7WIwAXrFj0AKoaNjyv+/jDP/QzpU1orHd3DqI8PfnMgKJhQ/ffiULz6L3J1hZ40i 0oRV/RYCnjhO9QCQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 8E4FD13B2D; Wed, 19 Jan 2022 09:13:13 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id UCfRICnW52HfHQAAMHmgww (envelope-from ); Wed, 19 Jan 2022 09:13:13 +0000 From: Andrea Cervesato To: ltp@lists.linux.it Date: Wed, 19 Jan 2022 10:13:10 +0100 Message-Id: <20220119091311.22150-2-andrea.cervesato@suse.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220119091311.22150-1-andrea.cervesato@suse.de> References: <20220119091311.22150-1-andrea.cervesato@suse.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.102.4 at in-3.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-3.smtp.seeweb.it Subject: [LTP] [PATCH v2 1/2] Update lapi/futex.h fallback X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Added a complete futex.h definition with futex2 support Signed-off-by: Andrea Cervesato --- configure.ac | 3 + include/lapi/futex.h | 180 ++++++++++++++++++ include/lapi/syscalls/aarch64.in | 1 + include/lapi/syscalls/arc.in | 1 + include/lapi/syscalls/arm.in | 1 + include/lapi/syscalls/hppa.in | 1 + include/lapi/syscalls/i386.in | 1 + include/lapi/syscalls/ia64.in | 1 + include/lapi/syscalls/mips_n32.in | 1 + include/lapi/syscalls/mips_n64.in | 1 + include/lapi/syscalls/mips_o32.in | 1 + include/lapi/syscalls/powerpc.in | 1 + include/lapi/syscalls/powerpc64.in | 1 + include/lapi/syscalls/s390.in | 1 + include/lapi/syscalls/s390x.in | 1 + include/lapi/syscalls/sh.in | 1 + include/lapi/syscalls/sparc.in | 1 + include/lapi/syscalls/sparc64.in | 1 + include/lapi/syscalls/x86_64.in | 1 + lib/tst_checkpoint.c | 1 - testcases/kernel/syscalls/clone/clone08.c | 1 - .../syscalls/futex/futex_cmp_requeue01.c | 2 +- .../syscalls/futex/futex_cmp_requeue02.c | 2 +- testcases/kernel/syscalls/futex/futextest.h | 72 +++---- 24 files changed, 231 insertions(+), 47 deletions(-) diff --git a/configure.ac b/configure.ac index 3c56d1922..88afec2c8 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,7 @@ AC_CHECK_HEADERS_ONCE([ \ linux/close_range.h \ linux/dccp.h \ linux/fs.h \ + linux/futex.h \ linux/genetlink.h \ linux/if_alg.h \ linux/if_ether.h \ @@ -216,6 +217,8 @@ AC_CHECK_TYPES([struct xt_entry_match, struct xt_entry_target],,,[ AC_CHECK_TYPES([struct __kernel_old_timeval, struct __kernel_old_timespec, struct __kernel_timespec, struct __kernel_old_itimerspec, struct __kernel_itimerspec],,,[#include ]) +AC_CHECK_TYPES([struct futex_waitv],,,[#include ]) + # Tools knobs # Bash diff --git a/include/lapi/futex.h b/include/lapi/futex.h index 00b26c355..a05fcb89c 100644 --- a/include/lapi/futex.h +++ b/include/lapi/futex.h @@ -1,12 +1,14 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 2015 Linux Test Project + * Copyright (C) 2021 SUSE LLC Andrea Cervesato */ #ifndef LAPI_FUTEX_H__ #define LAPI_FUTEX_H__ #include +#include "config.h" typedef volatile uint32_t futex_t; @@ -14,4 +16,182 @@ typedef volatile uint32_t futex_t; #define SYS_futex SYS_futex_time64 #endif +#ifdef HAVE_LINUX_FUTEX_H +# include +#else +#include + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 +#define FUTEX_FD 2 +#define FUTEX_REQUEUE 3 +#define FUTEX_CMP_REQUEUE 4 +#define FUTEX_WAKE_OP 5 +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 +#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_WAIT_BITSET 9 +#define FUTEX_WAKE_BITSET 10 +#define FUTEX_WAIT_REQUEUE_PI 11 +#define FUTEX_CMP_REQUEUE_PI 12 +#define FUTEX_LOCK_PI2 13 + +#define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 +#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) + +#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) +#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) +#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) +#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) +#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) +#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) +#define FUTEX_LOCK_PI2_PRIVATE (FUTEX_LOCK_PI2 | FUTEX_PRIVATE_FLAG) +#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) +#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) +#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG) +#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG) +#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \ + FUTEX_PRIVATE_FLAG) +#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \ + FUTEX_PRIVATE_FLAG) + +/* + * Support for robust futexes: the kernel cleans up held futexes at + * thread exit time. + */ + +/* + * Per-lock list entry - embedded in user-space locks, somewhere close + * to the futex field. (Note: user-space uses a double-linked list to + * achieve O(1) list add and remove, but the kernel only needs to know + * about the forward link) + * + * NOTE: this structure is part of the syscall ABI, and must not be + * changed. + */ +struct robust_list { + struct robust_list *next; +}; + +/* + * Per-thread list head: + * + * NOTE: this structure is part of the syscall ABI, and must only be + * changed if the change is first communicated with the glibc folks. + * (When an incompatible change is done, we'll increase the structure + * size, which glibc will detect) + */ +struct robust_list_head { + /* + * The head of the list. Points back to itself if empty: + */ + struct robust_list list; + + /* + * This relative offset is set by user-space, it gives the kernel + * the relative position of the futex field to examine. This way + * we keep userspace flexible, to freely shape its data-structure, + * without hardcoding any particular offset into the kernel: + */ + long futex_offset; + + /* + * The death of the thread may race with userspace setting + * up a lock's links. So to handle this race, userspace first + * sets this field to the address of the to-be-taken lock, + * then does the lock acquire, and then adds itself to the + * list, and then clears this field. Hence the kernel will + * always have full knowledge of all locks that the thread + * _might_ have taken. We check the owner TID in any case, + * so only truly owned locks will be handled. + */ + struct robust_list *list_op_pending; +}; + +/* + * Are there any waiters for this robust futex: + */ +#define FUTEX_WAITERS 0x80000000 + +/* + * The kernel signals via this bit that a thread holding a futex + * has exited without unlocking the futex. The kernel also does + * a FUTEX_WAKE on such futexes, after setting the bit, to wake + * up any possible waiters: + */ +#define FUTEX_OWNER_DIED 0x40000000 + +/* + * The rest of the robust-futex field is for the TID: + */ +#define FUTEX_TID_MASK 0x3fffffff + +/* + * This limit protects against a deliberately circular list. + * (Not worth introducing an rlimit for it) + */ +#define ROBUST_LIST_LIMIT 2048 + +/* + * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a + * match of any bit. + */ +#define FUTEX_BITSET_MATCH_ANY 0xffffffff + + +#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */ +#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */ +#define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */ +#define FUTEX_OP_ANDN 3 /* *(int *)UADDR2 &= ~OPARG; */ +#define FUTEX_OP_XOR 4 /* *(int *)UADDR2 ^= OPARG; */ + +#define FUTEX_OP_OPARG_SHIFT 8 /* Use (1 << OPARG) instead of OPARG. */ + +#define FUTEX_OP_CMP_EQ 0 /* if (oldval == CMPARG) wake */ +#define FUTEX_OP_CMP_NE 1 /* if (oldval != CMPARG) wake */ +#define FUTEX_OP_CMP_LT 2 /* if (oldval < CMPARG) wake */ +#define FUTEX_OP_CMP_LE 3 /* if (oldval <= CMPARG) wake */ +#define FUTEX_OP_CMP_GT 4 /* if (oldval > CMPARG) wake */ +#define FUTEX_OP_CMP_GE 5 /* if (oldval >= CMPARG) wake */ + +/* FUTEX_WAKE_OP will perform atomically + int oldval = *(int *)UADDR2; + *(int *)UADDR2 = oldval OP OPARG; + if (oldval CMP CMPARG) + wake UADDR2; */ + +#define FUTEX_OP(op, oparg, cmp, cmparg) \ + (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \ + | ((oparg & 0xfff) << 12) | (cmparg & 0xfff)) + +#endif /* HAVE_LINUX_FUTEX_H */ + +#ifndef HAVE_STRUCT_FUTEX_WAITV +/* + * Flags to specify the bit length of the futex word for futex2 syscalls. + * Currently, only 32 is supported. + */ +#define FUTEX_32 2 + +/* + * Max numbers of elements in a futex_waitv array + */ +#define FUTEX_WAITV_MAX 128 + +/** + * struct futex_waitv - A waiter for vectorized wait + * @val: Expected value at uaddr + * @uaddr: User address to wait on + * @flags: Flags for this waiter + * @__reserved: Reserved member to preserve data alignment. Should be 0. + */ +struct futex_waitv { + uint64_t val; + uint64_t uaddr; + uint32_t flags; + uint32_t __reserved; +}; +#endif /* HAVE_STRUCT_FUTEX_WAITV */ + #endif /* LAPI_FUTEX_H__ */ diff --git a/include/lapi/syscalls/aarch64.in b/include/lapi/syscalls/aarch64.in index 89b63ee4b..de4ed5fb1 100644 --- a/include/lapi/syscalls/aarch64.in +++ b/include/lapi/syscalls/aarch64.in @@ -295,4 +295,5 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 _sysctl 1078 diff --git a/include/lapi/syscalls/arc.in b/include/lapi/syscalls/arc.in index 72420754a..9f11381db 100644 --- a/include/lapi/syscalls/arc.in +++ b/include/lapi/syscalls/arc.in @@ -315,3 +315,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/arm.in b/include/lapi/syscalls/arm.in index 2a78d7c3c..4b0f63a28 100644 --- a/include/lapi/syscalls/arm.in +++ b/include/lapi/syscalls/arm.in @@ -393,3 +393,4 @@ openat2 (__NR_SYSCALL_BASE+437) pidfd_getfd (__NR_SYSCALL_BASE+438) epoll_pwait2 (__NR_SYSCALL_BASE+441) quotactl_fd (__NR_SYSCALL_BASE+443) +futex_waitv (__NR_SYSCALL_BASE+449) diff --git a/include/lapi/syscalls/hppa.in b/include/lapi/syscalls/hppa.in index 2f0fc8153..b6d32d386 100644 --- a/include/lapi/syscalls/hppa.in +++ b/include/lapi/syscalls/hppa.in @@ -42,3 +42,4 @@ pidfd_open 434 close_range 436 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/i386.in b/include/lapi/syscalls/i386.in index 34a8a621f..d0e6e9a4b 100644 --- a/include/lapi/syscalls/i386.in +++ b/include/lapi/syscalls/i386.in @@ -429,3 +429,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/ia64.in b/include/lapi/syscalls/ia64.in index b729cd3f0..123200624 100644 --- a/include/lapi/syscalls/ia64.in +++ b/include/lapi/syscalls/ia64.in @@ -342,3 +342,4 @@ openat2 1461 pidfd_getfd 1462 epoll_pwait2 1465 quotactl_fd 1467 +futex_waitv 1473 diff --git a/include/lapi/syscalls/mips_n32.in b/include/lapi/syscalls/mips_n32.in index 46098a616..e818c9d92 100644 --- a/include/lapi/syscalls/mips_n32.in +++ b/include/lapi/syscalls/mips_n32.in @@ -370,3 +370,4 @@ process_madvise 6440 epoll_pwait2 6441 mount_setattr 6442 quotactl_fd 6443 +futex_waitv 6449 diff --git a/include/lapi/syscalls/mips_n64.in b/include/lapi/syscalls/mips_n64.in index 07f96ac5d..6e15f43b3 100644 --- a/include/lapi/syscalls/mips_n64.in +++ b/include/lapi/syscalls/mips_n64.in @@ -346,3 +346,4 @@ process_madvise 5440 epoll_pwait2 5441 mount_setattr 5442 quotactl_fd 5443 +futex_waitv 5449 diff --git a/include/lapi/syscalls/mips_o32.in b/include/lapi/syscalls/mips_o32.in index 5e64a4a1c..921d5d331 100644 --- a/include/lapi/syscalls/mips_o32.in +++ b/include/lapi/syscalls/mips_o32.in @@ -416,3 +416,4 @@ process_madvise 4440 epoll_pwait2 4441 mount_setattr 4442 quotactl_fd 4443 +futex_waitv 4449 diff --git a/include/lapi/syscalls/powerpc.in b/include/lapi/syscalls/powerpc.in index f4e85940c..d5de621e1 100644 --- a/include/lapi/syscalls/powerpc.in +++ b/include/lapi/syscalls/powerpc.in @@ -422,3 +422,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/powerpc64.in b/include/lapi/syscalls/powerpc64.in index f4e85940c..d5de621e1 100644 --- a/include/lapi/syscalls/powerpc64.in +++ b/include/lapi/syscalls/powerpc64.in @@ -422,3 +422,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/s390.in b/include/lapi/syscalls/s390.in index 3e16d8475..6505f3822 100644 --- a/include/lapi/syscalls/s390.in +++ b/include/lapi/syscalls/s390.in @@ -409,3 +409,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/s390x.in b/include/lapi/syscalls/s390x.in index beb0819af..bc5d2b34c 100644 --- a/include/lapi/syscalls/s390x.in +++ b/include/lapi/syscalls/s390x.in @@ -357,3 +357,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/sh.in b/include/lapi/syscalls/sh.in index a81cf8297..316ffe5f1 100644 --- a/include/lapi/syscalls/sh.in +++ b/include/lapi/syscalls/sh.in @@ -403,3 +403,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/sparc.in b/include/lapi/syscalls/sparc.in index 6a7817ae5..e0c60a360 100644 --- a/include/lapi/syscalls/sparc.in +++ b/include/lapi/syscalls/sparc.in @@ -408,3 +408,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/sparc64.in b/include/lapi/syscalls/sparc64.in index d3995181c..0acde6856 100644 --- a/include/lapi/syscalls/sparc64.in +++ b/include/lapi/syscalls/sparc64.in @@ -373,3 +373,4 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in index a5b2a24fe..1863e1df7 100644 --- a/include/lapi/syscalls/x86_64.in +++ b/include/lapi/syscalls/x86_64.in @@ -350,6 +350,7 @@ openat2 437 pidfd_getfd 438 epoll_pwait2 441 quotactl_fd 443 +futex_waitv 449 rt_sigaction 512 rt_sigreturn 513 ioctl 514 diff --git a/lib/tst_checkpoint.c b/lib/tst_checkpoint.c index b41986f0c..6a294b28b 100644 --- a/lib/tst_checkpoint.c +++ b/lib/tst_checkpoint.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "test.h" #include "safe_macros.h" diff --git a/testcases/kernel/syscalls/clone/clone08.c b/testcases/kernel/syscalls/clone/clone08.c index 3de1fe9bb..ad285a497 100644 --- a/testcases/kernel/syscalls/clone/clone08.c +++ b/testcases/kernel/syscalls/clone/clone08.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "tst_test.h" #include "clone_platform.h" diff --git a/testcases/kernel/syscalls/futex/futex_cmp_requeue01.c b/testcases/kernel/syscalls/futex/futex_cmp_requeue01.c index 13e67c758..bef44838e 100644 --- a/testcases/kernel/syscalls/futex/futex_cmp_requeue01.c +++ b/testcases/kernel/syscalls/futex/futex_cmp_requeue01.c @@ -12,12 +12,12 @@ #include #include #include -#include #include #include "tst_timer_test.h" #include "tst_test.h" #include "futextest.h" +#include "lapi/futex.h" struct shared_data { futex_t futexes[2]; diff --git a/testcases/kernel/syscalls/futex/futex_cmp_requeue02.c b/testcases/kernel/syscalls/futex/futex_cmp_requeue02.c index 0514b0ba4..073ea3bf6 100644 --- a/testcases/kernel/syscalls/futex/futex_cmp_requeue02.c +++ b/testcases/kernel/syscalls/futex/futex_cmp_requeue02.c @@ -13,11 +13,11 @@ */ #include -#include #include #include "tst_test.h" #include "futextest.h" +#include "lapi/futex.h" static futex_t *futexes; diff --git a/testcases/kernel/syscalls/futex/futextest.h b/testcases/kernel/syscalls/futex/futextest.h index 3f2f36fef..da5f61767 100644 --- a/testcases/kernel/syscalls/futex/futextest.h +++ b/testcases/kernel/syscalls/futex/futextest.h @@ -14,54 +14,15 @@ #define _FUTEXTEST_H #include -#include +#include #include -#include -#include "lapi/futex.h" +#include "tst_test.h" #include "tst_timer.h" +#include "lapi/futex.h" +#include "lapi/syscalls.h" #define FUTEX_INITIALIZER 0 -#ifndef FUTEX_CMP_REQUEUE -# define FUTEX_CMP_REQUEUE 4 -#endif -#ifndef FUTEX_WAKE_OP -# define FUTEX_WAKE_OP 5 -#endif -#ifndef FUTEX_LOCK_PI -# define FUTEX_LOCK_PI 6 -#endif -#ifndef FUTEX_UNLOCK_PI -# define FUTEX_UNLOCK_PI 7 -#endif -#ifndef FUTEX_WAIT_BITSET -# define FUTEX_WAIT_BITSET 9 -#endif -#ifndef FUTEX_WAKE_BITSET -# define FUTEX_WAKE_BITSET 10 -#endif -#ifndef FUTEX_WAIT_REQUEUE_PI -# define FUTEX_WAIT_REQUEUE_PI 11 -#endif -#ifndef FUTEX_CMP_REQUEUE_PI -# define FUTEX_CMP_REQUEUE_PI 12 -#endif -#ifndef FUTEX_PRIVATE_FLAG -# define FUTEX_PRIVATE_FLAG 128 -#endif -#ifndef FUTEX_WAIT_REQUEUE_PI_PRIVATE -# define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \ - FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_REQUEUE_PI_PRIVATE -# define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \ - FUTEX_PRIVATE_FLAG) -#endif - -#ifndef FUTEX_CLOCK_REALTIME -# define FUTEX_CLOCK_REALTIME 256 -#endif - enum futex_fn_type { FUTEX_FN_FUTEX, FUTEX_FN_FUTEX64, @@ -74,6 +35,16 @@ struct futex_test_variants { char *desc; }; +struct futex_test_variants futex_variants[] = { +#if (__NR_futex != __LTP__NR_INVALID_SYSCALL) + { .fntype = FUTEX_FN_FUTEX, .desc = "syscall with old kernel spec" }, +#endif + +#if (__NR_futex_time64 != __LTP__NR_INVALID_SYSCALL) + { .fntype = FUTEX_FN_FUTEX64, .desc = "syscall time64 with kernel spec" }, +#endif +}; + static inline void futex_supported_by_kernel(enum futex_fn_type fntype) { if (fntype != FUTEX_FN_FUTEX64) @@ -318,4 +289,19 @@ futex_set(futex_t *uaddr, u_int32_t newval) return newval; } +/** + * futex_waitv - Wait at multiple futexes, wake on any + * @waiters: Array of waiters + * @nr_waiters: Length of waiters array + * @flags: Operation flags + * @timo: Optional timeout for operation + */ +static inline int +tst_futex_waitv(volatile struct futex_waitv *waiters, unsigned long nr_waiters, + unsigned long flags, struct timespec *timo, clockid_t clockid) +{ + return tst_syscall(__NR_futex_waitv, + waiters, nr_waiters, flags, timo, clockid); +} + #endif From patchwork Wed Jan 19 09:13:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Cervesato X-Patchwork-Id: 1581713 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=cxbaTkQ4; dkim=fail reason="signature verification failed" header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=QSgCuYil; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jf0LD1X0fz9tD5 for ; Wed, 19 Jan 2022 20:13:22 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 105B73C967E for ; Wed, 19 Jan 2022 10:13:18 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-3.smtp.seeweb.it (in-3.smtp.seeweb.it [217.194.8.3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by picard.linux.it (Postfix) with ESMTPS id 1EF093C875F for ; Wed, 19 Jan 2022 10:13:15 +0100 (CET) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by in-3.smtp.seeweb.it (Postfix) with ESMTPS id 573461A00CA3 for ; Wed, 19 Jan 2022 10:13:14 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id EAB711F384; Wed, 19 Jan 2022 09:13:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1642583593; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WtFStwh671oAP1VRqGqLe1XIO17xbxvqYipUK9jpmS4=; b=cxbaTkQ4aahID+ZgpWxYoYisjDpvNzlmERlmLjti28QG40n2jNK1+8ibjH8kgfan1Dg11R dTgKSgPkCIBJ84zA4Zh1i7b3Z+2R5wZjnbVKiKrN4sqpg7CvZFDcu2N8UUX7lDGro1/OQW NyGsDXCFFM2s9Uz6La2L9BfYV2Dmv0M= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1642583593; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WtFStwh671oAP1VRqGqLe1XIO17xbxvqYipUK9jpmS4=; b=QSgCuYilQ6T9Qx2OzwLI4ka9sw51x8AgyWzk1FH1Payd5PpAn7bKIdhNL+gpThn3A0RXcY mJgX96znoLyM3HAw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id C4E7E13B2D; Wed, 19 Jan 2022 09:13:13 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id APTnLSnW52HfHQAAMHmgww (envelope-from ); Wed, 19 Jan 2022 09:13:13 +0000 From: Andrea Cervesato To: ltp@lists.linux.it Date: Wed, 19 Jan 2022 10:13:11 +0100 Message-Id: <20220119091311.22150-3-andrea.cervesato@suse.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220119091311.22150-1-andrea.cervesato@suse.de> References: <20220119091311.22150-1-andrea.cervesato@suse.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.102.4 at in-3.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-3.smtp.seeweb.it Subject: [LTP] [PATCH v2 2/2] Add futex_waitv testing suite X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Signed-off-by: Andrea Cervesato --- testcases/kernel/syscalls/futex/.gitignore | 3 + testcases/kernel/syscalls/futex/Makefile | 14 +- .../kernel/syscalls/futex/futex_waitv01.c | 129 ++++++++++++++++++ .../kernel/syscalls/futex/futex_waitv02.c | 104 ++++++++++++++ .../kernel/syscalls/futex/futex_waitv03.c | 112 +++++++++++++++ 5 files changed, 360 insertions(+), 2 deletions(-) create mode 100644 testcases/kernel/syscalls/futex/futex_waitv01.c create mode 100644 testcases/kernel/syscalls/futex/futex_waitv02.c create mode 100644 testcases/kernel/syscalls/futex/futex_waitv03.c diff --git a/testcases/kernel/syscalls/futex/.gitignore b/testcases/kernel/syscalls/futex/.gitignore index 54cd02b02..9d08ba7d3 100644 --- a/testcases/kernel/syscalls/futex/.gitignore +++ b/testcases/kernel/syscalls/futex/.gitignore @@ -10,3 +10,6 @@ /futex_wake02 /futex_wake03 /futex_wake04 +/futex_waitv01 +/futex_waitv02 +/futex_waitv03 diff --git a/testcases/kernel/syscalls/futex/Makefile b/testcases/kernel/syscalls/futex/Makefile index 5713c615d..7228496bc 100644 --- a/testcases/kernel/syscalls/futex/Makefile +++ b/testcases/kernel/syscalls/futex/Makefile @@ -3,8 +3,18 @@ top_srcdir ?= ../../../.. -futex_cmp_requeue01 futex_cmp_requeue02 futex_wait02 futex_wake03 futex_wait05 futex_wait_bitset01: LDLIBS += -lrt -futex_wait03 futex_wake02 futex_wake04: CFLAGS += -pthread +futex_cmp_requeue01: LDLIBS+=-lrt +futex_cmp_requeue02: LDLIBS+=-lrt +futex_wait02: LDLIBS+=-lrt +futex_wake03: LDLIBS+=-lrt +futex_wait05: LDLIBS+=-lrt +futex_wait_bitset01: LDLIBS+=-lrt + +futex_wait03: CFLAGS+=-pthread +futex_wake02: CFLAGS+=-pthread +futex_wake04: CFLAGS+=-pthread +futex_waitv02: CFLAGS+=-pthread +futex_waitv03: CFLAGS+=-pthread include $(top_srcdir)/include/mk/testcases.mk include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/futex/futex_waitv01.c b/testcases/kernel/syscalls/futex/futex_waitv01.c new file mode 100644 index 000000000..ccf1699de --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex_waitv01.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021 SUSE LLC Andrea Cervesato + */ + +/*\ + * [Description] + * + * This test verifies EINVAL for futex_waitv syscall. + */ + +#include +#include +#include "tst_test.h" +#include "futextest.h" + +static char *str_numfutex; +static int numfutex = 30; + +static uint32_t *futexes; +static struct futex_waitv *waitv; + +static void setup(void) +{ + struct futex_test_variants tv; + int i; + + tv = futex_variants[tst_variant]; + + tst_res(TINFO, "Testing variant: %s", tv.desc); + futex_supported_by_kernel(tv.fntype); + + if (tst_parse_int(str_numfutex, &numfutex, 1, FUTEX_WAITV_MAX)) + tst_brk(TBROK, "Invalid number of futexes '%s'", str_numfutex); + + futexes = SAFE_MALLOC(sizeof(uint32_t) * numfutex); + memset(futexes, 0, numfutex); + + waitv = SAFE_MALLOC(sizeof(struct futex_waitv) * numfutex); + for (i = 0; i < numfutex; i++) { + waitv[i].uaddr = (uintptr_t)&futexes[i]; + waitv[i].flags = FUTEX_32 | FUTEX_PRIVATE_FLAG; + waitv[i].val = 0; + } +} + +static void cleanup(void) +{ + free(futexes); + free(waitv); +} + +static void init_timeout(struct timespec *to) +{ + if (clock_gettime(CLOCK_MONOTONIC, to)) + tst_brk(TBROK, "gettime64 failed"); + + to->tv_sec++; +} + +static void run(void) +{ + struct timespec to; + int res; + + /* Testing a waiter without FUTEX_32 flag */ + waitv[0].flags = FUTEX_PRIVATE_FLAG; + + init_timeout(&to); + + res = tst_futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC); + if (res == EINVAL) + tst_res(TFAIL, "futex_waitv private returned: %d %s", res, tst_strerrno(res)); + else + tst_res(TPASS, "futex_waitv without FUTEX_32"); + + /* Testing a waiter with an unaligned address */ + waitv[0].flags = FUTEX_PRIVATE_FLAG | FUTEX_32; + waitv[0].uaddr = 1; + + init_timeout(&to); + + res = tst_futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC); + if (res == EINVAL) + tst_res(TFAIL, "futex_waitv private returned: %d %s", res, tst_strerrno(res)); + else + tst_res(TPASS, "futex_waitv with an unaligned address"); + + /* Testing a NULL address for waiters.uaddr */ + waitv[0].uaddr = 0x00000000; + + init_timeout(&to); + + res = tst_futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC); + if (res == EINVAL) + tst_res(TFAIL, "futex_waitv private returned: %d %s", res, tst_strerrno(res)); + else + tst_res(TPASS, "futex_waitv NULL address in waitv.uaddr"); + + /* Testing a NULL address for *waiters */ + init_timeout(&to); + + res = tst_futex_waitv(NULL, numfutex, 0, &to, CLOCK_MONOTONIC); + if (res == EINVAL) + tst_res(TFAIL, "futex_waitv private returned: %d %s", res, tst_strerrno(res)); + else + tst_res(TPASS, "futex_waitv NULL address in *waiters"); + + /* Testing an invalid clockid */ + init_timeout(&to); + + res = tst_futex_waitv(NULL, numfutex, 0, &to, CLOCK_TAI); + if (res == EINVAL) + tst_res(TFAIL, "futex_waitv private returned: %d %s", res, tst_strerrno(res)); + else + tst_res(TPASS, "futex_waitv invalid clockid"); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .min_kver = "5.16", + .test_variants = ARRAY_SIZE(futex_variants), + .options = (struct tst_option[]){ + {"n:", &str_numfutex, "Number of futex (default 30)"}, + {}, + }, +}; diff --git a/testcases/kernel/syscalls/futex/futex_waitv02.c b/testcases/kernel/syscalls/futex/futex_waitv02.c new file mode 100644 index 000000000..a19568993 --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex_waitv02.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021 SUSE LLC Andrea Cervesato + */ + +/*\ + * [Description] + * + * This test verifies futex_waitv syscall using private data. + */ + +#include +#include +#include "tst_test.h" +#include "tst_safe_pthread.h" +#include "futextest.h" + +static char *str_numfutex; +static int numfutex = 30; + +static uint32_t *futexes; +static struct futex_waitv *waitv; + +static void setup(void) +{ + struct futex_test_variants tv; + int i; + + tv = futex_variants[tst_variant]; + + tst_res(TINFO, "Testing variant: %s", tv.desc); + futex_supported_by_kernel(tv.fntype); + + if (tst_parse_int(str_numfutex, &numfutex, 1, FUTEX_WAITV_MAX)) + tst_brk(TBROK, "Invalid number of futexes '%s'", str_numfutex); + + futexes = SAFE_MALLOC(sizeof(uint32_t) * numfutex); + memset(futexes, 0, numfutex); + + waitv = SAFE_MALLOC(sizeof(struct futex_waitv) * numfutex); + for (i = 0; i < numfutex; i++) { + waitv[i].uaddr = (uintptr_t)&futexes[i]; + waitv[i].flags = FUTEX_32 | FUTEX_PRIVATE_FLAG; + waitv[i].val = 0; + } +} + +static void cleanup(void) +{ + free(futexes); + free(waitv); +} + +static void *threaded(void *arg) +{ + struct futex_test_variants tv; + int ret, pid = *(int *)arg; + + tv = futex_variants[tst_variant]; + + TST_PROCESS_STATE_WAIT(pid, 'S', 0); + + ret = futex_wake(tv.fntype, (void *)(uintptr_t)waitv[numfutex - 1].uaddr, 1, FUTEX_PRIVATE_FLAG); + if (ret < 0) + tst_brk(TBROK, "futex_wake private returned: %d %s", ret, tst_strerrno(-ret)); + + return NULL; +} + +static void run(void) +{ + struct timespec to; + int ret, pid = getpid(); + pthread_t t; + + SAFE_PTHREAD_CREATE(&t, NULL, threaded, (void *)&pid); + + /* setting absolute timeout for futex2 */ + if (clock_gettime(CLOCK_MONOTONIC, &to)) + tst_brk(TBROK, "gettime64 failed"); + + to.tv_sec++; + + ret = tst_futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC); + if (ret < 0) + tst_brk(TBROK, "futex_waitv returned: %d %s", ret, tst_strerrno(-ret)); + else if (ret != numfutex - 1) + tst_res(TFAIL, "futex_waitv returned: %d, expecting %d", ret, numfutex - 1); + + SAFE_PTHREAD_JOIN(t, NULL); + tst_res(TPASS, "futex_waitv returned correctly"); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .min_kver = "5.16", + .test_variants = ARRAY_SIZE(futex_variants), + .options = (struct tst_option[]){ + {"n:", &str_numfutex, "Number of futex (default 30)"}, + {}, + }, +}; diff --git a/testcases/kernel/syscalls/futex/futex_waitv03.c b/testcases/kernel/syscalls/futex/futex_waitv03.c new file mode 100644 index 000000000..3f18a15a2 --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex_waitv03.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021 SUSE LLC Andrea Cervesato + */ + +/*\ + * [Description] + * + * This test verifies futex_waitv syscall using shared data. + */ + +#include +#include +#include +#include "tst_test.h" +#include "tst_safe_pthread.h" +#include "futextest.h" + +static char *str_numfutex; +static int numfutex = 30; + +static struct futex_waitv *waitv; + +static void setup(void) +{ + struct futex_test_variants tv; + int shm_id; + int i; + + tv = futex_variants[tst_variant]; + + tst_res(TINFO, "Testing variant: %s", tv.desc); + futex_supported_by_kernel(tv.fntype); + + if (tst_parse_int(str_numfutex, &numfutex, 1, FUTEX_WAITV_MAX)) + tst_brk(TBROK, "Invalid number of futexes '%s'", str_numfutex); + + waitv = SAFE_MALLOC(sizeof(struct futex_waitv) * numfutex); + for (i = 0; i < numfutex; i++) { + shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666); + if (shm_id < 0) + tst_brk(TBROK, "shmget"); + + unsigned int *shared_data = shmat(shm_id, NULL, 0); + + waitv[i].uaddr = (uintptr_t)shared_data; + waitv[i].flags = FUTEX_32; + waitv[i].val = 0; + } +} + +static void cleanup(void) +{ + int i; + + for (i = 0; i < numfutex; i++) + shmdt((void *)(uintptr_t)waitv[i].uaddr); + + free(waitv); +} + +static void *threaded(void *arg) +{ + struct futex_test_variants tv; + int ret, pid = *(int *)arg; + + tv = futex_variants[tst_variant]; + + TST_PROCESS_STATE_WAIT(pid, 'S', 0); + + ret = futex_wake(tv.fntype, (void *)(uintptr_t)waitv[numfutex - 1].uaddr, 1, 0); + if (ret < 0) + tst_brk(TBROK, "futex_wake private returned: %d %s", ret, tst_strerrno(-ret)); + + return NULL; +} + +static void run(void) +{ + struct timespec to; + int ret, pid = getpid(); + pthread_t t; + + SAFE_PTHREAD_CREATE(&t, NULL, threaded, (void *)&pid); + + /* setting absolute timeout for futex2 */ + if (clock_gettime(CLOCK_MONOTONIC, &to)) + tst_brk(TBROK, "gettime64 failed"); + + to.tv_sec++; + + ret = tst_futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC); + if (ret < 0) + tst_brk(TBROK, "futex_waitv returned: %d %s", ret, tst_strerrno(-ret)); + else if (ret != numfutex - 1) + tst_res(TFAIL, "futex_waitv returned: %d, expecting %d", ret, numfutex - 1); + + SAFE_PTHREAD_JOIN(t, NULL); + tst_res(TPASS, "futex_waitv returned correctly"); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .min_kver = "5.16", + .test_variants = ARRAY_SIZE(futex_variants), + .options = (struct tst_option[]){ + {"n:", &str_numfutex, "Number of futex (default 30)"}, + {}, + }, +};