mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-02 06:43:00 +00:00
lazy-pages: make the check for outstanding request more strict
There could be several outstaning requests for the same page, either from page fault handler or from handle_remaining_pages. Verifying that the faulting address is already requested is not enough. We need to check if there any request in flight that covers the faulting address. Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Acked-by: Pavel Emelyanov <xemul@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
9354582fd2
commit
7c108b8b8d
1 changed files with 16 additions and 3 deletions
19
criu/uffd.c
19
criu/uffd.c
|
|
@ -68,6 +68,7 @@ struct lazy_iov {
|
|||
struct lp_req {
|
||||
unsigned long addr; /* actual #PF (or background) destination */
|
||||
unsigned long img_addr; /* the corresponding address at the dump time */
|
||||
unsigned long len;
|
||||
struct list_head l;
|
||||
};
|
||||
|
||||
|
|
@ -817,6 +818,7 @@ static int handle_remaining_pages(struct lazy_pages_info *lpi)
|
|||
|
||||
req->addr = iov->base;
|
||||
req->img_addr = iov->img_base;
|
||||
req->len = iov->len;
|
||||
list_add(&req->l, &lpi->reqs);
|
||||
|
||||
err = uffd_handle_pages(lpi, req->img_addr, nr_pages, 0);
|
||||
|
|
@ -917,6 +919,17 @@ static int complete_forks(int epollfd, struct epoll_event **events, int *nr_fds)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool is_page_queued(struct lazy_pages_info *lpi, unsigned long addr)
|
||||
{
|
||||
struct lp_req *req;
|
||||
|
||||
list_for_each_entry(req, &lpi->reqs, l)
|
||||
if (addr >= req->addr && addr < req->addr + req->len)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int handle_page_fault(struct lazy_pages_info *lpi, struct uffd_msg *msg)
|
||||
{
|
||||
struct lp_req *req;
|
||||
|
|
@ -928,9 +941,8 @@ static int handle_page_fault(struct lazy_pages_info *lpi, struct uffd_msg *msg)
|
|||
address = msg->arg.pagefault.address & ~(page_size() - 1);
|
||||
lp_debug(lpi, "#PF at 0x%llx\n", address);
|
||||
|
||||
list_for_each_entry(req, &lpi->reqs, l)
|
||||
if (req->addr == address)
|
||||
return 0;
|
||||
if (is_page_queued(lpi, address))
|
||||
return 0;
|
||||
|
||||
iov = find_lazy_iov(lpi, address);
|
||||
if (!iov)
|
||||
|
|
@ -941,6 +953,7 @@ static int handle_page_fault(struct lazy_pages_info *lpi, struct uffd_msg *msg)
|
|||
return -1;
|
||||
req->addr = address;
|
||||
req->img_addr = iov->img_base + (address - iov->base);
|
||||
req->len = PAGE_SIZE;
|
||||
list_add(&req->l, &lpi->reqs);
|
||||
|
||||
ret = uffd_handle_pages(lpi, req->img_addr, 1, PR_ASYNC | PR_ASAP);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue