Commit d7c0b1f1 authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

lazy-pages: handle UFFD_EVENT_EXIT

travis-ci: success for lazy-pages: add non-#PF events handling (rev2)
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent f10b348e
...@@ -87,6 +87,8 @@ struct lazy_pages_info { ...@@ -87,6 +87,8 @@ struct lazy_pages_info {
}; };
static LIST_HEAD(lpis); static LIST_HEAD(lpis);
static LIST_HEAD(exiting_lpis);
static int handle_uffd_event(struct epoll_rfd *lpfd); static int handle_uffd_event(struct epoll_rfd *lpfd);
static struct lazy_pages_info *lpi_init(void) static struct lazy_pages_info *lpi_init(void)
...@@ -106,15 +108,23 @@ static struct lazy_pages_info *lpi_init(void) ...@@ -106,15 +108,23 @@ static struct lazy_pages_info *lpi_init(void)
return lpi; 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; 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) if (!lpi)
return; return;
free(lpi->buf); free(lpi->buf);
list_for_each_entry_safe(p, n, &lpi->iovs, l) free_lazy_iovs(lpi);
xfree(p);
if (lpi->lpfd.fd > 0) if (lpi->lpfd.fd > 0)
close(lpi->lpfd.fd); close(lpi->lpfd.fd);
if (lpi->pr.close) if (lpi->pr.close)
...@@ -797,6 +807,29 @@ static int handle_remap(struct lazy_pages_info *lpi, struct uffd_msg *msg) ...@@ -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); 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) static int handle_page_fault(struct lazy_pages_info *lpi, struct uffd_msg *msg)
{ {
struct lp_req *req; struct lp_req *req;
...@@ -863,6 +896,8 @@ static int handle_uffd_event(struct epoll_rfd *lpfd) ...@@ -863,6 +896,8 @@ static int handle_uffd_event(struct epoll_rfd *lpfd)
return handle_remove(lpi, &msg); return handle_remove(lpi, &msg);
case UFFD_EVENT_REMAP: case UFFD_EVENT_REMAP:
return handle_remap(lpi, &msg); return handle_remap(lpi, &msg);
case UFFD_EVENT_EXIT:
return handle_exit(lpi, &msg);
default: default:
lp_err(lpi, "unexpected uffd event %u\n", msg.event); lp_err(lpi, "unexpected uffd event %u\n", msg.event);
return -1; return -1;
...@@ -902,6 +937,11 @@ static int handle_requests(int epollfd, struct epoll_event *events, int nr_fds) ...@@ -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); ret = epoll_run_rfds(epollfd, events, nr_fds, poll_timeout);
if (ret < 0) if (ret < 0)
goto out; goto out;
if (ret > 0) {
if (complete_exits(epollfd))
return -1;
continue;
}
if (poll_timeout) if (poll_timeout)
pr_debug("Start handling remaining pages\n"); pr_debug("Start handling remaining pages\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment