[LTP] [PATCH] syscalls/membarrier: Add membarrier() initial test
Jan Stancek
jstancek@redhat.com
Mon Oct 1 10:47:59 CEST 2018
Hi,
----- Original Message -----
> Fixes: #265
> +/*
> + * Basic tests for membarrier(2) syscall. Tests bellow are responsible for
> + * testing the membarrier(2) interface only, without checking if the barrier
> was
> + * successful or not.
> + *
> + * There are 11 test cases:
> + *
> + * 00) invalid cmd:
> + * - enabled by default
> + * - should always fail with EINVAL
> + * 01) invalid flags:
> + * - enabled by default
> + * - should always fail with EINVAL
> + * ----
> + * 02) global barrier:
> + * - ALWAYS enabled by CMD_QUERY
> + * - should always succeed
> + * ----
> + * commit 22e4ebb975 (v4.14-rc1) added following feature:
> + *
> + * 03) private expedited barrier with no registrations:
> + * - should fail with errno=EPERM due to no registrations
> + * - or be skipped if unsupported by running kernel
> + * 04) register private expedited
> + * - should succeed when supported by running kernel
> + * - or fail with errno=EINVAL if unsupported and forced
> + * 05) private expedited barrier with registration
> + * - should succeed due to existing registration (case 04)
> + * - or fail with errno=EINVAL if unsupported and forced
> + * - NOTE: if unsupported, and forced, on < 4.10, errno is EINVAL
> + * ----
> + * commit 70216e18e5 (v4.16-rc1) added following feature:
> + *
> + * 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
> + * 07) register private expedited sync core
> + * - should succeed when supported by running kernel
> + * - or fail with errno=EINVAL if unsupported and forced
> + * 08) private expedited sync core barrier with registration
> + * - should succeed due to existing registration (case 07)
> + * - or fail with errno=EINVAL if unsupported and forced
> + * ----
> + * commit c5f58bd58f4 (v4.16-rc1) added following feature:
> + *
> + * 09) global expedited barrier with no registrations
> + * - should never fail due to no registrations
> + * - or be skipped if unsupported by running kernel
> + * 10) register global expedited
> + * - should succeed when supported by running kernel
> + * - or fail with errno=EINVAL if unsupported and forced
> + * 11) global expedited barrier with registration
> + * - should succeed due to existing registration (case 10) or not
> + * - or fail with errno=EINVAL if unsupported and forced
I'd move these comments to test_case array. Because your cases
depend on each other, it'd be good to have description there.
> + * ----
> + * OBSERVATION:
> + *
> + * Linux kernel does not provide a way to unregister (mm->membarrier_state)
This breaks -i parameter, maybe fork a child?
> the
> + * process intent of being affected by the membarrier(2) call.
> + */
> +
> +#include "config.h"
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/wait.h>
> +#include <linux/membarrier.h>
Including linux headers directly is discouraged.
This breaks compilation on older distros:
membarrier01.c:72:30: error: linux/membarrier.h: No such file or directory
So we either need lapi header or configure check.
> +#include <syscall.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <signal.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include "tst_test.h"
<snip>
> static int sys_membarrier(int cmd, int flags)
> {
> return syscall(__NR_membarrier, cmd, flags);
> }
Needs syscall define in lapi/syscalls:
membarrier01.c:146: error: ‘__NR_membarrier’ undeclared (first use in this function)
> +
> +struct test_case tc[] = {
> + {
> + /* case 00 */
> + .testname = "cmd_fail\0",
string literals already contain null terminating character
> + .command = -1,
> + .exp_ret = -1,
> + .exp_errno = EINVAL,
> + .enabled = 1,
> + },
> + {
> + /* case 01 */
> + .testname = "cmd_flags_fail\0",
> + .command = MEMBARRIER_CMD_QUERY,
> + .flags = 1,
> + .exp_ret = -1,
> + .exp_errno = EINVAL,
> + .enabled = 1,
> + },
> + {
> + /* case 02 */
> + .testname = "cmd_global_success\0",
> + .command = MEMBARRIER_CMD_GLOBAL,
> + .flags = 0,
> + .exp_ret = 0,
> + .always = 1,
> + },
> + {
> + /* case 03 */
> + .testname = "cmd_private_expedited_fail\0",
> + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED,
> + .flags = 0,
> + .exp_ret = -1,
> + .exp_errno = EPERM,
> + },
> + {
> + /* case 04 */
> + .testname = "cmd_private_expedited_register_success\0",
> + .command = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
> + .flags = 0,
> + .exp_ret = 0,
> + .force = 1,
> + .force_exp_errno = EINVAL,
> + },
> + {
> + /* case 05 */
> + .testname = "cmd_private_expedited_success\0",
> + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED,
> + .flags = 0,
> + .exp_ret = 0,
> + .force = 1,
> + .force_exp_errno = EINVAL,
> + },
> + {
> + /* case 06 */
> + .testname = "cmd_private_expedited_sync_core_fail\0",
> + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
> + .flags = 0,
> + .exp_ret = -1,
> + .exp_errno = EPERM,
> + },
> + {
> + /* case 07 */
> + .testname = "cmd_private_expedited_sync_core_register_success\0",
> + .command = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
> + .flags = 0,
> + .exp_ret = 0,
> + .force = 1,
> + .force_exp_errno = EINVAL,
> + },
> + {
> + /* case 08 */
> + .testname = "cmd_private_expedited_sync_core_success\0",
> + .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
> + .flags = 0,
> + .exp_ret = 0,
> + .force = 1,
> + .force_exp_errno = EINVAL,
> + },
> + {
> + /* case 09 */
> + .testname = "cmd_global_expedited_success\0",
> + .command = MEMBARRIER_CMD_GLOBAL_EXPEDITED,
> + .flags = 0,
> + .exp_ret = 0,
> + },
> + {
> + /* case 10 */
> + .testname = "cmd_global_expedited_register_success\0",
> + .command = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED,
> + .flags = 0,
> + .exp_ret = 0,
> + .force = 1,
> + .force_exp_errno = EINVAL,
> + },
> + {
> + /* case 11 */
> + .testname = "cmd_global_expedited_success\0",
> + .command = MEMBARRIER_CMD_GLOBAL_EXPEDITED,
> + .flags = 0,
> + .exp_ret = 0,
> + .force = 1,
> + .force_exp_errno = EINVAL,
> + },
> +};
Same as for membarrier header applies to commands:
We either need configure check or lapi header to not break
LTP build on older distros.
> +
> +static void verify_membarrier(unsigned int i)
> +{
> + /* skips tests depending on supportability */
> +
> + if (tc[i].enabled != 1 && tc[i].force != 1) {
> + if (tc[i].always == 0)
> + skipped(tc[i]);
> +
> + skipped_fail(tc[i]);
> + }
> +
> + TEST(sys_membarrier(tc[i].command, tc[i].flags));
> +
> + /* cmd passes */
> +
> + if (tc[i].exp_ret == TST_RET) {
> +
> + if (TST_RET >= 0)
> + passed_ok(tc[i]);
> + else {
> + if (tc[i].enabled == 1 && tc[i].force != 1) {
> + if (tc[i].exp_errno != TST_ERR)
> + failed_not_ok(tc[i], TST_RET, TST_ERR);
> + else
> + failed_ok(tc[i]);
> + } else {
> + if (tc[i].force_exp_errno != TST_ERR)
> + failed_not_ok(tc[i], TST_RET, TST_ERR);
> + else
> + failed_ok_unsupported(tc[i]);
> + }
> + }
> +
> + /* cmd fails */
> +
> + } else {
> + if (tc[i].enabled == 1 && tc[i].force != 1) {
> + if (TST_RET >= 0)
> + passed_unexpectedly(tc[i]);
> + else
> + failed_unexpectedly(tc[i], TST_RET, TST_ERR);
> + } else {
> + if (tc[i].force_exp_errno == TST_ERR)
> + failed_ok_unsupported(tc[i]);
> + else
> + failed_not_ok(tc[i], TST_RET, TST_ERR);
> + }
> + }
> +}
> +
> +static void setup(void)
> +{
> + size_t i;
> + int ret;
> +
> + ret = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
> + if (ret < 0) {
> + if (errno == ENOSYS)
> + tst_brk(TCONF, "sys_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;
> + }
> +}
> +
> +static struct tst_test test = {
> + .setup = setup,
> + .test = verify_membarrier,
> + .tcnt = ARRAY_SIZE(tc),
> +};
Presumably, this syscall won't see many backports to older trees,
so I'd add minimum supported kernel version here.
Regards,
Jan
More information about the ltp
mailing list