mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 14:55:39 +00:00
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: Pavel Emelyanov <xemul@virtuozzo.com> Acked-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
This commit is contained in:
committed by
Andrei Vagin
parent
eb0e042666
commit
c9d374bb01
32
criu/uffd.c
32
criu/uffd.c
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user