Commit c9d374bb authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

uffd: Helper to complete the #PF

The _copy and _update_lazy_iovecs are both called by hands
once the data is ready.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Acked-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
parent eb0e0426
...@@ -82,6 +82,7 @@ struct lazy_pages_info { ...@@ -82,6 +82,7 @@ struct lazy_pages_info {
struct list_head l; struct list_head l;
void *buf; void *buf;
bool remaining;
}; };
static LIST_HEAD(lpis); static LIST_HEAD(lpis);
...@@ -575,6 +576,17 @@ static int uffd_copy(struct lazy_pages_info *lpi, __u64 address, int nr_pages) ...@@ -575,6 +576,17 @@ static int uffd_copy(struct lazy_pages_info *lpi, __u64 address, int nr_pages)
return 0; return 0;
} }
static int complete_page_fault(struct lazy_pages_info *lpi, unsigned long vaddr, int nr)
{
if (uffd_copy(lpi, vaddr, nr))
return -1;
if (lpi->remaining)
return 0;
return update_lazy_iovecs(lpi, vaddr, nr * PAGE_SIZE);
}
static int uffd_zero(struct lazy_pages_info *lpi, __u64 address, int nr_pages) static int uffd_zero(struct lazy_pages_info *lpi, __u64 address, int nr_pages)
{ {
struct uffdio_zeropage uffdio_zeropage; struct uffdio_zeropage uffdio_zeropage;
...@@ -637,7 +649,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr) ...@@ -637,7 +649,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr)
return ret; return ret;
} }
return uffd_copy(lpi, address, nr); return complete_page_fault(lpi, address, nr);
} }
static int handle_remaining_pages(struct lazy_pages_info *lpi) static int handle_remaining_pages(struct lazy_pages_info *lpi)
...@@ -645,6 +657,8 @@ static int handle_remaining_pages(struct lazy_pages_info *lpi) ...@@ -645,6 +657,8 @@ static int handle_remaining_pages(struct lazy_pages_info *lpi)
struct lazy_iovec *lazy_iov; struct lazy_iovec *lazy_iov;
int nr_pages, err; int nr_pages, err;
lpi->remaining = true;
lpi->pr.reset(&lpi->pr); lpi->pr.reset(&lpi->pr);
list_for_each_entry(lazy_iov, &lpi->iovs, l) { list_for_each_entry(lazy_iov, &lpi->iovs, l) {
...@@ -683,13 +697,7 @@ static int page_fault_local(struct lazy_pages_info *lpi, __u64 address, int nr) ...@@ -683,13 +697,7 @@ static int page_fault_local(struct lazy_pages_info *lpi, __u64 address, int nr)
if (page_fault_common(lpi, address, nr, PR_ASYNC | PR_ASAP)) if (page_fault_common(lpi, address, nr, PR_ASYNC | PR_ASAP))
return -1; return -1;
if (uffd_copy(lpi, address, nr)) return complete_page_fault(lpi, address, nr);
return -1;
if (update_lazy_iovecs(lpi, address, PAGE_SIZE * nr))
return -1;
return 0;
} }
static int page_fault_remote(struct lazy_pages_info *lpi, __u64 address, int nr) static int page_fault_remote(struct lazy_pages_info *lpi, __u64 address, int nr)
...@@ -957,13 +965,7 @@ static int page_server_event(struct lazy_pages_fd *lpfd) ...@@ -957,13 +965,7 @@ static int page_server_event(struct lazy_pages_fd *lpfd)
if (receive_remote_pages(nr_pages * PAGE_SIZE, lpi->buf)) if (receive_remote_pages(nr_pages * PAGE_SIZE, lpi->buf))
return -1; return -1;
if (uffd_copy(lpi, addr, nr_pages)) return complete_page_fault(lpi, addr, nr_pages);
return -1;
if (update_lazy_iovecs(lpi, addr, PAGE_SIZE * nr_pages))
return -1;
return 0;
} }
} }
......
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