[CRIU] [RFC 3/3] mem: Start using pagemap cache
Cyrill Gorcunov
gorcunov at openvz.org
Thu Feb 13 12:41:13 PST 2014
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
mem.c | 49 ++++++++++++++++++++-----------------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/mem.c b/mem.c
index 2c2717d290d6..a4d22bdf19a3 100644
--- a/mem.c
+++ b/mem.c
@@ -19,6 +19,7 @@
#include "pstree.h"
#include "restorer.h"
#include "files-reg.h"
+#include "pagemap-cache.h"
#include "protobuf.h"
#include "protobuf/pagemap.pb-c.h"
@@ -105,28 +106,27 @@ static inline bool page_in_parent(u64 pme)
* the memory contents is present in the pagent image set.
*/
-static int generate_iovs(struct vma_area *vma, int pagemap,
- struct page_pipe *pp, u64 *map, u64 *off)
+static int generate_iovs(pmc_t *pmc, struct vma_area *vma,
+ struct page_pipe *pp, u64 *off)
{
- unsigned long pfn, nr_to_scan;
+ unsigned long nr_to_scan;
unsigned long pages[2] = {};
unsigned long vaddr = *off;
- u64 from, len;
+ u64 pme;
- nr_to_scan = (vma->e->end - vaddr) / PAGE_SIZE;
- from = vaddr / PAGE_SIZE * sizeof(*map);
- len = nr_to_scan * sizeof(*map);
- if (pread(pagemap, map, len, from) != len) {
- pr_perror("Can't read pagemap file");
- return -1;
- }
+ nr_to_scan = PAGEMAP_PFN(vma->e->end - vaddr);
for ( ; vaddr < vma->e->end; vaddr += PAGE_SIZE) {
int ret;
- pfn = (vaddr - vma->e->start) / PAGE_SIZE;
+ pme = pmc_get_pme(pmc, vma, vaddr);
+ if (pme == PAGEMAP_PME_ERR) {
+ pr_err("Failed obtain PME for %p\n", (void *)vaddr);
+ *off = vaddr;
+ return -1;
+ }
- if (!should_dump_page(vma->e, map[pfn]))
+ if (!should_dump_page(vma->e, pme))
continue;
/*
@@ -136,7 +136,7 @@ static int generate_iovs(struct vma_area *vma, int pagemap,
* page. The latter would be checked in page-xfer.
*/
- if (page_in_parent(map[pfn])) {
+ if (page_in_parent(pme)) {
ret = page_pipe_add_hole(pp, vaddr);
pages[0]++;
} else {
@@ -236,8 +236,7 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
struct vm_area_list *vma_area_list,
struct page_pipe **pp_ret)
{
- u64 *map;
- int pagemap;
+ pmc_t pmc = PMC_INIT;
struct page_pipe *pp;
struct vma_area *vma_area;
struct page_xfer xfer;
@@ -258,19 +257,14 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
* Step 0 -- prepare
*/
- map = xmalloc(vma_area_list->longest * sizeof(*map));
- if (!map)
- goto out;
-
- ret = pagemap = open_proc(ctl->pid.real, "pagemap");
- if (ret < 0)
- goto out_free;
+ if (pmc_init(&pmc, ctl->pid.real, &vma_area_list->h, vma_area_list->longest))
+ return -1;
ret = -1;
pp = create_page_pipe(vma_area_list->priv_size / 2,
pargs_iovs(args), pp_ret == NULL);
if (!pp)
- goto out_close;
+ goto out;
if (pp_ret == NULL) {
ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, ctl->pid.virt);
@@ -288,7 +282,7 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
if (!privately_dump_vma(vma_area))
continue;
again:
- ret = generate_iovs(vma_area, pagemap, pp, map, &off);
+ ret = generate_iovs(&pmc, vma_area, pp, &off);
if (ret == -EAGAIN) {
BUG_ON(pp_ret);
@@ -322,11 +316,8 @@ out_xfer:
out_pp:
if (ret || !pp_ret)
destroy_page_pipe(pp);
-out_close:
- close(pagemap);
-out_free:
- xfree(map);
out:
+ pmc_fini(&pmc);
pr_info("----------------------------------------\n");
return ret;
}
--
1.8.3.1
More information about the CRIU
mailing list