[CRIU] [PATCHv0 7/8] shmem: implement anon shared memory autodedup
Pavel Emelyanov
xemul at parallels.com
Tue Dec 8 04:59:50 PST 2015
> @@ -386,23 +374,29 @@ static int dump_pages(struct page_pipe *pp, struct page_xfer *xfer, void *addr)
> return page_xfer_dump_pages(xfer, pp, (unsigned long)addr);
> }
>
> +/* Implementation comes from mem.c */
> +
> +static inline bool page_in_parent(unsigned long dirty)
> +{
> + /*
> + * If we do memory tracking, but w/o parent images,
> + * then we have to dump all memory
> + */
> +
> + return opts.track_mem && opts.img_parent && !dirty;
> +}
Don't copy code, better put this into include/mem.h
> +
> static int dump_one_shmem(struct shmem_info_dump *si)
> {
> struct iovec *iovs;
> struct page_pipe *pp;
> struct page_xfer xfer;
> int err, ret = -1, fd;
> - unsigned char *map = NULL;
> void *addr = NULL;
> unsigned long pfn, nrpages;
>
> pr_info("Dumping shared memory %ld\n", si->shmid);
>
> - nrpages = (si->size + PAGE_SIZE - 1) / PAGE_SIZE;
> - map = xmalloc(nrpages * sizeof(*map));
> - if (!map)
> - goto err;
> -
> fd = open_proc(si->pid, "map_files/%lx-%lx", si->start, si->end);
> if (fd < 0)
> goto err;
> @@ -415,17 +409,7 @@ static int dump_one_shmem(struct shmem_info_dump *si)
> goto err;
> }
>
> - /*
> - * We can't use pagemap here, because this vma is
> - * not mapped to us at all, but mincore reports the
> - * pagecache status of a file, which is correct in
> - * this case.
> - */
> -
> - err = mincore(addr, si->size, map);
> - if (err)
> - goto err_unmap;
> -
> + nrpages = BLOCKS_CNT(si->size, PAGE_SIZE);
> iovs = xmalloc(((nrpages + 1) / 2) * sizeof(struct iovec));
> if (!iovs)
> goto err_unmap;
> @@ -439,10 +423,13 @@ static int dump_one_shmem(struct shmem_info_dump *si)
> goto err_pp;
>
> for (pfn = 0; pfn < nrpages; pfn++) {
> - if (!(map[pfn] & PAGE_RSS))
> - continue;
> + unsigned long dirty = test_bit(pfn, si->pdirty_map);
> again:
> - ret = page_pipe_add_page(pp, (unsigned long)addr + pfn * PAGE_SIZE);
> + if (xfer.parent && page_in_parent(dirty))
> + ret = page_pipe_add_hole(pp, (unsigned long)addr + pfn * PAGE_SIZE);
> + else
> + ret = page_pipe_add_page(pp, (unsigned long)addr + pfn * PAGE_SIZE);
> +
> if (ret == -EAGAIN) {
> ret = dump_pages(pp, &xfer, addr);
> if (ret)
> @@ -464,7 +451,6 @@ err_iovs:
> err_unmap:
> munmap(addr, si->size);
> err:
> - xfree(map);
> return ret;
> }
>
>
More information about the CRIU
mailing list