[CRIU] [RFC PATCH v2 20/23] lazy-pages: handle UFFD_EVENT_EXIT
Pavel Emelyanov
xemul at virtuozzo.com
Wed Feb 8 01:25:45 PST 2017
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()?
> + 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