From caacdfd6e974f5b091bb39002bcd8391a8c72766 Mon Sep 17 00:00:00 2001 From: Michal Clapinski Date: Wed, 13 Sep 2023 18:42:58 +0200 Subject: [PATCH] zdtm: test MEMBARRIER_CMD_GLOBAL_EXPEDITED migration Check membarrier registration both ways: 1. By issuing membarrier commands and checking if they succeed. 2. By issuing MEMBARRIER_CMD_GET_REGISTRATIONS. The first way is needed for older kernels. The second way is needed to test MEMBARRIER_CMD_GLOBAL_EXPEDITED. --- test/zdtm/static/membarrier.c | 51 ++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/test/zdtm/static/membarrier.c b/test/zdtm/static/membarrier.c index a04b3603517..85d705ba7bc 100644 --- a/test/zdtm/static/membarrier.c +++ b/test/zdtm/static/membarrier.c @@ -8,14 +8,16 @@ const char *test_author = "Michał Mirosław "; /* * Define membarrier() CMDs to avoid depending on exact kernel header version. - * FIXME: use MEMBARRIER_CMD_GET_REGISTRATIONS if supported by kernel. */ +#define MEMBARRIER_CMD_GLOBAL_EXPEDITED (1 << 1) +#define MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED (1 << 2) #define MEMBARRIER_CMD_PRIVATE_EXPEDITED (1 << 3) #define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED (1 << 4) #define MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE (1 << 5) #define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE (1 << 6) #define MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ (1 << 7) #define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ (1 << 8) +#define MEMBARRIER_CMD_GET_REGISTRATIONS (1 << 9) static int membarrier(int cmd, unsigned int flags, int cpu_id) { @@ -27,9 +29,14 @@ static const struct { int register_cmd; int execute_cmd; } membarrier_cmds[] = { - { "", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, MEMBARRIER_CMD_PRIVATE_EXPEDITED }, - { "_SYNC_CORE", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE }, - { "_RSEQ", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ, MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ }, + { "GLOBAL_EXPEDITED", MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, + MEMBARRIER_CMD_GLOBAL_EXPEDITED }, + { "PRIVATE_EXPEDITED", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, + MEMBARRIER_CMD_PRIVATE_EXPEDITED }, + { "PRIVATE_EXPEDITED_SYNC_CORE", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, + MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE }, + { "PRIVATE_EXPEDITED_RSEQ", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ, + MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ }, }; static const int n_membarrier_cmds = sizeof(membarrier_cmds) / sizeof(*membarrier_cmds); @@ -49,10 +56,10 @@ static int register_membarriers(void) if (~barriers_supported & membarrier_cmds[i].register_cmd) continue; - barriers_registered |= membarrier_cmds[i].execute_cmd; + barriers_registered |= membarrier_cmds[i].register_cmd; if (membarrier(membarrier_cmds[i].register_cmd, 0, 0) < 0) { - pr_perror("membarrier(REGISTER_PRIVATE_EXPEDITED%s)", membarrier_cmds[i].name_suffix); + pr_perror("membarrier(REGISTER_%s)", membarrier_cmds[i].name_suffix); all_ok = false; } } @@ -71,15 +78,15 @@ static int register_membarriers(void) return barriers_registered; } -static bool check_membarriers(int barriers_registered) +static bool check_membarriers_compat(int barriers_registered) { bool all_ok = true; for (int i = 0; i < n_membarrier_cmds; ++i) { - if (~barriers_registered & membarrier_cmds[i].execute_cmd) + if (~barriers_registered & membarrier_cmds[i].register_cmd) continue; if (membarrier(membarrier_cmds[i].execute_cmd, 0, 0) < 0) { - pr_perror("membarrier(PRIVATE_EXPEDITED%s)", membarrier_cmds[i].name_suffix); + pr_perror("membarrier(%s)", membarrier_cmds[i].name_suffix); all_ok = false; } } @@ -90,6 +97,32 @@ static bool check_membarriers(int barriers_registered) return all_ok; } +static bool check_membarriers_get_registrations(int barriers_registered) +{ + int ret = membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS, 0, 0); + if (ret < 0) { + if (errno == EINVAL) { + test_msg("membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS) not supported by running kernel"); + return true; + } + fail("membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS)"); + return false; + } + if (ret != barriers_registered) { + fail("MEMBARRIER_CMD_GET_REGISTRATIONS check failed, expected: %d, got: %d", + barriers_registered, ret); + return false; + } + + return true; +} + +static bool check_membarriers(int barriers_registered) +{ + return check_membarriers_compat(barriers_registered) && + check_membarriers_get_registrations(barriers_registered); +} + int main(int argc, char **argv) { int barriers_registered;