From patchwork Fri Oct 5 20:39:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael David Tinoco X-Patchwork-Id: 148297 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp892585lji; Fri, 5 Oct 2018 13:39:25 -0700 (PDT) X-Google-Smtp-Source: ACcGV63iO8tluvMcD9ijPjh3X4I6lkmaJiAd3eChK5KzKHhpOrmE/ELSfXyF1tK+Ui5Nc7A3qe4D X-Received: by 2002:a5d:5088:: with SMTP id a8-v6mr3865862wrt.128.1538771965317; Fri, 05 Oct 2018 13:39:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538771965; cv=none; d=google.com; s=arc-20160816; b=pMvmYTq4R83587QAzOLIq33z+Q8cwVXAPr2SROKn3Jf42NLnbSpDA/LEfaQZaaxFW3 mLBrmNO9JTvmcxkSlOUImsEPG3E91toaEAuLShLi2uOpghKS+ldrp6sABOTUm6Q15k51 Vna3gmb82uMWA4u8xLEnYgHL93nbMXGDZ/rfPlZ5qybJ8hQGqyvmVQzlex3YtqinC0Gn 0EHURQamK60ReZmNwlRijUE896WTz/YGLadOV2DeBbjxItAtBe0d+sG0b1tXG2gd2+PK 4s+npVoAvGqTZlYvpcVfbFPlz+M5XwMKJ6YkBVfZoIqIROfwcFTjGexJ7lomKH5Gm4Kh KXhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :cc:mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:delivered-to; bh=Jfn5AakKtgMHD56AtKor30ZUhU1GWdkbt0SQeC7Md8I=; b=0Wd8XEPT26iazaRYmDrztkrA2ILPYANJ+/aCzGi/ijgMqJyW8ZqSJW8LjWzAE0cQ4j 2kh6T9eDF5ltgk8j+Yl7/ZDsHB8OXsl+pFs1omM2FefYPsEHKLYDQt33DcGAcro2VOIf 2R/9kSp59JrDLCMw1YX/uUS/A6E37yv2yiIYybVEr0H4pq+BxQYNE7wEYgko/NBk4EUj n6SZr6ZxUtItFk8yUaUJJ1QVJFnbs2BP1zaUM0B1pf8hObGohVjLtAnWsj2xRb6BEj/6 4GFLgq33xJiExYmEg9QbtLcm5o3TxoMW6CRCHhmKcBLYVBo0I+CVh84NzAxal1XONzxm AtjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=biB1ULLt; spf=pass (google.com: domain of ltp-bounces+patch=linaro.org@lists.linux.it designates 213.254.12.146 as permitted sender) smtp.mailfrom="ltp-bounces+patch=linaro.org@lists.linux.it"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from picard.linux.it (picard.linux.it. [213.254.12.146]) by mx.google.com with ESMTPS id h14si6917086wrx.122.2018.10.05.13.39.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 13:39:25 -0700 (PDT) Received-SPF: pass (google.com: domain of ltp-bounces+patch=linaro.org@lists.linux.it designates 213.254.12.146 as permitted sender) client-ip=213.254.12.146; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=biB1ULLt; spf=pass (google.com: domain of ltp-bounces+patch=linaro.org@lists.linux.it designates 213.254.12.146 as permitted sender) smtp.mailfrom="ltp-bounces+patch=linaro.org@lists.linux.it"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id D9BD13E77CF for ; Fri, 5 Oct 2018 22:39:24 +0200 (CEST) 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 [IPv6:2001:4b78:1:20::7]) by picard.linux.it (Postfix) with ESMTP id 8EE133E7141 for ; Fri, 5 Oct 2018 22:39:20 +0200 (CEST) Received: from mail-qk1-x741.google.com (mail-qk1-x741.google.com [IPv6:2607:f8b0:4864:20::741]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-7.smtp.seeweb.it (Postfix) with ESMTPS id B175D200744 for ; Fri, 5 Oct 2018 22:39:16 +0200 (CEST) Received: by mail-qk1-x741.google.com with SMTP id a13-v6so4130056qkc.7 for ; Fri, 05 Oct 2018 13:39:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kHfqu9KCLSRX/vDWvrO3T8GUmzlWxBSmcKcrs+NOmW4=; b=biB1ULLt6KUns+khOUoGCUeBMSIob/r+HDLMm6YMKef/St9Xcu71v28+MueOEpAgwT RpjPOWROm0bG0KYVN8Xk9XailojaVJAa2NP301WWGXPxB7HC0IWdIT21VAlGyNQeaNhq Z8X8bVTgHQSDM84F8YFCumAOWsP9FHH0pqhyo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kHfqu9KCLSRX/vDWvrO3T8GUmzlWxBSmcKcrs+NOmW4=; b=uZc8qRTD1K7NLTj8XgPZl6crdWb4FVSmvAA18a2cYLfkH09gOCj5CKROE3K8312O3M SgGTRIJbhl1fLTTJ4Htf49uqQ8PjGU+GC+HtIf2mRCz2IxggE5lPoHcaTsZcYjUdObH4 Dn/FxCcktkyNBM51N1/80pTuDQCVIAzHZTlM+iCMcu0Q/leF60eXQRvRGo7ga2zTOm9m 1Xl1OHSHgQOir4eg2F0XyjTl1jCV11lR4MEgb+F6RQLJCNQPqzhAMB9TBdE4EkxPa5Df xGlkVkGEWra7g9gDhxdVQYL/l70qWq1ZK+hWrZTgvfPd99eZilc0nia58FQ5WzTZDjca xczg== X-Gm-Message-State: ABuFfogjv7jDzVZ+oGj13vOmLR4i+MugU+mKkR5dJkQGESxoir5zJBt6 ZIdKqSunKjuaLhEBdDzGxaicNI5mYZo= X-Received: by 2002:a37:4c09:: with SMTP id z9-v6mr10856309qka.302.1538771954934; Fri, 05 Oct 2018 13:39:14 -0700 (PDT) Received: from workstation.celeiro.br ([138.204.25.12]) by smtp.gmail.com with ESMTPSA id j32-v6sm5228898qtc.59.2018.10.05.13.39.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Oct 2018 13:39:14 -0700 (PDT) From: Rafael David Tinoco To: ltp@lists.linux.it Date: Fri, 5 Oct 2018 17:39:10 -0300 Message-Id: <20181005203910.23360-1-rafael.tinoco@linaro.org> X-Mailer: git-send-email 2.19.0.rc2 In-Reply-To: <243767154.55279006.1538383679362.JavaMail.zimbra@redhat.com> References: <243767154.55279006.1538383679362.JavaMail.zimbra@redhat.com> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.99.2 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,SPF_PASS autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-7.smtp.seeweb.it Cc: rafael.tinoco@linaro.org Subject: [LTP] [PATCH v2] syscalls/membarrier: Add membarrier() initial test X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+patch=linaro.org@lists.linux.it Sender: "ltp" Fixes: #265 Initial test for membarrier() syscall. It tests all existing membarrier "commands" (or features), including the need (or not) for previous registration for the call to work. Some features did not exist in older kernels and that is covered by skipping some calls, flagging test as skipped & okay, and forcing others, making sure that return codes and errno are set right in those cases. Tests are done in a child process due to inexistent kernel interface to "unregister" the process from being affected by membarrier() call. Signed-off-by: Rafael David Tinoco --- configure.ac | 1 + include/lapi/syscalls/aarch64.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/powerpc.in | 1 + include/lapi/syscalls/powerpc64.in | 1 + include/lapi/syscalls/s390.in | 1 + include/lapi/syscalls/s390x.in | 1 + include/lapi/syscalls/sparc.in | 1 + include/lapi/syscalls/sparc64.in | 1 + include/lapi/syscalls/x86_64.in | 1 + runtest/syscalls | 2 + .../kernel/syscalls/membarrier/.gitignore | 1 + testcases/kernel/syscalls/membarrier/Makefile | 8 + .../kernel/syscalls/membarrier/membarrier01.c | 411 ++++++++++++++++++ 17 files changed, 435 insertions(+) create mode 100644 testcases/kernel/syscalls/membarrier/.gitignore create mode 100644 testcases/kernel/syscalls/membarrier/Makefile create mode 100644 testcases/kernel/syscalls/membarrier/membarrier01.c diff --git a/configure.ac b/configure.ac index e1ecb32a7..98425f997 100644 --- a/configure.ac +++ b/configure.ac @@ -45,6 +45,7 @@ AC_CHECK_HEADERS([ \ linux/mempolicy.h \ linux/module.h \ linux/netlink.h \ + linux/membarrier.h \ mm.h \ netinet/sctp.h \ pthread.h \ diff --git a/include/lapi/syscalls/aarch64.in b/include/lapi/syscalls/aarch64.in index 9ac7f997b..f6b0b2949 100644 --- a/include/lapi/syscalls/aarch64.in +++ b/include/lapi/syscalls/aarch64.in @@ -256,6 +256,7 @@ sendmmsg 269 kcmp 272 getrandom 278 memfd_create 279 +membarrier 283 mlock2 284 copy_file_range 285 _sysctl 1078 diff --git a/include/lapi/syscalls/arm.in b/include/lapi/syscalls/arm.in index 0a7f98ac5..d8897b180 100644 --- a/include/lapi/syscalls/arm.in +++ b/include/lapi/syscalls/arm.in @@ -341,6 +341,7 @@ renameat2 (__NR_SYSCALL_BASE+382) getrandom (__NR_SYSCALL_BASE+384) memfd_create (__NR_SYSCALL_BASE+385) execveat (__NR_SYSCALL_BASE+387) +membarrier (__NR_SYSCALL_BASE+389) mlock2 (__NR_SYSCALL_BASE+390) copy_file_range (__NR_SYSCALL_BASE+391) statx (__NR_SYSCALL_BASE+397) diff --git a/include/lapi/syscalls/hppa.in b/include/lapi/syscalls/hppa.in index 3db978069..e961dabe3 100644 --- a/include/lapi/syscalls/hppa.in +++ b/include/lapi/syscalls/hppa.in @@ -17,5 +17,6 @@ splice 291 tee 293 vmsplice 294 memfd_create 340 +membarrier 343 mlock2 345 copy_file_range 346 diff --git a/include/lapi/syscalls/i386.in b/include/lapi/syscalls/i386.in index a000564d2..f2a4ae845 100644 --- a/include/lapi/syscalls/i386.in +++ b/include/lapi/syscalls/i386.in @@ -343,4 +343,5 @@ memfd_create 356 execveat 358 mlock2 376 copy_file_range 377 +membarrier 375 statx 383 diff --git a/include/lapi/syscalls/ia64.in b/include/lapi/syscalls/ia64.in index 278819387..02f86d7d3 100644 --- a/include/lapi/syscalls/ia64.in +++ b/include/lapi/syscalls/ia64.in @@ -296,5 +296,6 @@ prlimit64 1325 renameat2 1338 getrandom 1339 memfd_create 1340 +membarrier 1344 mlock2 1346 copy_file_range 1347 diff --git a/include/lapi/syscalls/powerpc.in b/include/lapi/syscalls/powerpc.in index c0b4226eb..e8e5acb3b 100644 --- a/include/lapi/syscalls/powerpc.in +++ b/include/lapi/syscalls/powerpc.in @@ -347,6 +347,7 @@ sched_getattr 356 renameat2 357 getrandom 359 memfd_create 360 +membarrier 365 mlock2 378 copy_file_range 379 statx 383 diff --git a/include/lapi/syscalls/powerpc64.in b/include/lapi/syscalls/powerpc64.in index c0b4226eb..e8e5acb3b 100644 --- a/include/lapi/syscalls/powerpc64.in +++ b/include/lapi/syscalls/powerpc64.in @@ -347,6 +347,7 @@ sched_getattr 356 renameat2 357 getrandom 359 memfd_create 360 +membarrier 365 mlock2 378 copy_file_range 379 statx 383 diff --git a/include/lapi/syscalls/s390.in b/include/lapi/syscalls/s390.in index 47a04de27..8f0ba9278 100644 --- a/include/lapi/syscalls/s390.in +++ b/include/lapi/syscalls/s390.in @@ -331,6 +331,7 @@ sched_getattr 346 renameat2 347 getrandom 349 memfd_create 350 +membarrier 356 execveat 354 mlock2 374 copy_file_range 375 diff --git a/include/lapi/syscalls/s390x.in b/include/lapi/syscalls/s390x.in index 83732ffbe..4fe69f41e 100644 --- a/include/lapi/syscalls/s390x.in +++ b/include/lapi/syscalls/s390x.in @@ -331,5 +331,6 @@ sched_getattr 346 renameat2 347 getrandom 349 memfd_create 350 +membarrier 356 mlock2 374 copy_file_range 375 diff --git a/include/lapi/syscalls/sparc.in b/include/lapi/syscalls/sparc.in index 2b06a797a..5f061b244 100644 --- a/include/lapi/syscalls/sparc.in +++ b/include/lapi/syscalls/sparc.in @@ -336,5 +336,6 @@ kcmp 341 renameat2 345 getrandom 347 memfd_create 348 +membarrier 350 mlock2 356 copy_file_range 357 diff --git a/include/lapi/syscalls/sparc64.in b/include/lapi/syscalls/sparc64.in index 8c8a86673..cb821e892 100644 --- a/include/lapi/syscalls/sparc64.in +++ b/include/lapi/syscalls/sparc64.in @@ -312,5 +312,6 @@ kcmp 341 renameat2 345 getrandom 347 memfd_create 348 +membarrier 350 mlock2 356 copy_file_range 357 diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in index 4ce8477de..9a1832114 100644 --- a/include/lapi/syscalls/x86_64.in +++ b/include/lapi/syscalls/x86_64.in @@ -308,6 +308,7 @@ renameat2 316 getrandom 318 memfd_create 319 execveat 322 +membarrier 324 mlock2 325 copy_file_range 326 statx 332 diff --git a/runtest/syscalls b/runtest/syscalls index 0d0be7713..19be14098 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1504,3 +1504,5 @@ statx02 statx02 statx03 statx03 statx04 statx04 statx05 statx05 + +membarrier01 membarrier01 diff --git a/testcases/kernel/syscalls/membarrier/.gitignore b/testcases/kernel/syscalls/membarrier/.gitignore new file mode 100644 index 000000000..eec8058b9 --- /dev/null +++ b/testcases/kernel/syscalls/membarrier/.gitignore @@ -0,0 +1 @@ +/membarrier01 diff --git a/testcases/kernel/syscalls/membarrier/Makefile b/testcases/kernel/syscalls/membarrier/Makefile new file mode 100644 index 000000000..f71e4fc25 --- /dev/null +++ b/testcases/kernel/syscalls/membarrier/Makefile @@ -0,0 +1,8 @@ +# Copyright (c) 2018 - Linaro Limited. All rights reserved. +# SPDX-License-Identifier: GPL-2.0-or-later + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk + +include $(top_srcdir)/include/mk/generic_leaf_target.mk \ No newline at end of file diff --git a/testcases/kernel/syscalls/membarrier/membarrier01.c b/testcases/kernel/syscalls/membarrier/membarrier01.c new file mode 100644 index 000000000..061e9ed7e --- /dev/null +++ b/testcases/kernel/syscalls/membarrier/membarrier01.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2018 Linaro Limited. All rights reserved. + * Author: Rafael David Tinoco + */ +/* + * Basic tests for membarrier(2) syscall. Tests below are responsible for + * testing the membarrier(2) interface only, without checking if the barrier + * was successful or not. Check test_case structure for each test description. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LINUX_MEMBARRIER_H +# include +#endif +#include "tst_test.h" +#include "lapi/syscalls.h" + +#ifdef HAVE_SYS_XATTR_H + +struct test_case { + char testname[80]; + int command; /* membarrier cmd */ + int needregister; /* membarrier cmd needs register cmd */ + int flags; /* flags for given membarrier cmd */ + long exp_ret; /* expected return code for given cmd */ + int exp_errno; /* expected errno for given cmd failure */ + int enabled; /* enabled, despite results from CMD_QUERY */ + int always; /* CMD_QUERY should always enable this test */ + int force; /* force if CMD_QUERY reports not enabled */ + int force_exp_errno; /* expected errno after forced cmd */ +}; + +struct test_case tc[] = { + { + /* + * case 00) invalid cmd + * - enabled by default + * - should always fail with EINVAL + */ + .testname = "cmd_fail", + .command = -1, + .exp_ret = -1, + .exp_errno = EINVAL, + .enabled = 1, + }, + { + /* + * case 01) invalid flags + * - enabled by default + * - should always fail with EINVAL + */ + .testname = "cmd_flags_fail", + .command = MEMBARRIER_CMD_QUERY, + .flags = 1, + .exp_ret = -1, + .exp_errno = EINVAL, + .enabled = 1, + }, + { + /* + * case 02) global barrier + * - should ALWAYS be enabled by CMD_QUERY + * - should always succeed + */ + .testname = "cmd_global_success", + .command = MEMBARRIER_CMD_GLOBAL, + .flags = 0, + .exp_ret = 0, + .always = 1, + }, + /* + * commit 22e4ebb975 (v4.14-rc1) added cases 03, 04 and 05 features: + */ + { + /* + * case 03) private expedited barrier with no registrations + * - should fail with errno=EPERM due to no registrations + * - or be skipped if unsupported by running kernel + */ + .testname = "cmd_private_expedited_fail", + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED, + .flags = 0, + .exp_ret = -1, + .exp_errno = EPERM, + }, + { + /* + * case 04) register private expedited + * - should succeed when supported by running kernel + * - or fail with errno=EINVAL if unsupported and forced + */ + .testname = "cmd_private_expedited_register_success", + .command = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, + .flags = 0, + .exp_ret = 0, + .force = 1, + .force_exp_errno = EINVAL, + }, + { + /* + * case 05) private expedited barrier with registration + * - should succeed due to existing registration + * - or fail with errno=EINVAL if unsupported and forced + * - NOTE: (a) if unsupported, and forced, < 4.16 , errno is EINVAL + * - (b) if unsupported, and forced, >= 4.16, errno is EPERM + */ + .testname = "cmd_private_expedited_success", + .needregister = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED, + .flags = 0, + .exp_ret = 0, + .force = 1, + .force_exp_errno = EPERM, + }, + /* + * commit 70216e18e5 (v4.16-rc1) added cases 06, 07 and 08 features: + */ + { + /* + * case 06) private expedited sync core barrier with no registrations + * - should fail with errno=EPERM due to no registrations + * - or be skipped if unsupported by running kernel + */ + .testname = "cmd_private_expedited_sync_core_fail", + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, + .flags = 0, + .exp_ret = -1, + .exp_errno = EPERM, + }, + { + /* + * case 07) register private expedited sync core + * - should succeed when supported by running kernel + * - or fail with errno=EINVAL if unsupported and forced + */ + .testname = "cmd_private_expedited_sync_core_register_success", + .command = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, + .flags = 0, + .exp_ret = 0, + .force = 1, + .force_exp_errno = EINVAL, + }, + { + /* + * case 08) private expedited sync core barrier with registration + * - should succeed due to existing registration + * - or fail with errno=EINVAL if unsupported and forced + */ + .testname = "cmd_private_expedited_sync_core_success", + .needregister = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, + .flags = 0, + .exp_ret = 0, + .force = 1, + .force_exp_errno = EINVAL, + }, + /* + * commit c5f58bd58f4 (v4.16-rc1) added cases 09, 10 and 11 features: + */ + { + /* + * case 09) global expedited barrier with no registrations + * - should never fail due to no registrations + * - or be skipped if unsupported by running kernel + */ + .testname = "cmd_global_expedited_success", + .command = MEMBARRIER_CMD_GLOBAL_EXPEDITED, + .flags = 0, + .exp_ret = 0, + }, + { + /* + * case 10) register global expedited + * - should succeed when supported by running kernel + * - or fail with errno=EINVAL if unsupported and forced + */ + .testname = "cmd_global_expedited_register_success", + .command = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, + .flags = 0, + .exp_ret = 0, + .force = 1, + .force_exp_errno = EINVAL, + }, + { + /* + * case 11) global expedited barrier with registration + * - should also succeed with registrations + * - or fail with errno=EINVAL if unsupported and forced + */ + .testname = "cmd_global_expedited_success", + .needregister = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, + .command = MEMBARRIER_CMD_GLOBAL_EXPEDITED, + .flags = 0, + .exp_ret = 0, + .force = 1, + .force_exp_errno = EINVAL, + }, +}; + +#define passed_ok(_test) \ + do { \ + tst_res(TPASS, "membarrier(2): %s passed", _test.testname); \ + return; \ + } while (0) + +#define passed_unexpec(_test) \ + do { \ + tst_res(TFAIL, "membarrier(2): %s passed unexpectedly. " \ + "ret = %ld with errno %d were expected. (force: %d)", \ + _test.testname, _test.exp_ret, _test.exp_errno, \ + _test.force); \ + return; \ + } while (0) + +#define failed_ok(_test) \ + do { \ + tst_res(TPASS, "membarrier(2): %s failed as expected", \ + _test.testname); \ + return; \ + } while (0) + +#define failed_ok_unsupported(_test) \ + do { \ + tst_res(TPASS, "membarrier(2): %s failed as expected " \ + "(unsupported)", _test.testname); \ + return; \ + } while (0) + +#define failed_not_ok(_test, _gotret, _goterr) \ + do { \ + tst_res(TFAIL, "membarrier(2): %s failed. " \ + "ret = %ld when expected was %ld. " \ + "errno = %d when expected was %d. (force: %d)", \ + _test.testname, _gotret, _test.exp_ret, _goterr, \ + _test.exp_errno, _test.force); \ + return; \ + } while (0) + +#define failed_unexpec(_test, _gotret, _goterr) \ + do { \ + tst_res(TFAIL, "membarrier(2): %s failed unexpectedly. " \ + "Got ret = %ld with errno %d. (force: %d)", \ + _test.testname, _gotret, _goterr, _test.force); \ + return; \ + } while (0) + +#define skipped(_test) \ + do { \ + tst_res(TPASS, "membarrier(2): %s skipped (unsupported)", \ + _test.testname); \ + return; \ + } while (0) + +#define skipped_fail(_test) \ + do { \ + tst_res(TFAIL, "membarrier(2): %s reported as not supported", \ + _test.testname); \ + return; \ + } while (0) + +static int sys_membarrier(int cmd, int flags) +{ + return tst_syscall(__NR_membarrier, cmd, flags); +} + +static void verify_membarrier(unsigned int i) +{ + int ret; + + /* not enabled and not enforced: test is skipped */ + + if (!tc[i].enabled && !tc[i].force) { + + if (tc[i].always == 0) + skipped(tc[i]); + + skipped_fail(tc[i]); + } + + /* iterations: registration needed for some cases */ + + if (tc[i].needregister && tc[i].enabled) { + ret = sys_membarrier(tc[i].needregister, 0); + if (ret < 0) { + tst_brk(TBROK, "membarrier(2): %s could not register", + tc[i].testname); + } + } + + TEST(sys_membarrier(tc[i].command, tc[i].flags)); + + /* enabled and not enforced: regular expected results only */ + + if (tc[i].enabled && !tc[i].force) { + + if (TST_RET >= 0 && tc[i].exp_ret == TST_RET) + passed_ok(tc[i]); + + if (TST_RET < 0) { + if (tc[i].exp_ret == TST_RET) + failed_ok(tc[i]); + else + failed_not_ok(tc[i], TST_RET, TST_ERR); + } + } + + /* not enabled and enforced: failure and expected errors */ + + if (!tc[i].enabled && tc[i].force) { + + if (TST_RET >= 0) + passed_unexpec(tc[i]); + + if (TST_RET < 0) { + if (tc[i].force_exp_errno == TST_ERR) + failed_ok_unsupported(tc[i]); + else + failed_unexpec(tc[i], TST_RET, TST_ERR); + } + } + + /* enabled and enforced: tricky */ + + if (tc[i].enabled && tc[i].force) { + + if (TST_RET >= 0) { + if (tc[i].exp_ret == TST_RET) + passed_ok(tc[i]); + else + passed_unexpec(tc[i]); + } + + if (TST_RET < 0) { + + if (tc[i].exp_ret == TST_RET) { + + if (tc[i].exp_errno == TST_ERR) + failed_ok(tc[i]); + else + failed_unexpec(tc[i], TST_RET, TST_ERR); + } + + /* unknown on force failure if enabled and forced */ + failed_unexpec(tc[i], TST_RET, TST_ERR); + } + } +} + +static void wrap_verify_membarrier(unsigned int i) +{ + pid_t pid; + + /* + * The Linux kernel does not provide a way to unregister the process + * (mm->membarrier_state) intent of being affected by the membarrier(2) + * system call, thus the need of having a wrapper to fork() a child. + */ + + pid = SAFE_FORK(); + + if (pid) + SAFE_WAITPID(pid, NULL, 0); + else + verify_membarrier(i); +} + +static void setup(void) +{ + size_t i; + int ret; + + ret = sys_membarrier(MEMBARRIER_CMD_QUERY, 0); + if (ret < 0) { + if (errno == ENOSYS) + tst_brk(TBROK, "membarrier(2): not supported"); + } + + for (i = 0; i < ARRAY_SIZE(tc); i++) { + if ((tc[i].command > 0) && (ret & tc[i].command)) + tc[i].enabled = 1; + } + + /* case 05: commit 70216e18e5 (v4.16-rc1) changed behavior */ + + if (tst_kvercmp(4, 16, 0) < 0 && tc[5].enabled == 0) + tc[5].force_exp_errno = EINVAL; +} + +static struct tst_test test = { + .setup = setup, + .test = wrap_verify_membarrier, + .tcnt = ARRAY_SIZE(tc), + .min_kver = "4.3.0", /* commit: 5b25b13ab0 (sys_membarrier(): ...) */ + .forks_child = 1, +}; + +#else /* HAVE_LINUX_MEMBARRIER_H */ +TST_TEST_TCONF(" does not exist"); +#endif