[CRIU] [RFC PATCH 03/16] criu: lazy-pages: introduce collect_lazy_iovecs
Pavel Emelyanov
xemul at virtuozzo.com
Wed Oct 5 06:05:58 PDT 2016
On 09/27/2016 04:42 PM, Mike Rapoport wrote:
> 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)) {
This place looks like it wanted to do pr->get_pagemap(), but for
some reason it doesn't :) Why?
> + 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:
>
More information about the CRIU
mailing list