pagemap: add an ability to disable pagemap cache

Submitted by Andrei Vagin on Aug. 24, 2016, 7:17 p.m.

Details

Message ID 1472066226-10339-1-git-send-email-avagin@openvz.org
State Accepted
Series "pagemap: add an ability to disable pagemap cache"
Commit ce8313c5f862b914b37389f19f89d97d4b039702
Headers show

Commit Message

Andrei Vagin Aug. 24, 2016, 7:17 p.m.
From: Andrei Vagin <avagin@virtuozzo.com>

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: Andrei Vagin <avagin@virtuozzo.com>
---
 criu/pagemap-cache.c        | 18 +++++++++++++++++-
 scripts/travis/travis-tests |  4 ++++
 2 files changed, 21 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/pagemap-cache.c b/criu/pagemap-cache.c
index 28bd8ca..5a8def9 100644
--- a/criu/pagemap-cache.c
+++ b/criu/pagemap-cache.c
@@ -21,6 +21,13 @@ 
 
 #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)
 {
 	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
 	if (!pmc->map)
 		goto err;
 
+	if (pagemap_cache_disabled)
+		pr_debug("The pagemap cache is disabled\n");
+
 	if (kdat.pmap == PM_DISABLED) {
 		/*
 		 * FIXME We might need to implement greedy
@@ -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)
 	 * 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 nr_vmas = 1;
 
@@ -174,3 +185,8 @@  void pmc_fini(pmc_t *pmc)
 	xfree(pmc->map);
 	pmc_reset(pmc);
 }
+
+static void __attribute__((constructor)) pagemap_cache_init(void)
+{
+	pagemap_cache_disabled = (getenv("CRIU_PMC_OFF") != NULL);
+}
diff --git a/scripts/travis/travis-tests b/scripts/travis/travis-tests
index fb569ac..76f4db9 100755
--- a/scripts/travis/travis-tests
+++ b/scripts/travis/travis-tests
@@ -19,6 +19,10 @@  make -C test/zdtm
 
 umask 0000
 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
 

Comments

Cyrill Gorcunov Aug. 24, 2016, 7:23 p.m.
On Wed, Aug 24, 2016 at 10:17:06PM +0300, Andrei Vagin wrote:
> From: Andrei Vagin <avagin@virtuozzo.com>
> 
> 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: Andrei Vagin <avagin@virtuozzo.com>
> ---
> @@ -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)
>  	 * 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 nr_vmas = 1;
>  
> @@ -174,3 +185,8 @@ void pmc_fini(pmc_t *pmc)
>  	xfree(pmc->map);
>  	pmc_reset(pmc);
>  }

Wait. I don't understand this moment. If pagemap_cache_disabled then
we need to fill pagecache with present values, so criu would dump
all the pages?
Cyrill Gorcunov Aug. 24, 2016, 7:26 p.m.
On Wed, Aug 24, 2016 at 10:23:14PM +0300, Cyrill Gorcunov wrote:
> 
> Wait. I don't understand this moment. If pagemap_cache_disabled then
> we need to fill pagecache with present values, so criu would dump
> all the pages?

Ah, you rather want to disable caching instead. OK.

Acked-by: Cyrill Gorcunov <gorcunov@openvz.org>
Dmitry Safonov Aug. 24, 2016, 7:35 p.m.
2016-08-24 22:17 GMT+03:00 Andrei Vagin <avagin@openvz.org>:
> From: Andrei Vagin <avagin@virtuozzo.com>
>
> 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: Andrei Vagin <avagin@virtuozzo.com>
> ---

Reviewed-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Thanks!
Pavel Emelianov Aug. 25, 2016, 6:20 p.m.
Applied