[CRIU] [RFC PATCH v2 20/23] lazy-pages: handle UFFD_EVENT_EXIT
Mike Rapoport
rppt at linux.vnet.ibm.com
Mon Feb 6 03:44:13 PST 2017
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);
+ 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");
--
1.9.1
More information about the CRIU
mailing list