2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 01:51:51 +00:00

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.

Signed-off-by: Michal Clapinski <mclapinski@google.com>
This commit is contained in:
Michal Clapinski 2023-09-13 18:42:58 +02:00 committed by Andrei Vagin
parent 2ba8727822
commit 8caf460b9c

View File

@ -8,14 +8,16 @@ const char *test_author = "Michał Mirosław <emmir@google.com>";
/*
* 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;