[CRIU] [RFC PATCH 03/16] criu: lazy-pages: introduce collect_lazy_iovecs
Mike Rapoport
rppt at linux.vnet.ibm.com
Tue Sep 27 06:42:04 PDT 2016
Instead of tracking memory handled by userfaultfd on the page basis we can
use IOVs for continious chunks. Start conversion by introducing
collect_lazy_iovecs function.
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/uffd.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/criu/uffd.c b/criu/uffd.c
index 81dc7ae..063ce4f 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -45,11 +45,17 @@
static mutex_t *lazy_sock_mutex;
+struct lazy_iovec {
+ struct iovec iov;
+ struct list_head l;
+};
+
struct lazy_pages_info {
int pid;
int uffd;
struct list_head pages;
+ struct list_head iovs;
struct page_read pr;
@@ -74,6 +80,7 @@ static struct lazy_pages_info *lpi_init(void)
memset(lpi, 0, sizeof(*lpi));
INIT_LIST_HEAD(&lpi->pages);
+ INIT_LIST_HEAD(&lpi->iovs);
INIT_HLIST_NODE(&lpi->hash);
return lpi;
@@ -81,8 +88,12 @@ static struct lazy_pages_info *lpi_init(void)
static void lpi_fini(struct lazy_pages_info *lpi)
{
+ struct lazy_iovec *p, *n;
+
if (!lpi)
return;
+ list_for_each_entry_safe(p, n, &lpi->iovs, l)
+ xfree(p);
if (lpi->uffd > 0)
close(lpi->uffd);
if (lpi->pr.close)
@@ -314,6 +325,42 @@ out:
static int find_vmas(struct lazy_pages_info *lpi);
+static int collect_lazy_iovecs(struct lazy_pages_info *lpi)
+{
+ struct page_read *pr = &lpi->pr;
+ struct lazy_iovec *lazy_iov, *n;
+ int nr_pages = 0;
+
+ pr->reset(pr);
+
+ while (pr->advance(pr)) {
+ PagemapEntry *pe = pr->pe;
+
+ if (!pagemap_lazy(pe))
+ continue;
+
+ lazy_iov = xzalloc(sizeof(*lazy_iov));
+ if (!lazy_iov) {
+ pr_err("Out of memory\n");
+ goto free_iovs;
+ }
+
+ pagemap2iovec(pe, &lazy_iov->iov);
+ list_add_tail(&lazy_iov->l, &lpi->iovs);
+ nr_pages += pe->nr_pages;
+
+ pr_debug("adding IOV: %p:%lx (%d)\n", lazy_iov->iov.iov_base, lazy_iov->iov.iov_len, pe->nr_pages);
+ }
+
+ return nr_pages;
+
+free_iovs:
+ list_for_each_entry_safe(lazy_iov, n, &lpi->iovs, l)
+ xfree(lazy_iov);
+
+ return -1;
+}
+
static struct lazy_pages_info *ud_open(int client)
{
struct lazy_pages_info *lpi;
@@ -353,6 +400,12 @@ static struct lazy_pages_info *ud_open(int client)
hlist_add_head(&lpi->hash, &lpi_hash[lpi->uffd % LPI_HASH_SIZE]);
+ ret = collect_lazy_iovecs(lpi);
+ if (ret != lpi->total_pages) {
+ pr_err("collect_lazy_iovecs=%d\n", ret);
+ goto out;
+ }
+
return lpi;
out:
--
1.9.1
More information about the CRIU
mailing list