[CRIU] [PATCH 10/10] uffd: Introduce lazy_pages_fd as preparation for socket polling

Mike Rapoport rppt at linux.vnet.ibm.com
Sat Nov 12 06:02:24 PST 2016


On Sat, Nov 12, 2016 at 08:26:27AM +0300, Pavel Emelyanov wrote:
> We will want to poll not only a bunch of uffd-s, but also the lazy
> socket, so here's "an fd and a callback" object to be pushed into
> epoll.

Nit: it's not lazy socket, it's page-server socket
 
> Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>

Acked-by: Mike Rapoport <rppt at linux.vnet.ibm.com>

> ---
>  criu/uffd.c | 49 +++++++++++++++++++++++++++++++------------------
>  1 file changed, 31 insertions(+), 18 deletions(-)
> 
> diff --git a/criu/uffd.c b/criu/uffd.c
> index 1393a70..a5c2f8e 100644
> --- a/criu/uffd.c
> +++ b/criu/uffd.c
> @@ -48,9 +48,13 @@
>  static mutex_t *lazy_sock_mutex;
>  static void *aux_page;
> 
> +struct lazy_pages_fd {
> +	int fd;
> +	int (*event)(struct lazy_pages_fd *);
> +};
> +
>  struct lazy_pages_info {
>  	int pid;
> -	int uffd;
> 
>  	struct list_head pages;
> 
> @@ -59,10 +63,13 @@ struct lazy_pages_info {
>  	unsigned long total_pages;
>  	unsigned long copied_pages;
> 
> +	struct lazy_pages_fd lpfd;
> +
>  	struct list_head l;
>  };
> 
>  static LIST_HEAD(lpis);
> +static int handle_user_fault(struct lazy_pages_fd *lpfd);
> 
>  static struct lazy_pages_info *lpi_init(void)
>  {
> @@ -75,6 +82,7 @@ static struct lazy_pages_info *lpi_init(void)
>  	memset(lpi, 0, sizeof(*lpi));
>  	INIT_LIST_HEAD(&lpi->pages);
>  	INIT_LIST_HEAD(&lpi->l);
> +	lpi->lpfd.event = handle_user_fault;
> 
>  	return lpi;
>  }
> @@ -83,8 +91,8 @@ static void lpi_fini(struct lazy_pages_info *lpi)
>  {
>  	if (!lpi)
>  		return;
> -	if (lpi->uffd > 0)
> -		close(lpi->uffd);
> +	if (lpi->lpfd.fd > 0)
> +		close(lpi->lpfd.fd);
>  	if (lpi->pr.close)
>  		lpi->pr.close(&lpi->pr);
>  	free(lpi);
> @@ -318,15 +326,15 @@ static int ud_open(int client, struct lazy_pages_info **_lpi)
>  		return 0;
>  	}
> 
> -	lpi->uffd = recv_fd(client);
> -	if (lpi->uffd < 0) {
> +	lpi->lpfd.fd = recv_fd(client);
> +	if (lpi->lpfd.fd < 0) {
>  		pr_err("recv_fd error");
>  		goto out;
>  	}
> -	pr_debug("lpi->uffd %d\n", lpi->uffd);
> +	pr_debug("lpi->uffd %d\n", lpi->lpfd.fd);
> 
> -	pr_debug("uffd is 0x%d\n", lpi->uffd);
> -	uffd_flags = fcntl(lpi->uffd, F_GETFD, NULL);
> +	pr_debug("uffd is 0x%d\n", lpi->lpfd.fd);
> +	uffd_flags = fcntl(lpi->lpfd.fd, F_GETFD, NULL);
>  	pr_debug("uffd_flags are 0x%x\n", uffd_flags);
> 
>  	/*
> @@ -395,7 +403,7 @@ static int uffd_copy_page(struct lazy_pages_info *lpi, __u64 address)
>  	uffdio_copy.copy = 0;
> 
>  	pr_debug("uffdio_copy.dst 0x%llx\n", uffdio_copy.dst);
> -	rc = ioctl(lpi->uffd, UFFDIO_COPY, &uffdio_copy);
> +	rc = ioctl(lpi->lpfd.fd, UFFDIO_COPY, &uffdio_copy);
>  	pr_debug("ioctl UFFDIO_COPY rc 0x%x\n", rc);
>  	pr_debug("uffdio_copy.copy 0x%llx\n", uffdio_copy.copy);
>  	if (rc) {
> @@ -426,7 +434,7 @@ static int uffd_zero_page(struct lazy_pages_info *lpi, __u64 address)
>  	uffdio_zeropage.mode = 0;
> 
>  	pr_debug("uffdio_zeropage.range.start 0x%llx\n", uffdio_zeropage.range.start);
> -	rc = ioctl(lpi->uffd, UFFDIO_ZEROPAGE, &uffdio_zeropage);
> +	rc = ioctl(lpi->lpfd.fd, UFFDIO_ZEROPAGE, &uffdio_zeropage);
>  	pr_debug("ioctl UFFDIO_ZEROPAGE rc 0x%x\n", rc);
>  	pr_debug("uffdio_zeropage.zeropage 0x%llx\n", uffdio_zeropage.zeropage);
>  	if (rc) {
> @@ -643,15 +651,18 @@ out:
>  	return ret;
>  }
> 
> -static int handle_user_fault(struct lazy_pages_info *lpi)
> +static int handle_user_fault(struct lazy_pages_fd *lpfd)
>  {
> +	struct lazy_pages_info *lpi;
>  	struct uffd_msg msg;
>  	__u64 flags;
>  	__u64 address;
>  	struct uffd_pages_struct *uffd_pages;
>  	int ret;
> 
> -	ret = read(lpi->uffd, &msg, sizeof(msg));
> +	lpi = container_of(lpfd, struct lazy_pages_info, lpfd);
> +
> +	ret = read(lpfd->fd, &msg, sizeof(msg));
>  	pr_debug("read() ret: 0x%x\n", ret);
>  	if (!ret)
>  		return 1;
> @@ -723,6 +734,8 @@ static int handle_requests(int epollfd, struct epoll_event *events)
>  		return ret;
> 
>  	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
> @@ -742,8 +755,8 @@ static int handle_requests(int epollfd, struct epoll_event *events)
>  		for (i = 0; i < ret; i++) {
>  			int err;
> 
> -			lpi = (struct lazy_pages_info *)events[i].data.ptr;
> -			err = handle_user_fault(lpi);
> +			lpfd = (struct lazy_pages_fd *)events[i].data.ptr;
> +			err = lpfd->event(lpfd);
>  			if (err < 0)
>  				goto out;
>  		}
> @@ -803,13 +816,13 @@ free_events:
>  	return -1;
>  }
> 
> -static int epoll_add_lpi(int epollfd, struct lazy_pages_info *lpi)
> +static int epoll_add_lpfd(int epollfd, struct lazy_pages_fd *lpfd)
>  {
>  	struct epoll_event ev;
> 
>  	ev.events = EPOLLIN;
> -	ev.data.ptr = lpi;
> -	if (epoll_ctl(epollfd, EPOLL_CTL_ADD, lpi->uffd, &ev) == -1) {
> +	ev.data.ptr = lpfd;
> +	if (epoll_ctl(epollfd, EPOLL_CTL_ADD, lpfd->fd, &ev) == -1) {
>  		pr_perror("epoll_ctl failed");
>  		return -1;
>  	}
> @@ -856,7 +869,7 @@ static int prepare_uffds(int listen, int epollfd)
>  			goto close_uffd;
>  		if (lpi == NULL)
>  			continue;
> -		if (epoll_add_lpi(epollfd, lpi))
> +		if (epoll_add_lpfd(epollfd, &lpi->lpfd))
>  			goto close_uffd;
>  	}
> 
> -- 
> 2.5.0
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
> 



More information about the CRIU mailing list