mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-03 23:33:01 +00:00
criu: add ability to skip writing lazy pages
When appropriate, the lazy pages will no be written to the destination. Instead, a pagemap entry for range of such pages will be marked with 'lazy' flag. Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
a1ed9e0992
commit
a9a973da77
10 changed files with 31 additions and 11 deletions
|
|
@ -1483,7 +1483,7 @@ static int cr_pre_dump_finish(int ret)
|
|||
goto err;
|
||||
|
||||
mem_pp = dmpi(item)->mem_pp;
|
||||
ret = page_xfer_dump_pages(&xfer, mem_pp, 0);
|
||||
ret = page_xfer_dump_pages(&xfer, mem_pp, 0, true);
|
||||
|
||||
xfer.close(&xfer);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ struct page_xfer {
|
|||
extern int open_page_xfer(struct page_xfer *xfer, int fd_type, long id);
|
||||
struct page_pipe;
|
||||
extern int page_xfer_dump_pages(struct page_xfer *, struct page_pipe *,
|
||||
unsigned long off);
|
||||
unsigned long off, bool dump_lazy);
|
||||
extern int connect_to_page_server(void);
|
||||
extern int disconnect_from_page_server(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ enum {
|
|||
CNT_PAGES_SKIPPED_PARENT,
|
||||
CNT_PAGES_WRITTEN,
|
||||
CNT_PAGES_ZERO,
|
||||
CNT_PAGES_LAZY,
|
||||
|
||||
DUMP_CNT_NR_STATS,
|
||||
};
|
||||
|
|
|
|||
16
criu/mem.c
16
criu/mem.c
|
|
@ -143,7 +143,7 @@ static int generate_iovs(struct vma_area *vma, struct page_pipe *pp, u64 *map, u
|
|||
{
|
||||
u64 *at = &map[PAGE_PFN(*off)];
|
||||
unsigned long pfn, nr_to_scan;
|
||||
unsigned long pages[3] = {};
|
||||
unsigned long pages[4] = {};
|
||||
|
||||
nr_to_scan = (vma_area_len(vma) - *off) / PAGE_SIZE;
|
||||
|
||||
|
|
@ -175,7 +175,10 @@ static int generate_iovs(struct vma_area *vma, struct page_pipe *pp, u64 *map, u
|
|||
pages[1]++;
|
||||
} else {
|
||||
ret = page_pipe_add_page(pp, vaddr, ppb_flags);
|
||||
pages[2]++;
|
||||
if (ppb_flags & PPB_LAZY)
|
||||
pages[2]++;
|
||||
else
|
||||
pages[3]++;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
|
|
@ -189,10 +192,11 @@ static int generate_iovs(struct vma_area *vma, struct page_pipe *pp, u64 *map, u
|
|||
cnt_add(CNT_PAGES_SCANNED, nr_to_scan);
|
||||
cnt_add(CNT_PAGES_ZERO, pages[0]);
|
||||
cnt_add(CNT_PAGES_SKIPPED_PARENT, pages[1]);
|
||||
cnt_add(CNT_PAGES_WRITTEN, pages[2]);
|
||||
cnt_add(CNT_PAGES_LAZY, pages[2]);
|
||||
cnt_add(CNT_PAGES_WRITTEN, pages[3]);
|
||||
|
||||
pr_info("Pagemap generated: %lu pages %lu holes %lu zeros\n",
|
||||
pages[2], pages[1], pages[0]);
|
||||
pr_info("Pagemap generated: %lu pages (%lu lazy) %lu holes %lu zeros\n",
|
||||
pages[3] + pages[2], pages[2], pages[1], pages[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -272,7 +276,7 @@ static int xfer_pages(struct page_pipe *pp, struct page_xfer *xfer)
|
|||
* pre-dump action (see pre_dump_one_task)
|
||||
*/
|
||||
timing_start(TIME_MEMWRITE);
|
||||
ret = page_xfer_dump_pages(xfer, pp, 0);
|
||||
ret = page_xfer_dump_pages(xfer, pp, 0, true);
|
||||
timing_stop(TIME_MEMWRITE);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ static void psi2iovec(struct page_server_iov *ps, struct iovec *iov)
|
|||
#define PS_IOV_OPEN2 4
|
||||
#define PS_IOV_PARENT 5
|
||||
#define PS_IOV_ZERO 6
|
||||
#define PS_IOV_LAZY 7
|
||||
|
||||
#define PS_IOV_FLUSH 0x1023
|
||||
#define PS_IOV_FLUSH_N_CLOSE 0x1024
|
||||
|
|
@ -305,6 +306,10 @@ static int write_hole_loc(struct page_xfer *xfer, struct iovec *iov, int type)
|
|||
pe.has_zero = true;
|
||||
pe.zero = true;
|
||||
break;
|
||||
case PS_IOV_LAZY:
|
||||
pe.has_lazy = true;
|
||||
pe.lazy = true;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -439,7 +444,7 @@ static int dump_holes(struct page_xfer *xfer, struct page_pipe *pp,
|
|||
}
|
||||
|
||||
int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
|
||||
unsigned long off)
|
||||
unsigned long off, bool dump_lazy)
|
||||
{
|
||||
struct page_pipe_buf *ppb;
|
||||
unsigned int cur_hole = 0;
|
||||
|
|
@ -464,6 +469,12 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
|
|||
pr_debug("\tp %p [%u]\n", iov.iov_base,
|
||||
(unsigned int)(iov.iov_len / PAGE_SIZE));
|
||||
|
||||
if (!dump_lazy && ppb->flags & PPB_LAZY) {
|
||||
if (xfer->write_hole(xfer, &iov, PS_IOV_LAZY))
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xfer->write_pagemap(xfer, &iov))
|
||||
return -1;
|
||||
if (xfer->write_pages(xfer, ppb->p[0], iov.iov_len))
|
||||
|
|
@ -740,6 +751,7 @@ static int page_server_serve(int sk)
|
|||
break;
|
||||
case PS_IOV_HOLE:
|
||||
case PS_IOV_ZERO:
|
||||
case PS_IOV_LAZY:
|
||||
ret = page_server_hole(sk, &pi);
|
||||
break;
|
||||
case PS_IOV_FLUSH:
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len)
|
|||
if (!len)
|
||||
return;
|
||||
|
||||
if (!pr->pe->in_parent && !pr->pe->zero)
|
||||
if (!pr->pe->in_parent && !pr->pe->zero && !pr->pe->lazy)
|
||||
pr->pi_off += len;
|
||||
pr->cvaddr += len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ static int dump_pages(struct page_pipe *pp, struct page_xfer *xfer, void *addr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
return page_xfer_dump_pages(xfer, pp, (unsigned long)addr);
|
||||
return page_xfer_dump_pages(xfer, pp, (unsigned long)addr, true);
|
||||
}
|
||||
|
||||
static int next_data_segment(int fd, unsigned long pfn,
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ void write_stats(int what)
|
|||
ds_entry.pages_skipped_parent = dstats->counts[CNT_PAGES_SKIPPED_PARENT];
|
||||
ds_entry.pages_written = dstats->counts[CNT_PAGES_WRITTEN];
|
||||
ds_entry.pages_zero = dstats->counts[CNT_PAGES_ZERO];
|
||||
ds_entry.pages_lazy = dstats->counts[CNT_PAGES_LAZY];
|
||||
|
||||
name = "dump";
|
||||
} else if (what == RESTORE_STATS) {
|
||||
|
|
|
|||
|
|
@ -11,4 +11,5 @@ message pagemap_entry {
|
|||
required uint32 nr_pages = 2;
|
||||
optional bool in_parent = 3;
|
||||
optional bool zero = 4;
|
||||
optional bool lazy = 5;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ message dump_stats_entry {
|
|||
optional uint32 irmap_resolve = 8;
|
||||
|
||||
required uint64 pages_zero = 9;
|
||||
required uint64 pages_lazy = 10;
|
||||
}
|
||||
|
||||
message restore_stats_entry {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue