From patchwork Mon Feb 7 14:41:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Cervesato X-Patchwork-Id: 1589329 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=yluIPNHK; dkim=fail reason="signature verification failed" header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=WhOsgk69; 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 4JspkX5D7qz9s8q for ; Tue, 8 Feb 2022 01:41:56 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 355EB3C9AF3 for ; Mon, 7 Feb 2022 15:41:54 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-5.smtp.seeweb.it (in-5.smtp.seeweb.it [217.194.8.5]) (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 C5DA43C013D for ; Mon, 7 Feb 2022 15:41:51 +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-5.smtp.seeweb.it (Postfix) with ESMTPS id 424A76002A6 for ; Mon, 7 Feb 2022 15:41:51 +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 A33121F380; Mon, 7 Feb 2022 14:41:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1644244910; 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=CtabEwx/mL7ykaU8xdZTAgMWpu7ATYLCVdf7ndg68Uc=; b=yluIPNHKYvGH7nc7hWxjm3exyYo/gc1TRHA4D/DwxK8UhN0nlclg/wNBPe7MveqA9p/z5H kjGwzoQVNbnxtgrdNw11nP17JKOjTM1DUMMmyZMgxsQ62agOOVy5fkbC9ptXRYa3mAVQGd ojcM+xmMRAXzgqdYPUo/0IyCASs9NHc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1644244910; 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=CtabEwx/mL7ykaU8xdZTAgMWpu7ATYLCVdf7ndg68Uc=; b=WhOsgk69e+/dwsW6hpriQYiYxDMj7DH2AsmJXbNfrNQIfmBhsXoCyrWScIY2P1gELKIKo0 NpPF1IIB7oXeNnDg== 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 6D2ED13C28; Mon, 7 Feb 2022 14:41:50 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oPPBGK4vAWJwSwAAMHmgww (envelope-from ); Mon, 07 Feb 2022 14:41:50 +0000 From: Andrea Cervesato To: ltp@lists.linux.it Date: Mon, 7 Feb 2022 15:41:46 +0100 Message-Id: <20220207144148.27033-2-andrea.cervesato@suse.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207144148.27033-1-andrea.cervesato@suse.de> References: <20220207144148.27033-1-andrea.cervesato@suse.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.102.4 at in-5.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, T_SCC_BODY_TEXT_LINE autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-5.smtp.seeweb.it Subject: [LTP] [PATCH v4 1/3] Add TST_THREAD_STATE_WAIT macro 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" The TST_THREAD_STATE_WAIT macro can be used to wait and check for pthread state changes. Signed-off-by: Andrea Cervesato --- include/tst_test.h | 1 + include/tst_thread_state.h | 33 +++++++++++++++++++++++++++++++++ lib/tst_thread_state.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 include/tst_thread_state.h create mode 100644 lib/tst_thread_state.c diff --git a/include/tst_test.h b/include/tst_test.h index 450ddf086..79067f3bf 100644 --- a/include/tst_test.h +++ b/include/tst_test.h @@ -27,6 +27,7 @@ #include "tst_cmd.h" #include "tst_cpu.h" #include "tst_process_state.h" +#include "tst_thread_state.h" #include "tst_atomic.h" #include "tst_kvercmp.h" #include "tst_kernel.h" diff --git a/include/tst_thread_state.h b/include/tst_thread_state.h new file mode 100644 index 000000000..4d6a345b8 --- /dev/null +++ b/include/tst_thread_state.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022 SUSE LLC Andrea Cervesato + */ + +/* + * These functions helps you wait till a thread with given tpid changes state. + */ + +#ifndef TST_THREAD_STATE__ +#define TST_THREAD_STATE__ + +#include + +/* + * Waits for thread state change. + * + * The state is one of the following: + * + * R - running + * S - sleeping + * D - disk sleep + * T - stopped + * t - tracing stopped + * Z - zombie + * X - dead + */ +#define TST_THREAD_STATE_WAIT(tid, state, msec_timeout) \ + tst_thread_state_wait((tid), (state), (msec_timeout)) + +int tst_thread_state_wait(pid_t tid, const char state, unsigned int msec_timeout); + +#endif /* TST_THREAD_STATE__ */ diff --git a/lib/tst_thread_state.c b/lib/tst_thread_state.c new file mode 100644 index 000000000..f5580c39e --- /dev/null +++ b/lib/tst_thread_state.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022 SUSE LLC Andrea Cervesato + */ + +#include +#include +#include +#include + +#include "tst_safe_file_ops.h" +#include "tst_thread_state.h" + +int tst_thread_state_wait(pid_t tid, const char state, unsigned int msec_timeout) +{ + char proc_path[128], cur_state; + unsigned int msecs = 0; + + snprintf(proc_path, sizeof(proc_path), "/proc/self/task/%i/stat", tid); + + for (;;) { + SAFE_FILE_SCANF(proc_path, "%*i %*s %c", &cur_state); + + if (state == cur_state) + break; + + usleep(1000); + msecs += 1; + + if (msec_timeout && msecs >= msec_timeout) { + errno = ETIMEDOUT; + return -1; + } + } + + return 0; +} From patchwork Mon Feb 7 14:41:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Cervesato X-Patchwork-Id: 1589332 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=qG8xY4la; dkim=fail reason="signature verification failed" header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=BDr9qvpV; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (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 4Jspl848Dnz9s8q for ; Tue, 8 Feb 2022 01:42:28 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 09A313C9AE6 for ; Mon, 7 Feb 2022 15:42:26 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-4.smtp.seeweb.it (in-4.smtp.seeweb.it [217.194.8.4]) (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 457D63C9B1B for ; Mon, 7 Feb 2022 15:42:02 +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-4.smtp.seeweb.it (Postfix) with ESMTPS id 4868310005CD for ; Mon, 7 Feb 2022 15:41:51 +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 D3F341F386; Mon, 7 Feb 2022 14:41:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1644244910; 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=CgmGy3siJ69E/VcHcDVpAlXTCnWcAHAhwTMAge0P5ro=; b=qG8xY4labhRd7lZo0ZK5A50WM7MmGTGmwSOi96/NXnZljUntH1nHrGp3EO709U/oF7ZAeg z3GdHmh6a9Rk8fbyHxGjJsJTjSXVbbcD8MHxtH7Ga7C/W6RydgN2uKdNZgjKeyHJkTc3Vi IJNSe0hnsitUPkHalwq4yxIxom4uPLc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1644244910; 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=CgmGy3siJ69E/VcHcDVpAlXTCnWcAHAhwTMAge0P5ro=; b=BDr9qvpV0LIdZmkJeeMIwiYvmYKcAu8IlcNp0Dj52DlB/3QYfodHYuVqVT4/CiYzyDm9vn s/vT2vDXVfpTVsAg== 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 A025713C33; Mon, 7 Feb 2022 14:41:50 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id CBESJa4vAWJwSwAAMHmgww (envelope-from ); Mon, 07 Feb 2022 14:41:50 +0000 From: Andrea Cervesato To: ltp@lists.linux.it Date: Mon, 7 Feb 2022 15:41:47 +0100 Message-Id: <20220207144148.27033-3-andrea.cervesato@suse.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207144148.27033-1-andrea.cervesato@suse.de> References: <20220207144148.27033-1-andrea.cervesato@suse.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.102.4 at in-4.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, T_SCC_BODY_TEXT_LINE autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-4.smtp.seeweb.it Subject: [LTP] [PATCH v4 2/3] 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 +- 23 files changed, 202 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index aeb486f69..b4a8427d0 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; From patchwork Mon Feb 7 14:41:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Cervesato X-Patchwork-Id: 1589330 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=y6dsv0Y0; dkim=fail reason="signature verification failed" header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=QcREfYZX; 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 4Jspkk2yb5z9s8q for ; Tue, 8 Feb 2022 01:42:06 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 50F553C9AC6 for ; Mon, 7 Feb 2022 15:42:04 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [217.194.8.7]) (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 8174A3C013D for ; Mon, 7 Feb 2022 15:41:52 +0100 (CET) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) (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-7.smtp.seeweb.it (Postfix) with ESMTPS id 70D302009B2 for ; Mon, 7 Feb 2022 15:41:51 +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-out1.suse.de (Postfix) with ESMTPS id 068ED21102; Mon, 7 Feb 2022 14:41:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1644244911; 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=F/H6SHon1nNWjrydoXs5hba0mSD3Hfo+O6aaK1YhR0A=; b=y6dsv0Y016WYDkefgdX/9MQBgrzDCE6Fq41462L93IWrOk3gOF2tKpPOrv06gK8Fr8a63T NWX37GEKDOl5EgekPGS8DXvBDdX6sxRxmtwDhBX4AACvujpXhyrtcuRjBhQrXTGjrFH+f0 mleyURCBBUf/yKLCn6/NkmahgrpQ4ws= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1644244911; 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=F/H6SHon1nNWjrydoXs5hba0mSD3Hfo+O6aaK1YhR0A=; b=QcREfYZXd37eLA+VLxEzJEpZ6vgopwuNrPTAwRZR/0rmA4lHPrcX1REklQYBWtVxDMsLKH w0Xa0FnM43kzpWBg== 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 D541E13C28; Mon, 7 Feb 2022 14:41:50 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id cPf8Ma4vAWJwSwAAMHmgww (envelope-from ); Mon, 07 Feb 2022 14:41:50 +0000 From: Andrea Cervesato To: ltp@lists.linux.it Date: Mon, 7 Feb 2022 15:41:48 +0100 Message-Id: <20220207144148.27033-4-andrea.cervesato@suse.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207144148.27033-1-andrea.cervesato@suse.de> References: <20220207144148.27033-1-andrea.cervesato@suse.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.102.4 at in-7.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, T_SCC_BODY_TEXT_LINE autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-7.smtp.seeweb.it Subject: [LTP] [PATCH v4 3/3] 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 --- v4 introduces guarded buffers, more safe macros and TST_THREAD_STATE_WAIT usage. testcases/kernel/syscalls/futex/.gitignore | 3 + testcases/kernel/syscalls/futex/Makefile | 14 +- testcases/kernel/syscalls/futex/futex2test.h | 30 ++++ .../kernel/syscalls/futex/futex_waitv01.c | 162 ++++++++++++++++++ .../kernel/syscalls/futex/futex_waitv02.c | 111 ++++++++++++ .../kernel/syscalls/futex/futex_waitv03.c | 122 +++++++++++++ testcases/kernel/syscalls/futex/futextest.h | 58 ++----- 7 files changed, 456 insertions(+), 44 deletions(-) create mode 100644 testcases/kernel/syscalls/futex/futex2test.h 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/futex2test.h b/testcases/kernel/syscalls/futex/futex2test.h new file mode 100644 index 000000000..ec3667376 --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex2test.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Futex2 library addons for futex tests + * + * Copyright 2021 Collabora Ltd. + * Copyright (C) 2021 SUSE LLC Andrea Cervesato + */ + +#ifndef _FUTEX2TEST_H +#define _FUTEX2TEST_H + +#include +#include "lapi/syscalls.h" +#include "futextest.h" + +/** + * 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 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 /* _FUTEX2TEST_H */ \ No newline at end of file diff --git a/testcases/kernel/syscalls/futex/futex_waitv01.c b/testcases/kernel/syscalls/futex/futex_waitv01.c new file mode 100644 index 000000000..928740c2f --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex_waitv01.c @@ -0,0 +1,162 @@ +// 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 "tst_test.h" +#include "lapi/futex.h" +#include "futex2test.h" +#include "tst_safe_clocks.h" + +static uint32_t *futex; +static struct futex_waitv *waitv; + +static void setup(void) +{ + struct futex_test_variants tv; + + tv = futex_variants(); + + tst_res(TINFO, "Testing variant: %s", tv.desc); + futex_supported_by_kernel(tv.fntype); + + futex = SAFE_MALLOC(sizeof(uint32_t)); + *futex = FUTEX_INITIALIZER; + + waitv = tst_alloc(sizeof(struct futex_waitv)); +} + +static void init_timeout(struct timespec *to) +{ + SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, to); + to->tv_sec++; +} + +static void init_waitv(void) +{ + waitv->uaddr = (uintptr_t)&futex; + waitv->flags = FUTEX_32 | FUTEX_PRIVATE_FLAG; + waitv->val = 0; +} + +static void test_invalid_flags(void) +{ + struct timespec to; + int res; + + init_waitv(); + init_timeout(&to); + + /* Testing a waiter without FUTEX_32 flag */ + waitv->flags = FUTEX_PRIVATE_FLAG; + + res = futex_waitv(waitv, 1, 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 invalid flags"); + } +} + +static void test_unaligned_address(void) +{ + struct timespec to; + int res; + + init_waitv(); + init_timeout(&to); + + /* Testing a waiter with an unaligned address */ + waitv->uaddr = 1; + + res = futex_waitv(waitv, 1, 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 unligned address"); + } +} + +static void test_null_address(void) +{ + struct timespec to; + int res; + + init_waitv(); + init_timeout(&to); + + /* Testing a NULL address */ + waitv->uaddr = 0x00000000; + + res = futex_waitv(waitv, 1, 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 address is NULL"); + } +} + +static void test_null_waiters(void) +{ + struct timespec to; + int res; + + init_timeout(&to); + + /* Testing a NULL address for *waiters */ + res = futex_waitv(NULL, 1, 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 waiters are NULL"); + } +} + +static void test_invalid_clockid(void) +{ + struct timespec to; + int res; + + init_waitv(); + init_timeout(&to); + + /* Testing an invalid clockid */ + res = futex_waitv(waitv, 1, 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 void run(void) +{ + test_invalid_flags(); + test_unaligned_address(); + test_null_address(); + test_null_waiters(); + test_invalid_clockid(); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .min_kver = "5.16", + .bufs = + (struct tst_buffers[]){ + { &waitv, .size = sizeof(*waitv) }, + {}, + }, +}; diff --git a/testcases/kernel/syscalls/futex/futex_waitv02.c b/testcases/kernel/syscalls/futex/futex_waitv02.c new file mode 100644 index 000000000..d58de293f --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex_waitv02.c @@ -0,0 +1,111 @@ +// 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. + */ + +#define _GNU_SOURCE +#include +#include +#include "tst_test.h" +#include "lapi/futex.h" +#include "lapi/syscalls.h" +#include "futex2test.h" +#include "tst_safe_pthread.h" +#include "tst_safe_clocks.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_res(TINFO, "Testing variant: %s", tv.desc); + futex_supported_by_kernel(tv.fntype); + + tst_syscall(__NR_gettid); + + if (tst_parse_int(str_numfutex, &numfutex, 1, FUTEX_WAITV_MAX)) + tst_brk(TBROK, "Invalid number of futexes '%s'", str_numfutex); + + futexes = tst_alloc(sizeof(uint32_t) * numfutex); + memset(futexes, 0, numfutex); + + waitv = tst_alloc(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 *threaded(void *arg) +{ + struct futex_test_variants tv; + int ret, tid = *(int *)arg; + + tv = futex_variants(); + TST_THREAD_STATE_WAIT(tid, '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, tid; + pthread_t t; + + tid = tst_syscall(__NR_gettid); + + SAFE_PTHREAD_CREATE(&t, NULL, threaded, (void *)&tid); + + /* setting absolute timeout for futex2 */ + SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &to); + to.tv_sec++; + + ret = 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, + .min_kver = "5.16", + .bufs = + (struct tst_buffers[]){ + { &waitv, .size = sizeof(*waitv) }, + { &futexes, .size = sizeof(*futexes) }, + {}, + }, + .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..4f3b83ff1 --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex_waitv03.c @@ -0,0 +1,122 @@ +// 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. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include "tst_test.h" +#include "lapi/futex.h" +#include "lapi/syscalls.h" +#include "futex2test.h" +#include "tst_safe_pthread.h" +#include "tst_safe_clocks.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_res(TINFO, "Testing variant: %s", tv.desc); + futex_supported_by_kernel(tv.fntype); + + tst_syscall(__NR_gettid); + + if (tst_parse_int(str_numfutex, &numfutex, 1, FUTEX_WAITV_MAX)) + tst_brk(TBROK, "Invalid number of futexes '%s'", str_numfutex); + + waitv = tst_alloc(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); +} + +static void *threaded(void *arg) +{ + struct futex_test_variants tv; + int ret, tid = *(int *)arg; + + tv = futex_variants(); + TST_THREAD_STATE_WAIT(tid, '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, tid; + pthread_t t; + + tid = tst_syscall(__NR_gettid); + + SAFE_PTHREAD_CREATE(&t, NULL, threaded, (void *)&tid); + + /* setting absolute timeout for futex2 */ + SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &to); + to.tv_sec++; + + ret = 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", + .bufs = + (struct tst_buffers[]){ + { &waitv, .size = sizeof(*waitv) }, + {}, + }, + .options = + (struct tst_option[]){ + { "n:", &str_numfutex, "Number of futex (default 30)" }, + {}, + }, +}; diff --git a/testcases/kernel/syscalls/futex/futextest.h b/testcases/kernel/syscalls/futex/futextest.h index 3f2f36fef..cd925e686 100644 --- a/testcases/kernel/syscalls/futex/futextest.h +++ b/testcases/kernel/syscalls/futex/futextest.h @@ -16,52 +16,11 @@ #include #include #include -#include #include "lapi/futex.h" #include "tst_timer.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 +33,21 @@ struct futex_test_variants { char *desc; }; +static inline struct futex_test_variants futex_variants(void) +{ + struct futex_test_variants 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 + }; + + return variants[tst_variant]; +} + static inline void futex_supported_by_kernel(enum futex_fn_type fntype) { if (fntype != FUTEX_FN_FUTEX64) @@ -318,4 +292,4 @@ futex_set(futex_t *uaddr, u_int32_t newval) return newval; } -#endif +#endif /* _FUTEXTEST_H */