Commit 2986751d authored by Fyodor Bocharov's avatar Fyodor Bocharov Committed by Pavel Emelyanov

shmem: dump anon shared memory pages according to their PME derived states

This allows us not to dump anon shmem pages that weren't changed since
last dump. We dump each anon shmem vma using page-xfer. page-xfer does all
magic with storing "in_parent" field in pagemap-entry.
When restoring we simply read every page with page-read and it does
all magic of reading from right place in image hierarchy.
auto-dedup on restore is already implemented by page-read so we don't need
to code it.
Signed-off-by: 's avatarFyodor Bocharov <fbocharov@yandex.ru>
Signed-off-by: 's avatarEugene Batalov <eabatalov89@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 0ddfaa9b
...@@ -605,17 +605,11 @@ static int dump_one_shmem(struct shmem_info *si) ...@@ -605,17 +605,11 @@ static int dump_one_shmem(struct shmem_info *si)
struct page_pipe *pp; struct page_pipe *pp;
struct page_xfer xfer; struct page_xfer xfer;
int err, ret = -1, fd; int err, ret = -1, fd;
unsigned char *map = NULL;
void *addr = NULL; void *addr = NULL;
unsigned long pfn, nrpages; unsigned long pfn, nrpages;
pr_info("Dumping shared memory %ld\n", si->shmid); 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); fd = open_proc(si->pid, "map_files/%lx-%lx", si->start, si->end);
if (fd < 0) if (fd < 0)
goto err; goto err;
...@@ -628,17 +622,7 @@ static int dump_one_shmem(struct shmem_info *si) ...@@ -628,17 +622,7 @@ static int dump_one_shmem(struct shmem_info *si)
goto err; goto err;
} }
/* nrpages = (si->size + PAGE_SIZE - 1) / PAGE_SIZE;
* 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;
pp = create_page_pipe((nrpages + 1) / 2, NULL, PP_CHUNK_MODE); pp = create_page_pipe((nrpages + 1) / 2, NULL, PP_CHUNK_MODE);
if (!pp) if (!pp)
goto err_unmap; goto err_unmap;
...@@ -648,10 +632,20 @@ static int dump_one_shmem(struct shmem_info *si) ...@@ -648,10 +632,20 @@ static int dump_one_shmem(struct shmem_info *si)
goto err_pp; goto err_pp;
for (pfn = 0; pfn < nrpages; pfn++) { for (pfn = 0; pfn < nrpages; pfn++) {
if (!(map[pfn] & PAGE_RSS)) unsigned int pgstate;
unsigned long pgaddr;
pgstate = get_pstate(si->pstate_map, pfn);
if (pgstate == PST_DONT_DUMP)
continue; continue;
pgaddr = (unsigned long)addr + pfn * PAGE_SIZE;
again: again:
ret = page_pipe_add_page(pp, (unsigned long)addr + pfn * PAGE_SIZE); if (xfer.parent && page_in_parent(pgstate == PST_DIRTY))
ret = page_pipe_add_hole(pp, pgaddr);
else /* pgstate == PST_DUMP */
ret = page_pipe_add_page(pp, pgaddr);
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
ret = dump_pages(pp, &xfer, addr); ret = dump_pages(pp, &xfer, addr);
if (ret) if (ret)
...@@ -671,7 +665,6 @@ err_pp: ...@@ -671,7 +665,6 @@ err_pp:
err_unmap: err_unmap:
munmap(addr, si->size); munmap(addr, si->size);
err: err:
xfree(map);
return ret; return ret;
} }
......
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