[CRIU] [PATCH 10/11] vma: Mark cow roots
Pavel Emelyanov
xemul at virtuozzo.com
Fri May 5 09:04:05 PDT 2017
Next patch will stop premapping some private vmas. In particular -- those,
that are not COW-ed with anyone. To make this work we need to distinguish
vmas that are not cowed with anyone from those cowed with children only.
Currently both have vma->parent pointer set to NULL, so for former let's
introduce the special mark.
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/include/vma.h | 2 ++
criu/mem.c | 16 ++++++++++++----
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/criu/include/vma.h b/criu/include/vma.h
index de8b411..c941890 100644
--- a/criu/include/vma.h
+++ b/criu/include/vma.h
@@ -72,6 +72,8 @@ struct vma_area {
};
};
+#define VMA_COW_ROOT ((struct vma_area *)1)
+
typedef int (*dump_filemap_t)(struct vma_area *vma_area, int fd);
extern struct vma_area *alloc_vma_area(void);
diff --git a/criu/mem.c b/criu/mem.c
index e8ca093..fe62b41 100644
--- a/criu/mem.c
+++ b/criu/mem.c
@@ -581,6 +581,11 @@ static inline bool check_cow_vmas(struct vma_area *vma, struct vma_area *pvma)
return true;
}
+static inline bool vma_inherited(struct vma_area *vma)
+{
+ return (vma->pvma != NULL && vma->pvma != VMA_COW_ROOT);
+}
+
static void prepare_cow_vmas_for(struct vm_area_list *vmas, struct vm_area_list *pvmas)
{
struct vma_area *vma, *pvma;
@@ -589,8 +594,11 @@ static void prepare_cow_vmas_for(struct vm_area_list *vmas, struct vm_area_list
pvma = list_first_entry(&pvmas->h, struct vma_area, list);
while (1) {
- if ((vma->e->start == pvma->e->start) && check_cow_vmas(vma, pvma))
+ if ((vma->e->start == pvma->e->start) && check_cow_vmas(vma, pvma)) {
vma->pvma = pvma;
+ if (pvma->pvma == NULL)
+ pvma->pvma = VMA_COW_ROOT;
+ }
/* <= here to shift from matching VMAs and ... */
while (vma->e->start <= pvma->e->start) {
@@ -659,7 +667,7 @@ static int premap_private_vma(struct pstree_item *t, struct vma_area *vma, void
vma->e->start -= PAGE_SIZE;
size = vma_entry_len(vma->e);
- if (vma->pvma == NULL) {
+ if (!vma_inherited(vma)) {
int flag = 0;
/*
* The respective memory area was NOT found in the parent.
@@ -834,7 +842,7 @@ static int restore_priv_vma_content(struct pstree_item *t, struct page_read *pr)
vma->premmaped_addr);
set_bit(off, vma->page_bitmap);
- if (vma->pvma) { /* inherited vma */
+ if (vma_inherited(vma)) {
clear_bit(off, vma->pvma->page_bitmap);
ret = pr->read_pages(pr, va, 1, buf, 0);
@@ -892,7 +900,7 @@ err_read:
unsigned long size, i = 0;
void *addr = decode_pointer(vma->premmaped_addr);
- if (vma->pvma == NULL)
+ if (!vma_inherited(vma))
continue;
size = vma_entry_len(vma->e) / PAGE_SIZE;
--
2.5.5
More information about the CRIU
mailing list