[CRIU] [RFC PATCH v2 14/23] lazy-pages: add handling of UFFD_EVENT_UNMAP

Mike Rapoport rppt at linux.vnet.ibm.com
Mon Feb 6 03:44:07 PST 2017


The UNMAP event is generated by userfaultfd when a VMA (or a part of it) is
unmapped from the process address space. We won't receive #PF's at the
unmapped range, but we need to make sure we are not trying to fill that
range at handle_remaining_pages.
Note, that the VMA is gone, so there is no sense to unregister uffd from
it.

Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/uffd.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/criu/uffd.c b/criu/uffd.c
index 53e8580..9633061 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -678,9 +678,17 @@ static int handle_remove(struct lazy_pages_info *lpi, struct uffd_msg *msg)
 	unreg.start = msg->arg.remove.start;
 	unreg.len = msg->arg.remove.end - msg->arg.remove.start;
 
-	lp_debug(lpi, "REMOVE: %Lx(%Lx)\n", unreg.start, unreg.len);
+	lp_debug(lpi, "%s: %Lx(%Lx)\n",
+		 msg->event == UFFD_EVENT_REMOVE ? "REMOVE" : "UNMAP",
+		 unreg.start, unreg.len);
 
-	if (ioctl(lpi->lpfd.fd, UFFDIO_UNREGISTER, &unreg)) {
+	/*
+	 * The REMOVE event does not change the VMA, so we need to
+	 * make sure that we won't handle #PFs in the removed
+	 * range. With UNMAP, there's no VMA to worry about
+	 */
+	if (msg->event == UFFD_EVENT_REMOVE &&
+	    ioctl(lpi->lpfd.fd, UFFDIO_UNREGISTER, &unreg)) {
 		pr_perror("Failed to unregister (%llx - %llx)", unreg.start,
 			  unreg.start + unreg.len);
 		return -1;
@@ -750,6 +758,7 @@ static int handle_uffd_event(struct epoll_rfd *lpfd)
 	case UFFD_EVENT_PAGEFAULT:
 		return handle_page_fault(lpi, &msg);
 	case UFFD_EVENT_REMOVE:
+	case UFFD_EVENT_UNMAP:
 		return handle_remove(lpi, &msg);
 	default:
 		lp_err(lpi, "unexpected uffd event %u\n", msg.event);
-- 
1.9.1



More information about the CRIU mailing list