2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 09:58:09 +00:00

criu/proc_parse: support MAP_DROPPABLE mappings

Support MAP_DROPPABLE [1] by detecting it from /proc/<pid>/smaps
and restoring it as a normal private mapping flag on vma with only
difference that instead of MAP_PRIVATE we should use MAP_DROPPABLE.

[1] 9651fcedf7

Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
This commit is contained in:
Alexander Mikhalitsyn 2025-05-04 17:11:28 +02:00 committed by Andrei Vagin
parent 237f099b29
commit 708228f5b8
3 changed files with 31 additions and 0 deletions

View File

@ -4,6 +4,9 @@
#ifndef MAP_HUGETLB #ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000 #define MAP_HUGETLB 0x40000
#endif #endif
#ifndef MAP_DROPPABLE
#define MAP_DROPPABLE 0x08
#endif
#ifndef MADV_HUGEPAGE #ifndef MADV_HUGEPAGE
#define MADV_HUGEPAGE 14 #define MADV_HUGEPAGE 14
#endif #endif

View File

@ -10,6 +10,7 @@
#include "cr_options.h" #include "cr_options.h"
#include "servicefd.h" #include "servicefd.h"
#include "mem.h" #include "mem.h"
#include "mman.h"
#include "parasite-syscall.h" #include "parasite-syscall.h"
#include "parasite.h" #include "parasite.h"
#include "page-pipe.h" #include "page-pipe.h"
@ -398,6 +399,17 @@ static int generate_vma_iovs(struct pstree_item *item, struct vma_area *vma, str
if (vma_entry_is(vma->e, VMA_AREA_VVAR)) if (vma_entry_is(vma->e, VMA_AREA_VVAR))
return 0; return 0;
/*
* 9651fcedf7b9 ("mm: add MAP_DROPPABLE for designating always lazily freeable mappings")
* tells us that:
* Under memory pressure, mm can just drop the pages (so that they're
* zero when read back again).
*
* Let's just skip MAP_DROPPABLE mappings pages dump logic.
*/
if (vma->e->flags & MAP_DROPPABLE)
return 0;
/* /*
* To facilitate any combination of pre-dump modes to run after * To facilitate any combination of pre-dump modes to run after
* one another, we need to take extra care as discussed below. * one another, we need to take extra care as discussed below.

View File

@ -144,6 +144,8 @@ static void __parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf,
*flags |= MAP_NORESERVE; *flags |= MAP_NORESERVE;
else if (_vmflag_match(tok, "ht")) else if (_vmflag_match(tok, "ht"))
*flags |= MAP_HUGETLB; *flags |= MAP_HUGETLB;
else if (_vmflag_match(tok, "dp"))
*flags |= MAP_DROPPABLE;
/* madvise() block */ /* madvise() block */
if (_vmflag_match(tok, "sr")) if (_vmflag_match(tok, "sr"))
@ -206,6 +208,20 @@ static void parse_vma_vmflags(char *buf, struct vma_area *vma_area)
if (vma_area->e->madv) if (vma_area->e->madv)
vma_area->e->has_madv = true; vma_area->e->has_madv = true;
/*
* We set MAP_PRIVATE flag on vma_area->e->flags right after parsing
* a first line of VMA entry in /proc/<pid>/smaps file:
* 7fa84fa70000-7fa84fa95000 rw-p 00000000 00:00 0
* but it's too early and we can't distinguish between MAP_DROPPABLE
* and MAP_PRIVATE mappings yet, as they both private mappings in nature
* and at this point we haven't yet read "VmFlags:" line in smaps.
*
* Let's detect this situation and drop MAP_PRIVATE flag while keep
* MAP_DROPPABLE, otherwise restorer's restore_mapping() helper will fail.
*/
if ((vma_area->e->flags & MAP_PRIVATE) && (vma_area->e->flags & MAP_DROPPABLE))
vma_area->e->flags &= ~MAP_PRIVATE;
} }
static inline int is_anon_shmem_map(dev_t dev) static inline int is_anon_shmem_map(dev_t dev)