diff options
author | Bui Quang Minh <minhquangbui99@gmail.com> | 2022-05-12 18:40:54 +0300 |
---|---|---|
committer | Pavel Tikhomirov <ptikhomirov@virtuozzo.com> | 2022-06-18 23:32:43 +0300 |
commit | dd48de78f563d9f1250db8f4caf9cf404a777127 (patch) | |
tree | 2b8445edaf03b003362aee68903f3cb7aec04a77 | |
parent | 98eda32ae28b3ffcc849380c59ec9535586a1622 (diff) |
hugetlb: don't dump anonymous private hugetlb mapping using memfd approachtest
Currently, the content of anonymous private hugetlb mapping is dumped in 2
different images: memfd approach and normal private mapping dumping. In memfd
approach, we dump the content of the backing pseudo file (/anon_hugepage). This
is incorrect and redundant since the mapping is private, the content of backing
file may differ from the content of the mapping. With this commit, we remove the
redundant memfd approach dump and only do the normal private mapping dump on
anonymous hugetlb mapping.
Run zdtm.py run -f h --keep-img always -t zdtm/static/maps09, du -h in the
dumped image directory
Before this commit
13M test/dump/zdtm/static/maps09/55/1
After this commit
8.5M test/dump/zdtm/static/maps09/55/1
The reduction in size is approximately 4MB which is the size of anonymous
private hugetlb mapping in the test.
Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
-rw-r--r-- | criu/hugetlb.c | 13 | ||||
-rw-r--r-- | criu/include/hugetlb.h | 6 | ||||
-rw-r--r-- | criu/proc_parse.c | 7 |
3 files changed, 22 insertions, 4 deletions
diff --git a/criu/hugetlb.c b/criu/hugetlb.c index aa98662d8..866c4050f 100644 --- a/criu/hugetlb.c +++ b/criu/hugetlb.c @@ -35,6 +35,19 @@ int is_hugetlb_dev(dev_t dev, int *hugetlb_size_flag) return 0; } +int can_dump_with_memfd_hugetlb(dev_t dev, int *hugetlb_size_flag, const char *file_path, struct vma_area *vma) +{ + /* + * Dump the hugetlb backed mapping using memfd_hugetlb when it is not + * anonymous private mapping. + */ + if (kdat.has_memfd_hugetlb && is_hugetlb_dev(dev, hugetlb_size_flag) && + !((vma->e->flags & MAP_PRIVATE) && !strncmp(file_path, ANON_HUGEPAGE_PREFIX, ANON_HUGEPAGE_PREFIX_LEN))) + return 1; + + return 0; +} + unsigned long get_size_from_hugetlb_flag(int flag) { int i; diff --git a/criu/include/hugetlb.h b/criu/include/hugetlb.h index c0e83652b..9aee5bed3 100644 --- a/criu/include/hugetlb.h +++ b/criu/include/hugetlb.h @@ -4,6 +4,11 @@ #include <sys/types.h> #include <stddef.h> +#include "vma.h" + +#define ANON_HUGEPAGE_PREFIX "/anon_hugepage" +#define ANON_HUGEPAGE_PREFIX_LEN (sizeof(ANON_HUGEPAGE_PREFIX) - 1) + enum hugepage_size { HUGETLB_16KB, HUGETLB_64KB, @@ -46,6 +51,7 @@ struct htlb_info { extern struct htlb_info hugetlb_info[HUGETLB_MAX]; int is_hugetlb_dev(dev_t dev, int *hugetlb_size_flag); +int can_dump_with_memfd_hugetlb(dev_t dev, int *hugetlb_size_flag, const char *file_path, struct vma_area *vma); unsigned long get_size_from_hugetlb_flag(int flag); #ifndef MFD_HUGETLB diff --git a/criu/proc_parse.c b/criu/proc_parse.c index b3badb6e4..6b41a81db 100644 --- a/criu/proc_parse.c +++ b/criu/proc_parse.c @@ -620,17 +620,16 @@ static int handle_vma(pid_t pid, struct vma_area *vma_area, const char *file_pat pr_info("path: %s\n", file_path); vma_area->e->status |= VMA_AREA_SYSVIPC; } else { - /* Dump shmem dev, hugetlb dev (private and share) mappings the same way as memfd - * when possible. + /* We dump memfd backed mapping, both normal and hugepage anonymous share + * mapping using memfd approach when possible. */ if (is_memfd(st_buf->st_dev) || is_anon_shmem_map(st_buf->st_dev) || - (kdat.has_memfd_hugetlb && is_hugetlb_dev(st_buf->st_dev, &hugetlb_flag))) { + can_dump_with_memfd_hugetlb(st_buf->st_dev, &hugetlb_flag, file_path, vma_area)) { vma_area->e->status |= VMA_AREA_MEMFD; vma_area->e->flags |= hugetlb_flag; if (fault_injected(FI_HUGE_ANON_SHMEM_ID)) vma_area->e->shmid += FI_HUGE_ANON_SHMEM_ID_BASE; } else if (is_hugetlb_dev(st_buf->st_dev, &hugetlb_flag)) { - /* hugetlb mapping but memfd does not support HUGETLB */ vma_area->e->flags |= hugetlb_flag; vma_area->e->flags |= MAP_ANONYMOUS; |