[CRIU] [PATCH 3/5] util: Move epoll aux code from uffd to util (v2)
Mike Rapoport
rppt at linux.vnet.ibm.com
Tue Nov 22 04:35:08 PST 2016
On Tue, Nov 22, 2016 at 03:10:54PM +0300, Pavel Emelyanov wrote:
> v2: Move epoll_prepare() too
>
> Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
Acked-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
> ---
> criu/include/util.h | 15 +++++++++
> criu/uffd.c | 97 +++++++++--------------------------------------------
> criu/util.c | 64 +++++++++++++++++++++++++++++++++++
> 3 files changed, 95 insertions(+), 81 deletions(-)
>
> diff --git a/criu/include/util.h b/criu/include/util.h
> index 8eaee33..f20490c 100644
> --- a/criu/include/util.h
> +++ b/criu/include/util.h
> @@ -281,4 +281,19 @@ int setup_tcp_client(char *addr);
> #define LAST_PID_PATH "sys/kernel/ns_last_pid"
> #define PID_MAX_PATH "sys/kernel/pid_max"
>
> +/*
> + * Helpers to organize asynchronous reading from a bunch
> + * of file descriptors.
> + */
> +#include <sys/epoll.h>
> +
> +struct epoll_rfd {
> + int fd;
> + int (*revent)(struct epoll_rfd *);
> +};
> +
> +extern int epoll_add_rfd(int epfd, struct epoll_rfd *);
> +extern int epoll_run_rfds(int epfd, struct epoll_event *evs, int nr_fds, int tmo);
> +extern int epoll_prepare(int nr_events, struct epoll_event **evs);
> +
> #endif /* __CR_UTIL_H__ */
> diff --git a/criu/uffd.c b/criu/uffd.c
> index 5697708..301e3f4 100644
> --- a/criu/uffd.c
> +++ b/criu/uffd.c
> @@ -14,7 +14,6 @@
> #include <sys/ioctl.h>
> #include <sys/un.h>
> #include <sys/socket.h>
> -#include <sys/epoll.h>
> #include <sys/wait.h>
>
> #include "linux/userfaultfd.h"
> @@ -39,6 +38,7 @@
> #include "page-xfer.h"
> #include "common/lock.h"
> #include "rst-malloc.h"
> +#include "util.h"
>
> #undef LOG_PREFIX
> #define LOG_PREFIX "lazy-pages: "
> @@ -55,11 +55,6 @@ struct lazy_iovec {
>
> struct lazy_pages_info;
>
> -struct lazy_pages_fd {
> - int fd;
> - int (*event)(struct lazy_pages_fd *);
> -};
> -
> struct lazy_pages_info {
> int pid;
>
> @@ -70,7 +65,7 @@ struct lazy_pages_info {
> unsigned long total_pages;
> unsigned long copied_pages;
>
> - struct lazy_pages_fd lpfd;
> + struct epoll_rfd lpfd;
>
> struct list_head l;
>
> @@ -79,7 +74,7 @@ struct lazy_pages_info {
> };
>
> static LIST_HEAD(lpis);
> -static int handle_user_fault(struct lazy_pages_fd *lpfd);
> +static int handle_user_fault(struct epoll_rfd *lpfd);
>
> static struct lazy_pages_info *lpi_init(void)
> {
> @@ -92,7 +87,7 @@ static struct lazy_pages_info *lpi_init(void)
> memset(lpi, 0, sizeof(*lpi));
> INIT_LIST_HEAD(&lpi->iovs);
> INIT_LIST_HEAD(&lpi->l);
> - lpi->lpfd.event = handle_user_fault;
> + lpi->lpfd.revent = handle_user_fault;
>
> return lpi;
> }
> @@ -673,7 +668,7 @@ static int handle_remaining_pages(struct lazy_pages_info *lpi)
> return 0;
> }
>
> -static int handle_user_fault(struct lazy_pages_fd *lpfd)
> +static int handle_user_fault(struct epoll_rfd *lpfd)
> {
> struct lazy_pages_info *lpi;
> struct uffd_msg msg;
> @@ -737,39 +732,14 @@ static int lazy_pages_summary(struct lazy_pages_info *lpi)
>
> static int handle_requests(int epollfd, struct epoll_event *events)
> {
> - int nr_fds = epoll_nr_fds(task_entries->nr_tasks);
> struct lazy_pages_info *lpi;
> - int ret = -1;
> - int i;
> -
> - while (1) {
> - struct lazy_pages_fd *lpfd;
> -
> - /*
> - * Setting the timeout to 5 seconds. If after this time
> - * no uffd pages are requested the code switches to
> - * copying the remaining pages.
> - */
> - ret = epoll_wait(epollfd, events, nr_fds, POLL_TIMEOUT);
> - pr_debug("epoll() ret: 0x%x\n", ret);
> - if (ret < 0) {
> - pr_perror("polling failed");
> - goto out;
> - } else if (ret == 0) {
> - pr_debug("read timeout\n");
> - pr_debug("switching from request to copy mode\n");
> - break;
> - }
> + int ret;
>
> - for (i = 0; i < ret; i++) {
> - int err;
> + ret = epoll_run_rfds(epollfd, events, epoll_nr_fds(task_entries->nr_tasks), POLL_TIMEOUT);
> + if (ret < 0)
> + goto out;
>
> - lpfd = (struct lazy_pages_fd *)events[i].data.ptr;
> - err = lpfd->event(lpfd);
> - if (err < 0)
> - goto out;
> - }
> - }
> + pr_debug("switching from request to copy mode\n");
> pr_debug("Handle remaining pages\n");
> list_for_each_entry(lpi, &lpis, l) {
> ret = handle_remaining_pages(lpi);
> @@ -788,41 +758,6 @@ out:
>
> }
>
> -static int prepare_epoll(int nr_fds, struct epoll_event **events)
> -{
> - int epollfd;
> -
> - *events = xmalloc(sizeof(struct epoll_event) * nr_fds);
> - if (!*events)
> - return -1;
> -
> - epollfd = epoll_create(nr_fds);
> - if (epollfd == -1) {
> - pr_perror("epoll_create failed");
> - goto free_events;
> - }
> -
> - return epollfd;
> -
> -free_events:
> - free(*events);
> - return -1;
> -}
> -
> -static int epoll_add_lpfd(int epollfd, struct lazy_pages_fd *lpfd)
> -{
> - struct epoll_event ev;
> -
> - ev.events = EPOLLIN;
> - ev.data.ptr = lpfd;
> - if (epoll_ctl(epollfd, EPOLL_CTL_ADD, lpfd->fd, &ev) == -1) {
> - pr_perror("epoll_ctl failed");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> static int prepare_lazy_socket(void)
> {
> int listen;
> @@ -862,7 +797,7 @@ static int prepare_uffds(int listen, int epollfd)
> goto close_uffd;
> if (lpi == NULL)
> continue;
> - if (epoll_add_lpfd(epollfd, &lpi->lpfd))
> + if (epoll_add_rfd(epollfd, &lpi->lpfd))
> goto close_uffd;
> }
>
> @@ -876,12 +811,12 @@ close_uffd:
> return -1;
> }
>
> -static int page_server_event(struct lazy_pages_fd *lpfd)
> +static int page_server_event(struct epoll_rfd *lpfd)
> {
> return page_server_async_read();
> }
>
> -static struct lazy_pages_fd page_server_sk_fd;
> +static struct epoll_rfd page_server_sk_fd;
>
> static int prepare_page_server_socket(int epollfd)
> {
> @@ -891,10 +826,10 @@ static int prepare_page_server_socket(int epollfd)
> if (sk < 0)
> return -1;
>
> - page_server_sk_fd.event = page_server_event;
> + page_server_sk_fd.revent = page_server_event;
> page_server_sk_fd.fd = sk;
>
> - return epoll_add_lpfd(epollfd, &page_server_sk_fd);
> + return epoll_add_rfd(epollfd, &page_server_sk_fd);
> }
>
> int cr_lazy_pages(bool daemon)
> @@ -936,7 +871,7 @@ int cr_lazy_pages(bool daemon)
> }
>
> nr_fds = epoll_nr_fds(task_entries->nr_tasks);
> - epollfd = prepare_epoll(nr_fds, &events);
> + epollfd = epoll_prepare(nr_fds, &events);
> if (epollfd < 0)
> return -1;
>
> diff --git a/criu/util.c b/criu/util.c
> index 2cf0355..622e948 100644
> --- a/criu/util.c
> +++ b/criu/util.c
> @@ -1185,3 +1185,67 @@ int setup_tcp_client(char *addr)
>
> return sk;
> }
> +
> +int epoll_add_rfd(int epfd, struct epoll_rfd *rfd)
> +{
> + struct epoll_event ev;
> +
> + ev.events = EPOLLIN;
> + ev.data.ptr = rfd;
> + if (epoll_ctl(epfd, EPOLL_CTL_ADD, rfd->fd, &ev) == -1) {
> + pr_perror("epoll_ctl failed");
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +int epoll_run_rfds(int epollfd, struct epoll_event *evs, int nr_fds, int timeout)
> +{
> + int ret = 0, i;
> +
> + while (1) {
> + /* FIXME -- timeout should decrease over time... */
> + ret = epoll_wait(epollfd, evs, nr_fds, timeout);
> + pr_debug("epoll() ret: 0x%x\n", ret);
> + if (ret <= 0) {
> + if (ret < 0)
> + pr_perror("polling failed");
> + else
> + pr_debug("polling timeout\n");
> + break;
> + }
> +
> + for (i = 0; i < ret; i++) {
> + struct epoll_rfd *rfd;
> +
> + rfd = (struct epoll_rfd *)evs[i].data.ptr;
> + ret = rfd->revent(rfd);
> + if (ret < 0)
> + goto out;
> + }
> + }
> +out:
> + return ret;
> +}
> +
> +int epoll_prepare(int nr_fds, struct epoll_event **events)
> +{
> + int epollfd;
> +
> + *events = xmalloc(sizeof(struct epoll_event) * nr_fds);
> + if (!*events)
> + return -1;
> +
> + epollfd = epoll_create(nr_fds);
> + if (epollfd == -1) {
> + pr_perror("epoll_create failed");
> + goto free_events;
> + }
> +
> + return epollfd;
> +
> +free_events:
> + xfree(*events);
> + return -1;
> +}
> --
> 2.5.0
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
>
More information about the CRIU
mailing list