Skip to content

Commit

Permalink
criu: Allow disabling freeze cgroups
Browse files Browse the repository at this point in the history
Some plugins (e.g., CUDA) may not function correctly when processes are
frozen using cgroups. This change introduces a mechanism to disable the
use of freeze cgroups during process seizing, even if explicitly
requested via the --freeze-cgroup option.

The CUDA plugin is updated to utilize this new mechanism to ensure
compatibility.

Signed-off-by: Andrei Vagin <[email protected]>
  • Loading branch information
avagin committed Sep 12, 2024
1 parent 4ca4a09 commit d83e536
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
1 change: 1 addition & 0 deletions criu/include/seize.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ extern bool alarm_timeouted(void);

extern char *task_comm_info(pid_t pid, char *comm, size_t size);
extern char *__task_comm_info(pid_t pid);
extern void dont_use_freeze_cgroup(void);

#endif
68 changes: 57 additions & 11 deletions criu/seize.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@
#include "xmalloc.h"
#include "util.h"

static bool freeze_cgroup_disabled;

/*
* Disables the use of freeze cgroups for process seizing, even if explicitly
* requested via the --freeze-cgroup option. This is necessary for plugins
* (e.g., CUDA) that do not function correctly when processes are frozen using
* cgroups.
*/
void __attribute__((used)) dont_use_freeze_cgroup(void)
{
freeze_cgroup_disabled = true;
}

char *task_comm_info(pid_t pid, char *comm, size_t size)
{
bool is_read = false;
Expand Down Expand Up @@ -397,7 +410,7 @@ static int freezer_detach(void)
{
int i;

if (!opts.freeze_cgroup)
if (!opts.freeze_cgroup || freeze_cgroup_disabled)
return 0;

for (i = 0; i < processes_to_wait && processes_to_wait_pids; i++) {
Expand Down Expand Up @@ -492,6 +505,33 @@ static int log_unfrozen_stacks(char *root)
return 0;
}

static int unfreeze_cgroup(void)
{
enum freezer_state state = THAWED;
int fd;

fd = freezer_open();
if (fd < 0)
return -1;

state = get_freezer_state(fd);
if (state == FREEZER_ERROR) {
close(fd);
return -1;
}
origin_freezer_state = state == FREEZING ? FROZEN : state;

if (origin_freezer_state != THAWED) {
pr_warn("The freeze cgroup will not be used. Unfreeze processes.\n");
if (freezer_write_state(fd, THAWED)) {
close(fd);
return -1;
}
}

return 0;
}

static int freeze_processes(void)
{
int fd, exit_code = -1;
Expand Down Expand Up @@ -643,7 +683,7 @@ static int collect_children(struct pstree_item *item)
goto free;
}

if (!opts.freeze_cgroup)
if (!opts.freeze_cgroup || freeze_cgroup_disabled)
/* fails when meets a zombie */
__ignore_value(compel_interrupt_task(pid));

Expand Down Expand Up @@ -831,7 +871,8 @@ static int collect_threads(struct pstree_item *item)

pr_info("\tSeizing %d's %d thread\n", item->pid->real, pid);

if (!opts.freeze_cgroup && compel_interrupt_task(pid))
if ((!opts.freeze_cgroup || freeze_cgroup_disabled) &&
compel_interrupt_task(pid))
continue;

ret = compel_wait_task(pid, item_ppid(item), parse_pid_status, NULL, &t_creds.s, NULL);
Expand Down Expand Up @@ -887,7 +928,7 @@ static int collect_loop(struct pstree_item *item, int (*collect)(struct pstree_i
{
int attempts = NR_ATTEMPTS, nr_inprogress = 1;

if (opts.freeze_cgroup)
if (opts.freeze_cgroup && !freeze_cgroup_disabled)
attempts = 1;

/*
Expand Down Expand Up @@ -993,12 +1034,16 @@ int collect_pstree(void)

pr_debug("Detected cgroup V%d freezer\n", cgroup_v2 ? 2 : 1);

if (opts.freeze_cgroup && freeze_processes())
goto err;

if (!opts.freeze_cgroup && compel_interrupt_task(pid)) {
set_cr_errno(ESRCH);
goto err;
if (opts.freeze_cgroup && !freeze_cgroup_disabled) {
if (freeze_processes())
goto err;
} else {
if (opts.freeze_cgroup && unfreeze_cgroup())
goto err;
if (compel_interrupt_task(pid)) {
set_cr_errno(ESRCH);
goto err;
}
}

ret = compel_wait_task(pid, -1, parse_pid_status, NULL, &creds.s, NULL);
Expand All @@ -1024,7 +1069,8 @@ int collect_pstree(void)
if (ret < 0)
goto err;

if (opts.freeze_cgroup && freezer_wait_processes()) {
if (opts.freeze_cgroup && !freeze_cgroup_disabled &&
freezer_wait_processes()) {
ret = -1;
goto err;
}
Expand Down
2 changes: 2 additions & 0 deletions plugins/cuda/cuda_plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,8 @@ int cuda_plugin_init(int stage)
INIT_LIST_HEAD(&cuda_pids);
}

dont_use_freeze_cgroup();

return 0;
}

Expand Down

0 comments on commit d83e536

Please sign in to comment.