From ba3d099b74e44f0f310ed705cd2ffde08d11c424 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Mon, 6 Feb 2017 13:44:06 +0200 Subject: [PATCH] lazy-pages: add handling of UFFD_EVENT_REMOVE When the restored process calls madvise(MADV_DONTNEED) or madvise(MADV_REMOVE) the memory range specified by the madvise() call should be remapped to zero pfn and we should stop monitoring this range in order to avoid its pollution with data the process does not expect. All we need to do here, is to unregister the memory range from userfaultfd and the kernel will take care of the rest. travis-ci: success for lazy-pages: add non-#PF events handling (rev2) Signed-off-by: Mike Rapoport Signed-off-by: Pavel Emelyanov --- criu/uffd.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/criu/uffd.c b/criu/uffd.c index 1066dc1eb..a96f62e32 100644 --- a/criu/uffd.c +++ b/criu/uffd.c @@ -671,6 +671,24 @@ static int handle_remaining_pages(struct lazy_pages_info *lpi) return 0; } +static int handle_remove(struct lazy_pages_info *lpi, struct uffd_msg *msg) +{ + struct uffdio_range unreg; + + 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); + + if (ioctl(lpi->lpfd.fd, UFFDIO_UNREGISTER, &unreg)) { + pr_perror("Failed to unregister (%llx - %llx)", unreg.start, + unreg.start + unreg.len); + return -1; + } + + return drop_lazy_iovs(lpi, unreg.start, unreg.len); +} + static int handle_page_fault(struct lazy_pages_info *lpi, struct uffd_msg *msg) { struct lp_req *req; @@ -731,6 +749,8 @@ static int handle_uffd_event(struct epoll_rfd *lpfd) switch (msg.event) { case UFFD_EVENT_PAGEFAULT: return handle_page_fault(lpi, &msg); + case UFFD_EVENT_REMOVE: + return handle_remove(lpi, &msg); default: lp_err(lpi, "unexpected uffd event %u\n", msg.event); return -1;