Skip to content

Commit

Permalink
Merge pull request #3413 from Blub/dont-busy-loop-on-freeze
Browse files Browse the repository at this point in the history
Don't busy loop on freeze with cgroupv2
  • Loading branch information
Christian Brauner committed May 15, 2020
2 parents 94f544e + 385e58e commit 6b641ce
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 49 deletions.
66 changes: 20 additions & 46 deletions src/lxc/cgroups/cgfsng.c
Expand Up @@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <unistd.h>

Expand Down Expand Up @@ -2042,7 +2043,11 @@ static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata,
return LXC_MAINLOOP_CONTINUE;
}

static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
static int cg_unified_freeze_do(struct cgroup_ops *ops, int timeout,
const char *state_string,
int state_num,
const char *epoll_error,
const char *wait_error)
{
__do_close int fd = -EBADF;
call_cleaner(lxc_mainloop_close) struct lxc_epoll_descr *descr_ptr = NULL;
Expand All @@ -2067,26 +2072,33 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)

ret = lxc_mainloop_open(&descr);
if (ret)
return log_error_errno(-1, errno, "Failed to create epoll instance to wait for container freeze");
return log_error_errno(-1, errno, "%s", epoll_error);

/* automatically cleaned up now */
descr_ptr = &descr;

ret = lxc_mainloop_add_handler(&descr, fd, freezer_cgroup_events_cb, INT_TO_PTR((int){1}));
ret = lxc_mainloop_add_handler_events(&descr, fd, EPOLLPRI, freezer_cgroup_events_cb, INT_TO_PTR(state_num));
if (ret < 0)
return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop");
}

ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "1", 1);
ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", state_string, 1);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to open cgroup.freeze file");

if (timeout != 0 && lxc_mainloop(&descr, timeout))
return log_error_errno(-1, errno, "Failed to wait for container to be frozen");
return log_error_errno(-1, errno, "%s", wait_error);

return 0;
}

static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
{
return cg_unified_freeze_do(ops, timeout, "1", 1,
"Failed to create epoll instance to wait for container freeze",
"Failed to wait for container to be frozen");
}

__cgfsng_ops static int cgfsng_freeze(struct cgroup_ops *ops, int timeout)
{
if (!ops->hierarchies)
Expand All @@ -2112,47 +2124,9 @@ static int cg_legacy_unfreeze(struct cgroup_ops *ops)

static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout)
{
__do_close int fd = -EBADF;
call_cleaner(lxc_mainloop_close)struct lxc_epoll_descr *descr_ptr = NULL;
int ret;
struct lxc_epoll_descr descr;
struct hierarchy *h;

h = ops->unified;
if (!h)
return ret_set_errno(-1, ENOENT);

if (!h->container_full_path)
return ret_set_errno(-1, EEXIST);

if (timeout != 0) {
__do_free char *events_file = NULL;

events_file = must_make_path(h->container_full_path, "cgroup.events", NULL);
fd = open(events_file, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return log_error_errno(-1, errno, "Failed to open cgroup.events file");

ret = lxc_mainloop_open(&descr);
if (ret)
return log_error_errno(-1, errno, "Failed to create epoll instance to wait for container unfreeze");

/* automatically cleaned up now */
descr_ptr = &descr;

ret = lxc_mainloop_add_handler(&descr, fd, freezer_cgroup_events_cb, INT_TO_PTR((int){0}));
if (ret < 0)
return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop");
}

ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "0", 1);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to open cgroup.freeze file");

if (timeout != 0 && lxc_mainloop(&descr, timeout))
return log_error_errno(-1, errno, "Failed to wait for container to be unfrozen");

return 0;
return cg_unified_freeze_do(ops, timeout, "0", 0,
"Failed to create epoll instance to wait for container unfreeze",
"Failed to wait for container to be unfrozen");
}

__cgfsng_ops static int cgfsng_unfreeze(struct cgroup_ops *ops, int timeout)
Expand Down
15 changes: 12 additions & 3 deletions src/lxc/mainloop.c
Expand Up @@ -59,8 +59,10 @@ int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms)
}
}

int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
lxc_mainloop_callback_t callback, void *data)
int lxc_mainloop_add_handler_events(struct lxc_epoll_descr *descr, int fd,
int events,
lxc_mainloop_callback_t callback,
void *data)
{
__do_free struct mainloop_handler *handler = NULL;
__do_free struct lxc_list *item = NULL;
Expand All @@ -77,7 +79,7 @@ int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
handler->fd = fd;
handler->data = data;

ev.events = EPOLLIN;
ev.events = events;
ev.data.ptr = handler;

if (epoll_ctl(descr->epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
Expand All @@ -92,6 +94,13 @@ int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
return 0;
}

int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
lxc_mainloop_callback_t callback, void *data)
{
return lxc_mainloop_add_handler_events(descr, fd, EPOLLIN, callback,
data);
}

int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd)
{
struct mainloop_handler *handler;
Expand Down
4 changes: 4 additions & 0 deletions src/lxc/mainloop.h
Expand Up @@ -22,6 +22,10 @@ typedef int (*lxc_mainloop_callback_t)(int fd, uint32_t event, void *data,

extern int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms);

extern int lxc_mainloop_add_handler_events(struct lxc_epoll_descr *descr,
int fd, int events,
lxc_mainloop_callback_t callback,
void *data);
extern int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
lxc_mainloop_callback_t callback,
void *data);
Expand Down

0 comments on commit 6b641ce

Please sign in to comment.