Commit 9bc9fcb0 authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

criu: pagemap: replace 'zero' and 'lazy' booleans with 'flags'

Having three booleans in pagemap entry clues for usage of good old flags.
Replace 'zero' and 'lazy' booleans with flags and use flags for internal
tracking of in_parent value. Eventually, in_parent may be deprecated.
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent b711f89c
...@@ -89,7 +89,7 @@ static int cr_dedup_one_pagemap(int id, int flags) ...@@ -89,7 +89,7 @@ static int cr_dedup_one_pagemap(int id, int flags)
pr_debug("dedup iovec base=%"PRIx64", len=%lu\n", pr_debug("dedup iovec base=%"PRIx64", len=%lu\n",
pr.pe->vaddr, pagemap_len(pr.pe)); pr.pe->vaddr, pagemap_len(pr.pe));
if (!pr.pe->in_parent) { if (!pagemap_in_parent(pr.pe)) {
ret = dedup_one_iovec(prp, pr.pe->vaddr, ret = dedup_one_iovec(prp, pr.pe->vaddr,
pagemap_len(pr.pe)); pagemap_len(pr.pe));
if (ret) if (ret)
......
...@@ -113,4 +113,25 @@ static inline unsigned long pagemap_len(PagemapEntry *pe) ...@@ -113,4 +113,25 @@ static inline unsigned long pagemap_len(PagemapEntry *pe)
{ {
return pe->nr_pages * PAGE_SIZE; return pe->nr_pages * PAGE_SIZE;
} }
/* Pagemap flags */
#define PE_PARENT (1 << 0) /* pages are in parent snapshot */
#define PE_ZERO (1 << 1) /* pages can be lazily restored */
#define PE_LAZY (1 << 2) /* pages are mapped to zero pfn */
static inline bool pagemap_in_parent(PagemapEntry *pe)
{
return !!(pe->flags & PE_PARENT);
}
static inline bool pagemap_zero(PagemapEntry *pe)
{
return !!(pe->flags & PE_ZERO);
}
static inline bool pagemap_lazy(PagemapEntry *pe)
{
return !!(pe->flags & PE_LAZY);
}
#endif /* __CR_PAGE_READ_H__ */ #endif /* __CR_PAGE_READ_H__ */
...@@ -205,6 +205,7 @@ static int write_pagemap_loc(struct page_xfer *xfer, ...@@ -205,6 +205,7 @@ static int write_pagemap_loc(struct page_xfer *xfer,
pe.vaddr = encode_pointer(iov->iov_base); pe.vaddr = encode_pointer(iov->iov_base);
pe.nr_pages = iov->iov_len / PAGE_SIZE; pe.nr_pages = iov->iov_len / PAGE_SIZE;
pe.has_flags = true;
if (opts.auto_dedup && xfer->parent != NULL) { if (opts.auto_dedup && xfer->parent != NULL) {
ret = dedup_one_iovec(xfer->parent, pe.vaddr, ret = dedup_one_iovec(xfer->parent, pe.vaddr,
pagemap_len(&pe)); pagemap_len(&pe));
...@@ -288,6 +289,7 @@ static int write_hole_loc(struct page_xfer *xfer, struct iovec *iov, int type) ...@@ -288,6 +289,7 @@ static int write_hole_loc(struct page_xfer *xfer, struct iovec *iov, int type)
pe.vaddr = encode_pointer(iov->iov_base); pe.vaddr = encode_pointer(iov->iov_base);
pe.nr_pages = iov->iov_len / PAGE_SIZE; pe.nr_pages = iov->iov_len / PAGE_SIZE;
pe.has_flags = true;
switch (type) { switch (type) {
case PS_IOV_HOLE: case PS_IOV_HOLE:
...@@ -301,17 +303,13 @@ static int write_hole_loc(struct page_xfer *xfer, struct iovec *iov, int type) ...@@ -301,17 +303,13 @@ static int write_hole_loc(struct page_xfer *xfer, struct iovec *iov, int type)
return -1; return -1;
} }
} }
pe.flags |= PE_PARENT;
pe.has_in_parent = true;
pe.in_parent = true;
break; break;
case PS_IOV_ZERO: case PS_IOV_ZERO:
pe.has_zero = true; pe.flags |= PE_ZERO;
pe.zero = true;
break; break;
case PS_IOV_LAZY: case PS_IOV_LAZY:
pe.has_lazy = true; pe.flags |= PE_LAZY;
pe.lazy = true;
break; break;
default: default:
return -1; return -1;
......
...@@ -96,7 +96,7 @@ int dedup_one_iovec(struct page_read *pr, unsigned long off, unsigned long len) ...@@ -96,7 +96,7 @@ int dedup_one_iovec(struct page_read *pr, unsigned long off, unsigned long len)
if (!pr->pe) if (!pr->pe)
return -1; return -1;
piov_end = pr->pe->vaddr + pagemap_len(pr->pe); piov_end = pr->pe->vaddr + pagemap_len(pr->pe);
if (!pr->pe->in_parent) { if (!pagemap_in_parent(pr->pe)) {
ret = punch_hole(pr, pr->pi_off, min(piov_end, iov_end) - off, false); ret = punch_hole(pr, pr->pi_off, min(piov_end, iov_end) - off, false);
if (ret == -1) if (ret == -1)
return ret; return ret;
...@@ -130,7 +130,7 @@ static int advance(struct page_read *pr) ...@@ -130,7 +130,7 @@ static int advance(struct page_read *pr)
pe = pr->pmes[pr->curr_pme]; pe = pr->pmes[pr->curr_pme];
if (!pe->zero) if (!pagemap_zero(pe))
break; break;
} }
...@@ -144,7 +144,7 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len) ...@@ -144,7 +144,7 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len)
if (!len) if (!len)
return; return;
if (!pr->pe->in_parent && !pr->pe->zero && !pr->pe->lazy) if (!pagemap_in_parent(pr->pe) && !pagemap_zero(pr->pe) && !pagemap_lazy(pr->pe))
pr->pi_off += len; pr->pi_off += len;
pr->cvaddr += len; pr->cvaddr += len;
} }
...@@ -415,10 +415,10 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr, ...@@ -415,10 +415,10 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
pr_info("pr%u Read %lx %u pages\n", pr->id, vaddr, nr); pr_info("pr%u Read %lx %u pages\n", pr->id, vaddr, nr);
pagemap_bound_check(pr->pe, vaddr, nr); pagemap_bound_check(pr->pe, vaddr, nr);
if (pr->pe->in_parent) { if (pagemap_in_parent(pr->pe)) {
if (read_parent_page(pr, vaddr, nr, buf, flags) < 0) if (read_parent_page(pr, vaddr, nr, buf, flags) < 0)
return -1; return -1;
} else if (pr->pe->zero) { } else if (pagemap_zero(pr->pe)) {
/* zero mappings should be skipped by get_pagemap */ /* zero mappings should be skipped by get_pagemap */
BUG(); BUG();
} else { } else {
...@@ -603,6 +603,12 @@ err_cl: ...@@ -603,6 +603,12 @@ err_cl:
return -1; return -1;
} }
static void init_compat_pagemap_entry(PagemapEntry *pe)
{
if (pe->has_in_parent && pe->in_parent)
pe->flags |= PE_PARENT;
}
/* /*
* The pagemap entry size is at least 8 bytes for small mappings with * The pagemap entry size is at least 8 bytes for small mappings with
* low address and may get to 18 bytes or even more for large mappings * low address and may get to 18 bytes or even more for large mappings
...@@ -638,6 +644,8 @@ static int init_pagemaps(struct page_read *pr) ...@@ -638,6 +644,8 @@ static int init_pagemaps(struct page_read *pr)
if (ret == 0) if (ret == 0)
break; break;
init_compat_pagemap_entry(pr->pmes[pr->nr_pmes]);
pr->nr_pmes++; pr->nr_pmes++;
if (pr->nr_pmes >= nr_pmes) { if (pr->nr_pmes >= nr_pmes) {
nr_pmes += nr_realloc; nr_pmes += nr_realloc;
......
...@@ -371,7 +371,7 @@ static int get_page(struct lazy_pages_info *lpi, unsigned long addr, void *dest) ...@@ -371,7 +371,7 @@ static int get_page(struct lazy_pages_info *lpi, unsigned long addr, void *dest)
if (ret <= 0) if (ret <= 0)
return ret; return ret;
if (lpi->pr.pe->zero) if (pagemap_zero(lpi->pr.pe))
return 0; return 0;
ret = lpi->pr.read_pages(&lpi->pr, addr, 1, buf, 0); ret = lpi->pr.read_pages(&lpi->pr, addr, 1, buf, 0);
......
...@@ -10,6 +10,5 @@ message pagemap_entry { ...@@ -10,6 +10,5 @@ message pagemap_entry {
required uint64 vaddr = 1 [(criu).hex = true]; required uint64 vaddr = 1 [(criu).hex = true];
required uint32 nr_pages = 2; required uint32 nr_pages = 2;
optional bool in_parent = 3; optional bool in_parent = 3;
optional bool zero = 4; optional uint32 flags = 4 [(criu).hex = true];
optional bool lazy = 5;
} }
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