[CRIU] [RFC PATCH v2 20/23] lazy-pages: handle UFFD_EVENT_EXIT

Mike Rapoport rppt at linux.vnet.ibm.com
Wed Feb 8 01:57:06 PST 2017


On Wed, Feb 08, 2017 at 12:25:45PM +0300, Pavel Emelyanov wrote:
> On 02/06/2017 02:44 PM, Mike Rapoport wrote:
> > Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
> > ---
> >  criu/uffd.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 43 insertions(+), 3 deletions(-)
> > 
> > diff --git a/criu/uffd.c b/criu/uffd.c
> > index 6ac34f7..f2a6bfa 100644
> > --- a/criu/uffd.c
> > +++ b/criu/uffd.c
> > @@ -87,6 +87,8 @@ struct lazy_pages_info {
> >  };
> >  
> >  static LIST_HEAD(lpis);
> > +static LIST_HEAD(exiting_lpis);
> > +
> >  static int handle_uffd_event(struct epoll_rfd *lpfd);
> >  
> >  static struct lazy_pages_info *lpi_init(void)
> > @@ -106,15 +108,23 @@ static struct lazy_pages_info *lpi_init(void)
> >  	return lpi;
> >  }
> >  
> > -static void lpi_fini(struct lazy_pages_info *lpi)
> > +static void free_lazy_iovs(struct lazy_pages_info *lpi)
> >  {
> >  	struct lazy_iov *p, *n;
> >  
> > +	list_for_each_entry_safe(p, n, &lpi->iovs, l) {
> > +		list_del(&p->l);
> > +		xfree(p);
> > +	}
> > +}
> > +
> > +static void lpi_fini(struct lazy_pages_info *lpi)
> > +{
> > +
> >  	if (!lpi)
> >  		return;
> >  	free(lpi->buf);
> > -	list_for_each_entry_safe(p, n, &lpi->iovs, l)
> > -		xfree(p);
> > +	free_lazy_iovs(lpi);
> >  	if (lpi->lpfd.fd > 0)
> >  		close(lpi->lpfd.fd);
> >  	if (lpi->pr.close)
> > @@ -797,6 +807,29 @@ static int handle_remap(struct lazy_pages_info *lpi, struct uffd_msg *msg)
> >  	return remap_lazy_iovs(lpi, from, to, len);
> >  }
> >  
> > +static int handle_exit(struct lazy_pages_info *lpi, struct uffd_msg *msg)
> > +{
> > +	lp_debug(lpi, "EXIT\n");
> > +	list_move(&lpi->l, &exiting_lpis);
> 
> Why not kill it right here? What do we wait for epoll event on this
> guy to call complete_exits()?

Here it's pretty much because I was too lazy to bring epollfd all the way
here.
 
> > +	return 1;
> > +}
> > +
> > +static int complete_exits(int epollfd)
> > +{
> > +	struct lazy_pages_info *lpi, *n;
> > +
> > +	list_for_each_entry_safe(lpi, n, &exiting_lpis, l) {
> > +		if (epoll_del_rfd(epollfd, &lpi->lpfd))
> > +			return -1;
> > +		free_lazy_iovs(lpi);
> > +		close(lpi->lpfd.fd);
> > +		/* keep it for summary */
> > +		list_move_tail(&lpi->l, &lpis);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static int handle_page_fault(struct lazy_pages_info *lpi, struct uffd_msg *msg)
> >  {
> >  	struct lp_req *req;
> > @@ -863,6 +896,8 @@ static int handle_uffd_event(struct epoll_rfd *lpfd)
> >  		return handle_remove(lpi, &msg);
> >  	case UFFD_EVENT_REMAP:
> >  		return handle_remap(lpi, &msg);
> > +	case UFFD_EVENT_EXIT:
> > +		return handle_exit(lpi, &msg);
> >  	default:
> >  		lp_err(lpi, "unexpected uffd event %u\n", msg.event);
> >  		return -1;
> > @@ -902,6 +937,11 @@ static int handle_requests(int epollfd, struct epoll_event *events, int nr_fds)
> >  		ret = epoll_run_rfds(epollfd, events, nr_fds, poll_timeout);
> >  		if (ret < 0)
> >  			goto out;
> > +		if (ret > 0) {
> > +			if (complete_exits(epollfd))
> > +				return -1;
> > +			continue;
> > +		}
> >  
> >  		if (poll_timeout)
> >  			pr_debug("Start handling remaining pages\n");
> > 
> 



More information about the CRIU mailing list