Skip to content

Commit

Permalink
dump: use MEMBARRIER_CMD_GET_REGISTRATIONS when available
Browse files Browse the repository at this point in the history
MEMBARRIER_CMD_GET_REGISTRATIONS can tell us whether or not the process used
MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED unlike the old probing method.

Falls back to the old method when MEMBARRIER_CMD_GET_REGISTRATIONS is
unavailable.

Signed-off-by: Michal Clapinski <mclapinski@google.com>
  • Loading branch information
mclapinski committed Sep 12, 2023
1 parent 82bfb67 commit 2926651
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 13 deletions.
1 change: 1 addition & 0 deletions criu/include/kerndat.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ struct kerndat_s {
bool has_ptrace_get_rseq_conf;
struct __ptrace_rseq_configuration libc_rseq_conf;
bool has_ipv6_freebind;
bool has_membarrier_get_registrations;
};

extern struct kerndat_s kdat;
Expand Down
2 changes: 2 additions & 0 deletions criu/include/parasite.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ static inline int posix_timers_dump_size(int timer_n)
*/

struct parasite_dump_misc {
bool has_membarrier_get_registrations; // this is sent from criu to parasite.

unsigned long brk;

u32 pid;
Expand Down
22 changes: 22 additions & 0 deletions criu/kerndat.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <sys/inotify.h>
#include <sched.h>
#include <sys/mount.h>
#include <linux/membarrier.h>

#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1)
#include <nftables/libnftables.h>
Expand Down Expand Up @@ -1636,6 +1637,23 @@ static int kerndat_has_ipv6_freebind(void)
return ret;
}

static int kerndat_has_membarrier_get_registrations(void)
{
const int cmd_get_registrations = 1 << 9;
int ret = syscall(__NR_membarrier, cmd_get_registrations, 0);
if (ret < 0) {
if (errno != EINVAL) {
return ret;
}

kdat.has_membarrier_get_registrations = false;
} else {
kdat.has_membarrier_get_registrations = true;
}

return 0;
}

/*
* Some features depend on resource that can be dynamically changed
* at the OS runtime. There are cases that we cannot determine the
Expand Down Expand Up @@ -1879,6 +1897,10 @@ int kerndat_init(void)
pr_err("kerndat_has_ipv6_freebind failed when initializing kerndat.\n");
ret = -1;
}
if (!ret && kerndat_has_membarrier_get_registrations()) {
pr_err("kerndat_has_membarrier_get_registrations failed when initializing kerndat.\n");
ret = -1;
}

kerndat_lsm();
kerndat_mmap_min_addr();
Expand Down
1 change: 1 addition & 0 deletions criu/parasite-syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_mis
struct parasite_dump_misc *ma;

ma = compel_parasite_args(ctl, struct parasite_dump_misc);
ma->has_membarrier_get_registrations = kdat.has_membarrier_get_registrations;
if (compel_rpc_call_sync(PARASITE_CMD_DUMP_MISC, ctl) < 0)
return -1;

Expand Down
46 changes: 33 additions & 13 deletions criu/pie/parasite.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,27 @@ static int get_membarrier_registration_mask(int cmd_bit)
#define MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED 3
#define MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_SYNC_CORE 5
#define MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_RSEQ 7
#define MEMBARRIER_CMDBIT_GET_REGISTRATIONS 9

static int dump_membarrier_compat(int *membarrier_registration_mask)
{
int ret;

*membarrier_registration_mask = 0;
ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED);
if (ret < 0)
return -1;
*membarrier_registration_mask |= ret;
ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_SYNC_CORE);
if (ret < 0)
return -1;
*membarrier_registration_mask |= ret;
ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_RSEQ);
if (ret < 0)
return -1;
*membarrier_registration_mask |= ret;
return 0;
}

static int dump_misc(struct parasite_dump_misc *args)
{
Expand All @@ -261,19 +282,18 @@ static int dump_misc(struct parasite_dump_misc *args)
args->dumpable = sys_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
args->thp_disabled = sys_prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0);

args->membarrier_registration_mask = 0;
ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED);
if (ret < 0)
return -1;
args->membarrier_registration_mask |= ret;
ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_SYNC_CORE);
if (ret < 0)
return -1;
args->membarrier_registration_mask |= ret;
ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_RSEQ);
if (ret < 0)
return -1;
args->membarrier_registration_mask |= ret;
if (args->has_membarrier_get_registrations) {
ret = sys_membarrier(1 << MEMBARRIER_CMDBIT_GET_REGISTRATIONS, 0, 0);
if (ret < 0) {
pr_err("membarrier(1 << %d) returned %d\n", MEMBARRIER_CMDBIT_GET_REGISTRATIONS, ret);
return -1;
}
args->membarrier_registration_mask = ret;
} else {
ret = dump_membarrier_compat(&args->membarrier_registration_mask);
if (ret)
return ret;
}

ret = sys_prctl(PR_GET_CHILD_SUBREAPER, (unsigned long)&args->child_subreaper, 0, 0, 0);
if (ret)
Expand Down

0 comments on commit 2926651

Please sign in to comment.