Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp5022221pxb; Mon, 15 Feb 2021 07:33:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJxaiKySswh75oaSJybr5gESYFWg5CvhaQnv9moi6BPQ6omaFmSdmywu/n3ArRD4tITeYUDk X-Received: by 2002:a17:906:2898:: with SMTP id o24mr15779533ejd.215.1613403207013; Mon, 15 Feb 2021 07:33:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613403207; cv=none; d=google.com; s=arc-20160816; b=TOCaBh3UCzbxxB9JVpuOrsr7DYpHsJkkj7hX7MRjTz7CsgwBxd6b+ZJmpu8U+BWXdr SeFuf+9NOcg6AWQOxZVlPOTN/oYfIMsPuvBlhajiCrMDGp7ax4r6TCyJ3b8ZxqtLYKUp bCgBY2OKvBX1OQC7thIm5k/jcFgkzQjj8ur/so/Gw2B8P/J+s/tDNIxv8NaF5gzOikzp L6wsOsJWESKmPy+YX8/ObXbGA8EbtTlHWNVang3uJ1Yw638nbKdS5wXa73Kxeak7KzTw /96agcw2zIbB+H2P28nmR635upwzYqsaIGjgUArTV+1rOOLuuYTcMSiidjQonubKWLX6 RyZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=C022/devU9zueVvHVAb2vb/BHpOzorFAbh86G19OLeY=; b=RBOAmzJ+Wkz/ACxAQ+sY38hKe+DPD3LwEV0OfwRzIVpL0ci5SMYaTQGz1wSXvysr0b 9RPUwIIJ5qZA4zx8DynsA5YYFtLgQuLJHgCX3AvxfPPoz5iOBF24tQa5M2tEhJB+97kq UbMcqdcG4bX/YYKKmtYnE3VFtZMihd2a9g58PTG9PyOPh/kGgA8Pws+03RkSSo0wOuuC v94nLSUPc2+r4APGduB4Jm7AFtaH6RnTILucSdIQvRDToq0jrvSbAdZkkZE00C/QKc5B h1KSYuDAk4w2dvPgzitfuieCMbU5s6lblVCxD12iHMO4O9/BRjVE8rPl4ABepy/DfqYz /yzA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a42si16415393edf.469.2021.02.15.07.33.04; Mon, 15 Feb 2021 07:33:27 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230030AbhBOPbe (ORCPT + 99 others); Mon, 15 Feb 2021 10:31:34 -0500 Received: from bhuna.collabora.co.uk ([46.235.227.227]:60310 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230396AbhBOP0U (ORCPT ); Mon, 15 Feb 2021 10:26:20 -0500 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: tonyk) with ESMTPSA id 73F3C1F44F2F From: =?UTF-8?q?Andr=C3=A9=20Almeida?= To: Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Darren Hart , linux-kernel@vger.kernel.org, Steven Rostedt , Sebastian Andrzej Siewior Cc: kernel@collabora.com, krisman@collabora.com, pgriffais@valvesoftware.com, z.figura12@gmail.com, joel@joelfernandes.org, malteskarupke@fastmail.fm, linux-api@vger.kernel.org, fweimer@redhat.com, libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, shuah@kernel.org, acme@kernel.org, corbet@lwn.net, =?UTF-8?q?Andr=C3=A9=20Almeida?= Subject: [RFC PATCH 11/13] selftests: futex2: Add requeue test Date: Mon, 15 Feb 2021 12:24:02 -0300 Message-Id: <20210215152404.250281-12-andrealmeid@collabora.com> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210215152404.250281-1-andrealmeid@collabora.com> References: <20210215152404.250281-1-andrealmeid@collabora.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add testing for futex_requeue(). The first test just requeue from one waiter to another one, and wake it. The second performs both wake and requeue, and we check return values to see if the operation woke/requeued the expected number of waiters. Signed-off-by: André Almeida --- .../selftests/futex/functional/.gitignore | 1 + .../selftests/futex/functional/Makefile | 3 +- .../futex/functional/futex2_requeue.c | 164 ++++++++++++++++++ .../selftests/futex/include/futex2test.h | 16 ++ 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/futex/functional/futex2_requeue.c diff --git a/tools/testing/selftests/futex/functional/.gitignore b/tools/testing/selftests/futex/functional/.gitignore index d0b8f637b786..af7557e821da 100644 --- a/tools/testing/selftests/futex/functional/.gitignore +++ b/tools/testing/selftests/futex/functional/.gitignore @@ -8,3 +8,4 @@ futex_wait_uninitialized_heap futex_wait_wouldblock futex2_wait futex2_waitv +futex2_requeue diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile index 09c08ccdeaf2..3ccb9ea58ddd 100644 --- a/tools/testing/selftests/futex/functional/Makefile +++ b/tools/testing/selftests/futex/functional/Makefile @@ -17,7 +17,8 @@ TEST_GEN_FILES := \ futex_wait_uninitialized_heap \ futex_wait_private_mapped_file \ futex2_wait \ - futex2_waitv + futex2_waitv \ + futex2_requeue TEST_PROGS := run.sh diff --git a/tools/testing/selftests/futex/functional/futex2_requeue.c b/tools/testing/selftests/futex/functional/futex2_requeue.c new file mode 100644 index 000000000000..1bc3704dc8c2 --- /dev/null +++ b/tools/testing/selftests/futex/functional/futex2_requeue.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/****************************************************************************** + * + * Copyright Collabora Ltd., 2021 + * + * DESCRIPTION + * Test requeue mechanism of futex2, using 32bit sized futexes. + * + * AUTHOR + * André Almeida + * + * HISTORY + * 2021-Feb-5: Initial version by André + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "futex2test.h" +#include "logging.h" + +#define TEST_NAME "futex2-wait" +#define timeout_ns 30000000 +#define WAKE_WAIT_US 10000 +volatile futex_t *f1; + +void usage(char *prog) +{ + printf("Usage: %s\n", prog); + printf(" -c Use color\n"); + printf(" -h Display this help message\n"); + printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n", + VQUIET, VCRITICAL, VINFO); +} + +void *waiterfn(void *arg) +{ + struct timespec64 to64; + + /* setting absolute timeout for futex2 */ + if (gettime64(CLOCK_MONOTONIC, &to64)) + error("gettime64 failed\n", errno); + + to64.tv_nsec += timeout_ns; + + if (to64.tv_nsec >= 1000000000) { + to64.tv_sec++; + to64.tv_nsec -= 1000000000; + } + + if (futex2_wait(f1, *f1, FUTEX_32, &to64)) + printf("waiter failed errno %d\n", errno); + + return NULL; +} + +int main(int argc, char *argv[]) +{ + pthread_t waiter[10]; + int res, ret = RET_PASS; + int c, i; + volatile futex_t _f1 = 0; + volatile futex_t f2 = 0; + struct futex_requeue r1, r2; + + f1 = &_f1; + + r1.flags = FUTEX_32; + r2.flags = FUTEX_32; + + r1.uaddr = f1; + r2.uaddr = &f2; + + while ((c = getopt(argc, argv, "cht:v:")) != -1) { + switch (c) { + case 'c': + log_color(1); + break; + case 'h': + usage(basename(argv[0])); + exit(0); + case 'v': + log_verbosity(atoi(optarg)); + break; + default: + usage(basename(argv[0])); + exit(1); + } + } + + ksft_print_header(); + ksft_set_plan(2); + ksft_print_msg("%s: Test FUTEX2_REQUEUE\n", + basename(argv[0])); + + /* + * Requeue a waiter from f1 to f2, and wake f2. + */ + if (pthread_create(&waiter[0], NULL, waiterfn, NULL)) + error("pthread_create failed\n", errno); + + usleep(WAKE_WAIT_US); + + res = futex2_requeue(&r1, &r2, 0, 1, 0, 0); + if (res != 1) { + ksft_test_result_fail("futex2_requeue private returned: %d %s\n", + res ? errno : res, + res ? strerror(errno) : ""); + ret = RET_FAIL; + } + + + info("Calling private futex2_wake on f2: %u @ %p with val=%u\n", f2, &f2, f2); + res = futex2_wake(&f2, 1, FUTEX_32); + if (res != 1) { + ksft_test_result_fail("futex2_requeue private returned: %d %s\n", + res ? errno : res, + res ? strerror(errno) : ""); + ret = RET_FAIL; + } else { + ksft_test_result_pass("futex2_requeue simple succeeds\n"); + } + + + /* + * Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7. + * At futex_wake, wake INT_MAX (should be exaclty 7). + */ + for (i = 0; i < 10; i++) { + if (pthread_create(&waiter[i], NULL, waiterfn, NULL)) + error("pthread_create failed\n", errno); + } + + usleep(WAKE_WAIT_US); + + res = futex2_requeue(&r1, &r2, 3, 7, 0, 0); + if (res != 10) { + ksft_test_result_fail("futex2_requeue private returned: %d %s\n", + res ? errno : res, + res ? strerror(errno) : ""); + ret = RET_FAIL; + } + + res = futex2_wake(&f2, INT_MAX, FUTEX_32); + if (res != 7) { + ksft_test_result_fail("futex2_requeue private returned: %d %s\n", + res ? errno : res, + res ? strerror(errno) : ""); + ret = RET_FAIL; + } else { + ksft_test_result_pass("futex2_requeue succeeds\n"); + } + + ksft_print_cnts(); + return ret; +} diff --git a/tools/testing/selftests/futex/include/futex2test.h b/tools/testing/selftests/futex/include/futex2test.h index 31979afc486f..e2635006b1a9 100644 --- a/tools/testing/selftests/futex/include/futex2test.h +++ b/tools/testing/selftests/futex/include/futex2test.h @@ -103,3 +103,19 @@ static inline int futex2_waitv(volatile struct futex_waitv *waiters, unsigned lo { return syscall(__NR_futex_waitv, waiters, nr_waiters, flags, timo); } + +/** + * futex2_requeue - Wake futexes at uaddr1 and requeue from uaddr1 to uaddr2 + * @uaddr1: Original address to wake and requeue from + * @uaddr2: Address to requeue to + * @nr_wake: Number of futexes to wake at uaddr1 before requeuing + * @nr_requeue: Number of futexes to requeue from uaddr1 to uaddr2 + * @cmpval: If (uaddr1->uaddr != cmpval), return immediatally + * @flgas: Operation flags + */ +static inline int futex2_requeue(struct futex_requeue *uaddr1, struct futex_requeue *uaddr2, + unsigned int nr_wake, unsigned int nr_requeue, + unsigned int cmpval, unsigned long flags) +{ + return syscall(__NR_futex_requeue, uaddr1, uaddr2, nr_wake, nr_requeue, cmpval, flags); +} -- 2.30.1