Commit de2b4261 authored by Andrei Vagin's avatar Andrei Vagin Committed by Pavel Emelyanov

pagemap: add an ability to disable pagemap cache

We found that the 3.19 Ubuntu kernel has a bug and
the pagemap cache doesn't work properly on this kernel.

Unfortunately Travis-CI allows to create intancies only with this kernel,
so we need to add this workaround.

https://github.com/xemul/criu/issues/207

Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Dmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Reviewed-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 95ae8ae5
...@@ -21,6 +21,13 @@ ...@@ -21,6 +21,13 @@
#define PAGEMAP_LEN(addr) (PAGE_PFN(addr) * sizeof(u64)) #define PAGEMAP_LEN(addr) (PAGE_PFN(addr) * sizeof(u64))
/*
* It's a workaround for a kernel bug. In the 3.19 kernel when pagemap are read
* for a few vma-s for one read call, it returns incorrect data.
* https://github.com/xemul/criu/issues/207
*/
static bool pagemap_cache_disabled;
static inline void pmc_reset(pmc_t *pmc) static inline void pmc_reset(pmc_t *pmc)
{ {
memzero(pmc, sizeof(*pmc)); memzero(pmc, sizeof(*pmc));
...@@ -47,6 +54,9 @@ int pmc_init(pmc_t *pmc, pid_t pid, const struct list_head *vma_head, size_t siz ...@@ -47,6 +54,9 @@ int pmc_init(pmc_t *pmc, pid_t pid, const struct list_head *vma_head, size_t siz
if (!pmc->map) if (!pmc->map)
goto err; goto err;
if (pagemap_cache_disabled)
pr_debug("The pagemap cache is disabled\n");
if (kdat.pmap == PM_DISABLED) { if (kdat.pmap == PM_DISABLED) {
/* /*
* FIXME We might need to implement greedy * FIXME We might need to implement greedy
...@@ -107,7 +117,8 @@ static int pmc_fill_cache(pmc_t *pmc, const struct vma_area *vma) ...@@ -107,7 +117,8 @@ static int pmc_fill_cache(pmc_t *pmc, const struct vma_area *vma)
* The benefit (apart redusing the number of read() calls) * The benefit (apart redusing the number of read() calls)
* is to walk page tables less. * is to walk page tables less.
*/ */
if (len < PMC_SIZE && (vma->e->start - low) < PMC_SIZE_GAP) { if (!pagemap_cache_disabled &&
len < PMC_SIZE && (vma->e->start - low) < PMC_SIZE_GAP) {
size_t size_cov = len; size_t size_cov = len;
size_t nr_vmas = 1; size_t nr_vmas = 1;
...@@ -174,3 +185,8 @@ void pmc_fini(pmc_t *pmc) ...@@ -174,3 +185,8 @@ void pmc_fini(pmc_t *pmc)
xfree(pmc->map); xfree(pmc->map);
pmc_reset(pmc); pmc_reset(pmc);
} }
static void __attribute__((constructor)) pagemap_cache_init(void)
{
pagemap_cache_disabled = (getenv("CRIU_PMC_OFF") != NULL);
}
...@@ -24,6 +24,10 @@ make -C test/zdtm ...@@ -24,6 +24,10 @@ make -C test/zdtm
umask 0000 umask 0000
export SKIP_PREP=1 export SKIP_PREP=1
# The 3.19 Ubuntu kernel has a bug. When pagemap are read for a few vma-s
# for one read call, it returns incorrect data.
# https://github.com/xemul/criu/issues/207
export CRIU_PMC_OFF=1
./test/zdtm.py run -a -x 'cgroup*' -p 2 ./test/zdtm.py run -a -x 'cgroup*' -p 2
......
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