[CRIU] [PATCH v5 3/5] Try to include userfaultfd with criu (part 1)

Dmitry Safonov dsafonov at virtuozzo.com
Thu Mar 10 04:06:06 PST 2016


On 03/10/2016 10:39 AM, Adrian Reber wrote:
> From: Adrian Reber <areber at redhat.com>
>
> This is a first try to include userfaultfd with criu. Right now it
> still requires a "normal" checkpoint. After checkpointing the
> application it can be restored with the help of userfaultfd.
>
> All restored pages with MAP_ANONYMOUS and MAP_PRIVATE set are marked as
> being handled by userfaultfd.
>
> As soon as the process is restored it blocks on the first memory access
> and waits for pages being transferred by userfaultfd.
>
> To handle the required pages a new criu command has been added. For a
> userfaultfd supported restore the first step is to start the
> 'lazy-pages' server:
>
>    criu lazy-pages -v4 -D /tmp/3/ --address /tmp/userfault.socket
>
> This is part 1 of the userfaultfd integration which provides the
> 'lazy-pages' server implementation.
>
> v2:
>      * provide option '--lazy-pages' to enable uffd style restore
>      * use send_fd()/recv_fd() provided by criu (instead of own
>        implementation)
>      * do not install the uffd as service_fd
>      * use named constants for MAP_ANONYMOUS
>      * do not restore memory pages and then later mark them as uffd
>        handled
>      * remove function find_pages() to search in pages-<id>.img;
>        now using criu functions to find the necessary pages;
>        for each new page search the pages-<id>.img file is opened
>      * only check the UFFDIO_API once
>      * trying to protect uffd code by CONFIG_UFFD;
>        use make UFFD=1 to compile criu with this patch
>
> v3:
>     * renamed the server mode from 'uffd' -> 'lazy-pages'
>     * switched client and server roles transferring the UFFD FD
>       * the criu part running in lazy-pages server mode is now
>         waiting for connections
>       * the criu restore process connects to the lazy-pages server
>         to pass the UFFD FD
>     * before UFFD copying anything else the VDSO pages are copied
>       as it fails to copy unused VDSO pages once the process is running.
>       this was necessary to be able to copy all pages.
>     * if there are no more UFFD messages for 5 seconds the lazy-pages
>       server switches in copy mode to copy all remaining pages, which
>       have not been requested yet, into the restored process
>     * check the UFFDIO_API at the correct place
>     * close UFFD FD in the restorer to remove open UFFD FD in the
>       restored process
>
> v4:
>      * removed unnecessary madvise() calls ; it seemed necessary when
>        first running tests with uffd; it actually is not necessary
>      * auto-detect if build-system provides linux/userfaultfd.h
>        header
>      * simplify unix domain socket setup and communication.
>      * use --address to specify the location of the used
>        unix domain socket
>
> v5:
>      * split the userfaultfd patch in multiple smaller patches
>      * introduced vma_can_be_lazy() function to check if a page
>        can be handled by uffd
>      * moved uffd related code from cr-restore.c to uffd.c
>      * handle failure to register a memory page of the restored process
>        with userfaultfd
Hello, Adrian,
just a small nip from me below:
>
> Signed-off-by: Adrian Reber <areber at redhat.com>
> ---
>   criu/Makefile.config      |   6 +-
>   criu/Makefile.crtools     |   4 +
>   criu/crtools.c            |   6 +
>   criu/include/crtools.h    |   5 +
>   criu/include/uffd.h       |  16 ++
>   criu/uffd.c               | 437 ++++++++++++++++++++++++++++++++++++++++++++++
>   scripts/feature-tests.mak |  15 ++
>   7 files changed, 488 insertions(+), 1 deletion(-)
>   create mode 100644 criu/include/uffd.h
>   create mode 100644 criu/uffd.c
>
> diff --git a/criu/Makefile.config b/criu/Makefile.config
> index aaaca1f..c3841b9 100644
> --- a/criu/Makefile.config
> +++ b/criu/Makefile.config
> @@ -14,8 +14,12 @@ ifeq ($(call pkg-config-check,libselinux),y)
>           DEFINES	+= -DCONFIG_HAS_SELINUX
>   endif
>   
> +ifeq ($(call try-cc,$(FEATURE_TEST_UFFD)),y)
> +	export UFFD := 1
> +endif
> +
Here we try-cc feature test,
>   FEATURES_LIST	:= TCP_REPAIR PRLIMIT STRLCPY STRLCAT PTRACE_PEEKSIGINFO \
> -	SETPROCTITLE_INIT MEMFD
> +	SETPROCTITLE_INIT MEMFD UFFD
and adding it to FEATURES_LIST will compile feature test for CONFIG_HAS_*
define the second time, which will slowdown makefile processing.
As we know the result of first try-cc, we may use it (completely untested):

diff --git a/criu/Makefile.config b/criu/Makefile.config
index c3841b9..56076b6 100644
--- a/criu/Makefile.config
+++ b/criu/Makefile.config
@@ -19,7 +19,7 @@ ifeq ($(call try-cc,$(FEATURE_TEST_UFFD)),y)
  endif

  FEATURES_LIST  := TCP_REPAIR PRLIMIT STRLCPY STRLCAT PTRACE_PEEKSIGINFO \
-       SETPROCTITLE_INIT MEMFD UFFD
+       SETPROCTITLE_INIT MEMFD

  # $1 - config name
  define gen-feature-test
@@ -38,6 +38,10 @@ $(CONFIG_HEADER): include/config-base.h
         $(Q) @echo '#include "config-base.h"'                           
 >> $$@
         $(Q) @echo ''                                                   
 >> $$@
  $(call map,gen-feature-test,$(FEATURES_LIST))
+ifeq ($$(UFFD),1)
+       $(Q) @echo '#define CONFIG_HAS_UFFD'                            
 >> $$@
+       $(Q) @echo ''                                                   
 >> $$@
+endif
  ifeq ($$(VDSO),y)
         $(Q) @echo '#define CONFIG_VDSO'                                
 >> $$@
         $(Q) @echo ''                                                   
 >> $$@

Through, slowdown will not be great (exec+cc a small program) - you
may drop this and I'm fine.
Maybe if we'll have more feature test that need Makefile define exports,
we'll make some standard for makefile variables like $(UFFD) and
clean this, but yet, I suggest adding this diff.

Thanks,
Dmitry


More information about the CRIU mailing list