Commit 94c6d773 authored by Pavel Emelyanov's avatar Pavel Emelyanov

shmem: Split shmem dumping code into two

Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 9486946b
...@@ -291,92 +291,83 @@ int add_shmem_area(pid_t pid, VmaEntry *vma) ...@@ -291,92 +291,83 @@ int add_shmem_area(pid_t pid, VmaEntry *vma)
return 0; return 0;
} }
#define for_each_shmem_dump(_i, _si) \ static int dump_one_shmem(struct shmem_info_dump *si)
for (i = 0; i < SHMEM_HASH_SIZE; i++) \
for (si = shmems_hash[i]; si; si = si->next)
int cr_dump_shmem(void)
{ {
int i, err, fd, fd_pg; PagemapEntry pe = PAGEMAP_ENTRY__INIT;
int err, fd, fd_pg;
unsigned char *map = NULL; unsigned char *map = NULL;
void *addr = NULL; void *addr = NULL;
struct shmem_info_dump *si;
unsigned long pfn, nrpages; unsigned long pfn, nrpages;
for_each_shmem_dump (i, si) { pr_info("Dumping shared memory 0x%lx\n", si->shmid);
PagemapEntry pe = PAGEMAP_ENTRY__INIT;
pr_info("Dumping shared memory 0x%lx\n", si->shmid); nrpages = (si->size + PAGE_SIZE - 1) / PAGE_SIZE;
map = xmalloc(nrpages * sizeof(*map));
if (!map)
goto err;
nrpages = (si->size + PAGE_SIZE - 1) / PAGE_SIZE; fd = open_proc(si->pid, "map_files/%lx-%lx", si->start, si->end);
map = xmalloc(nrpages * sizeof(*map)); if (fd < 0)
if (!map) goto err;
goto err;
fd = open_proc(si->pid, "map_files/%lx-%lx", si->start, si->end);
if (fd < 0)
goto err;
addr = mmap(NULL, si->size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
if (addr == MAP_FAILED) {
pr_err("Can't map shmem 0x%lx (0x%lx-0x%lx)\n",
si->shmid, si->start, si->end);
goto err;
}
/* addr = mmap(NULL, si->size, PROT_READ, MAP_SHARED, fd, 0);
* We can't use pagemap here, because this vma is close(fd);
* not mapped to us at all, but mincore reports the if (addr == MAP_FAILED) {
* pagecache status of a file, which is correct in pr_err("Can't map shmem 0x%lx (0x%lx-0x%lx)\n",
* this case. si->shmid, si->start, si->end);
*/ goto err;
}
err = mincore(addr, si->size, map); /*
if (err) * We can't use pagemap here, because this vma is
goto err_unmap; * not mapped to us at all, but mincore reports the
* pagecache status of a file, which is correct in
* this case.
*/
fd = open_image(CR_FD_SHMEM_PAGEMAP, O_DUMP, si->shmid); err = mincore(addr, si->size, map);
if (fd < 0) if (err)
goto err_unmap; goto err_unmap;
fd_pg = open_pages_image(O_DUMP, fd); fd = open_image(CR_FD_SHMEM_PAGEMAP, O_DUMP, si->shmid);
if (fd_pg < 0) if (fd < 0)
goto err_close; goto err_unmap;
pe.nr_pages = 0; fd_pg = open_pages_image(O_DUMP, fd);
for (pfn = 0; pfn < nrpages; pfn++) { if (fd_pg < 0)
u64 offset = pfn * PAGE_SIZE; goto err_close;
if (map[pfn] & PAGE_RSS) { pe.nr_pages = 0;
if (!pe.nr_pages) for (pfn = 0; pfn < nrpages; pfn++) {
pe.vaddr = offset; u64 offset = pfn * PAGE_SIZE;
pe.nr_pages++;
if (pfn + 1 < nrpages)
continue;
}
if (map[pfn] & PAGE_RSS) {
if (!pe.nr_pages) if (!pe.nr_pages)
pe.vaddr = offset;
pe.nr_pages++;
if (pfn + 1 < nrpages)
continue; continue;
if (pb_write_one(fd, &pe, PB_PAGEMAP))
break;
if (write(fd_pg, addr + pe.vaddr, pe.nr_pages * PAGE_SIZE) !=
pe.nr_pages * PAGE_SIZE)
break;
pe.nr_pages = 0;
} }
if (pfn != nrpages) if (!pe.nr_pages)
goto err_close2; continue;
close(fd_pg); if (pb_write_one(fd, &pe, PB_PAGEMAP))
close(fd); break;
munmap(addr, si->size); if (write(fd_pg, addr + pe.vaddr, pe.nr_pages * PAGE_SIZE) !=
xfree(map); pe.nr_pages * PAGE_SIZE)
break;
pe.nr_pages = 0;
} }
if (pfn != nrpages)
goto err_close2;
close(fd_pg);
close(fd);
munmap(addr, si->size);
xfree(map);
return 0; return 0;
err_close2: err_close2:
...@@ -389,3 +380,21 @@ err: ...@@ -389,3 +380,21 @@ err:
xfree(map); xfree(map);
return -1; return -1;
} }
#define for_each_shmem_dump(_i, _si) \
for (i = 0; i < SHMEM_HASH_SIZE; i++) \
for (si = shmems_hash[i]; si; si = si->next)
int cr_dump_shmem(void)
{
int ret = 0, i;
struct shmem_info_dump *si;
for_each_shmem_dump (i, si) {
ret = dump_one_shmem(si);
if (ret)
break;
}
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