[CRIU] [PATCH v1] shmem: don't use anon shmem changes tracking by default
Eugene Batalov
eabatalov89 at gmail.com
Tue Sep 27 05:21:30 PDT 2016
Anon shmem changes tracking has known bugs.
So don't use it by default. Enable it only when
CRIU_TRACK_SHMEM env variable is defined.
Now we can run transition/shmem test in CI because it works:
python test/zdtm.py run -t zdtm/transition/shmem --pre 3
Cc: Andrei Vagin <avagin at virtuozzo.com>
Cc: Pavel Emelyanov <xemul at virtuozzo.com>
Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com>
---
criu/shmem.c | 49 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 41 insertions(+), 8 deletions(-)
diff --git a/criu/shmem.c b/criu/shmem.c
index 341e3bc..9f4c147 100644
--- a/criu/shmem.c
+++ b/criu/shmem.c
@@ -2,6 +2,7 @@
#include <sys/mman.h>
#include <stdlib.h>
#include <fcntl.h>
+#include <stdbool.h>
#include "list.h"
#include "pid.h"
@@ -17,6 +18,7 @@
#include "config.h"
#include "syscall-codes.h"
#include "asm/bitops.h"
+#include "criu-log.h"
#include "protobuf.h"
#include "images/pagemap.pb-c.h"
@@ -131,6 +133,26 @@ static struct shmem_info *shmem_find(unsigned long shmid)
#define PST_BIT0_IX(pfn) ((pfn) * PST_BITS)
#define PST_BIT1_IX(pfn) (PST_BIT0_IX(pfn) + 1)
+/*
+ * Disable pagemap based shmem changes tracking by default
+ * because it has bugs in implementation -
+ * process can map shmem page, change it and unmap it.
+ * We won't observe any changes in such pagemaps during dump.
+ */
+static bool is_shmem_tracking_en(void)
+{
+ static bool is_inited = false;
+ static bool is_enabled = false;
+
+ if (!is_inited) {
+ is_enabled = (bool)getenv("CRIU_TRACK_SHMEM");
+ is_inited = true;
+ if (is_enabled)
+ pr_msg("Turn anon shmem tracking on via env\n");
+ }
+ return is_enabled;
+}
+
static unsigned int get_pstate(unsigned long *pstate_map, unsigned long pfn)
{
unsigned int bit0 = test_bit(PST_BIT0_IX(pfn), pstate_map) ? 1 : 0;
@@ -150,9 +172,14 @@ static void set_pstate(unsigned long *pstate_map, unsigned long pfn,
static int expand_shmem(struct shmem_info *si, unsigned long new_size)
{
unsigned long nr_pages, nr_map_items, map_size,
- nr_new_map_items, new_map_size;
+ nr_new_map_items, new_map_size, old_size;
- nr_pages = DIV_ROUND_UP(si->size, PAGE_SIZE);
+ old_size = si->size;
+ si->size = new_size;
+ if (!is_shmem_tracking_en())
+ return 0;
+
+ nr_pages = DIV_ROUND_UP(old_size, PAGE_SIZE);
nr_map_items = BITS_TO_LONGS(nr_pages * PST_BITS);
map_size = nr_map_items * sizeof(*si->pstate_map);
@@ -166,8 +193,6 @@ static int expand_shmem(struct shmem_info *si, unsigned long new_size)
if (!si->pstate_map)
return -1;
memzero(si->pstate_map + nr_map_items, new_map_size - map_size);
-
- si->size = new_size;
return 0;
}
@@ -175,6 +200,9 @@ static void update_shmem_pmaps(struct shmem_info *si, u64 *map, VmaEntry *vma)
{
unsigned long shmem_pfn, vma_pfn, vma_pgcnt;
+ if (!is_shmem_tracking_en())
+ return;
+
vma_pgcnt = DIV_ROUND_UP(si->size - vma->pgoff, PAGE_SIZE);
for (vma_pfn = 0; vma_pfn < vma_pgcnt; ++vma_pfn) {
if (!should_dump_page(vma, map[vma_pfn]))
@@ -640,11 +668,16 @@ static int dump_one_shmem(struct shmem_info *si)
goto err_pp;
for (pfn = 0; pfn < nrpages; pfn++) {
- unsigned int pgstate;
+ unsigned int pgstate = PST_DIRTY;
+ bool use_mc = true;
unsigned long pgaddr;
- pgstate = get_pstate(si->pstate_map, pfn);
- if ((pgstate == PST_DONT_DUMP) && !(mc_map[pfn] & PAGE_RSS))
+ if (is_shmem_tracking_en()) {
+ pgstate = get_pstate(si->pstate_map, pfn);
+ use_mc = pgstate == PST_DONT_DUMP;
+ }
+
+ if (use_mc && !(mc_map[pfn] & PAGE_RSS))
continue;
pgaddr = (unsigned long)addr + pfn * PAGE_SIZE;
@@ -653,7 +686,7 @@ again:
ret = page_pipe_add_hole(pp, pgaddr, PP_HOLE_ZERO);
else if (xfer.parent && page_in_parent(pgstate == PST_DIRTY))
ret = page_pipe_add_hole(pp, pgaddr, PP_HOLE_PARENT);
- else /* pgstate == PST_DUMP */
+ else
ret = page_pipe_add_page(pp, pgaddr, 0);
if (ret == -EAGAIN) {
--
1.9.1
More information about the CRIU
mailing list