[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