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

page-xfer: add methods for requesting and receiving remote pages

For asynchrounous page transfers in post-copy migration we need to be able
to request a remote pages, receive back information about the data is going
to arrive and receive the page data itself.

travis-ci: success for uffd: A new set of improvements
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 57d341f1
......@@ -42,6 +42,23 @@ extern int disconnect_from_page_server(void);
extern int check_parent_page_xfer(int fd_type, long id);
/*
* The post-copy migration makes it necessary to receive pages from
* remote dump. The protocol we use for that is quite simple:
* - lazy-pages sedns request containing PS_IOV_GET(nr_pages, vaddr, pid)
* - dump-side page server responds with PS_IOV_ADD(nr_pages, vaddr,
pid) or PS_IOV_ADD(0, 0, 0) if it failed to locate the required
pages
* - dump-side page server sends the raw page data
*/
/* sync receive of remote pages */
extern int get_remote_pages(int pid, unsigned long addr, int nr_pages, void *dest);
/* async request/receive of remote pages */
extern int request_remote_pages(int pid, unsigned long addr, int nr_pages);
extern int receive_remote_pages_info(int *nr_pages, unsigned long *addr, int *pid);
extern int receive_remote_pages(int len, void *buf);
#endif /* __CR_PAGE_XFER__H__ */
......@@ -979,3 +979,48 @@ int get_remote_pages(int pid, unsigned long addr, int nr_pages, void *dest)
return 1;
}
int request_remote_pages(int pid, unsigned long addr, int nr_pages)
{
struct page_server_iov pi = {
.cmd = PS_IOV_GET,
.nr_pages = nr_pages,
.vaddr = addr,
.dst_id = pid,
};
/* We cannot use send_psi here because we have to use MSG_DONTWAIT */
if (send(page_server_sk, &pi, sizeof(pi), MSG_DONTWAIT) != sizeof(pi)) {
pr_perror("Can't write PSI to server");
return -1;
}
tcp_nodelay(page_server_sk, true);
return 0;
}
int receive_remote_pages_info(int *nr_pages, unsigned long *addr, int *pid)
{
struct page_server_iov pi;
if (recv(page_server_sk, &pi, sizeof(pi), MSG_WAITALL) != sizeof(pi)) {
pr_perror("Failed to receive page metadata");
return -1;
}
*nr_pages = pi.nr_pages;
*addr = pi.vaddr;
*pid = pi.dst_id;
return 0;
}
int receive_remote_pages(int len, void *buf)
{
if (recv(page_server_sk, buf, len, MSG_WAITALL) != len) {
pr_perror("Failed to receive page data");
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