All of lore.kernel.org
 help / color / mirror / Atom feed
From: Petr Vorel <pvorel@suse.cz>
To: Martin Cermak <mcermak@redhat.com>
Cc: valgrind-developers@lists.sourceforge.net, ltp@lists.linux.it
Subject: Re: [LTP] [Valgrind-developers] [PATCH] Make userfaultfd0{1, 3, 4} LTP tests valgrind compatible
Date: Wed, 22 Apr 2026 07:37:12 +0200	[thread overview]
Message-ID: <20260422053712.GB392764@pevik> (raw)
In-Reply-To: <20260421152349.1673057-1-mcermak@redhat.com>

Hi Martin,

[ Cc Ricardo ]

> Historically a page fault is handled in the linux kernel. The
> userfaultfd mechanism [1] was introduced in Linux 4.3 (2015) to allow
> custom handling page faults in userspace. It allows for custom page
> fault handling strategies such as lazy loading, live migration of qemu
> VMs, etc.  With userfaultfd, kernel communicates with userspace via a
> file descriptor (userfaultfd).  Userfaultfd LTP tests cover this.

> These tests set up a main thread and a page fault handler thread.  Once
> a page fault happens in the main thread, kernel stops it, and let's the
> handler take care of the page fault.

> This is a problem for Valgrind, because it serializes the threads
> execution (using one "big mutex", VG_(acquire_BigLock)).  Once kernel
> stops the main thread, under valgrind, the handler thread doesn't have
> a chance to handle the page fault.  Valgrind stalls till the timeout
> (adjustable via LTP_TIMEOUT_MUL ;)

> However, some of the testcases can be easily changed to use forked
> processes instead of threads.  That's what this patch does.  When
> client program forks, Valgrind forks too, and that allows for the needed
> parallelism to handle the page fault.

You understand process vs. threads more than me. But shouldn't mmap() use
MAP_SHARED instead of MAP_PRIVATE for those which aren't using /dev/userfaultfd?

> This redesign can't be easily done with some of the tests, such as e.g.
> userfaultfd02 where both the main thread and the handler thread need to
> share the address space.  That could be done via clone() and is proven

What is the difference with userfaultfd02 then?

> to work.  But unfortunately there is another Valgrind limitation in clone
> flags it supports, so this also isn't a practical way to go.

> That said, this update tweaks userfaultfd01, userfaultfd03, and
> userfaultfd04 in a way that they become "compatible" with Valgrind.
> It's a test coverage improvement.

Also doc should be updated (mentions thread).

Please don't forget to add it next time:
Signed-off-by: Martin Cermak <mcermak@redhat.com>

> [1] https://www.kernel.org/doc/html/latest/admin-guide/mm/userfaultfd.html
> ---
>  .../kernel/syscalls/userfaultfd/userfaultfd01.c   | 13 +++++++++----
>  .../kernel/syscalls/userfaultfd/userfaultfd03.c   | 15 ++++++++++-----
>  .../kernel/syscalls/userfaultfd/userfaultfd04.c   | 13 +++++++++----
>  3 files changed, 28 insertions(+), 13 deletions(-)

> diff --git a/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c b/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c
> index 7368d3863..c927cda95 100644
> --- a/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c
> +++ b/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c
> @@ -57,7 +57,7 @@ static void reset_pages(void)
>  	SAFE_MUNMAP(copy_page, page_size);
>  }

> -static void *handle_thread(void)
> +static void *pagefault_handler(void)
>  {
>  	static struct uffd_msg msg;
>  	struct uffdio_copy uffdio_copy = {};
> @@ -91,7 +91,7 @@ static void *handle_thread(void)

>  static void run(unsigned int i)
>  {
> -	pthread_t thr;
> +	pid_t pid;
>  	struct uffdio_api uffdio_api = {};
>  	struct uffdio_register uffdio_register;
>  	struct tcase *tc = &tcases[i];
> @@ -112,7 +112,11 @@ static void run(unsigned int i)

>  	SAFE_IOCTL(uffd, UFFDIO_REGISTER, &uffdio_register);

> -	SAFE_PTHREAD_CREATE(&thr, NULL, (void *) handle_thread, NULL);
> +	pid = SAFE_FORK();
> +	if (pid == 0) {
> +		pagefault_handler();
> +		_exit(0);
> +	}

>  	char c = page[0xf];

> @@ -121,7 +125,7 @@ static void run(unsigned int i)
>  	else
>  		tst_res(TFAIL, "Pagefault not handled!");

> -	SAFE_PTHREAD_JOIN(thr, NULL);
> +	SAFE_WAITPID(pid, NULL, 0);
>  	reset_pages();
>  }

> @@ -129,4 +133,5 @@ static struct tst_test test = {
>  	.setup = setup,
>  	.test = run,
>  	.tcnt = ARRAY_SIZE(tcases),
> +	.forks_child = 1,
>  };
> diff --git a/testcases/kernel/syscalls/userfaultfd/userfaultfd03.c b/testcases/kernel/syscalls/userfaultfd/userfaultfd03.c
> index b65f39eca..f5d3be1ae 100644
> --- a/testcases/kernel/syscalls/userfaultfd/userfaultfd03.c
> +++ b/testcases/kernel/syscalls/userfaultfd/userfaultfd03.c
> @@ -61,7 +61,7 @@ static void reset_pages(void)
>  	SAFE_MUNMAP(copy_page, page_size);
>  }

> -static void *handle_thread(void)
> +static void *pagefault_handler(void)
>  {
>  	static struct uffd_msg msg;
>  	struct uffdio_copy uffdio_copy = {};
> @@ -95,7 +95,7 @@ static void *handle_thread(void)

>  static void run(void)
>  {
> -	pthread_t thr;
> +	pid_t pid;
>  	struct uffdio_api uffdio_api = {};
>  	struct uffdio_register uffdio_register;

> @@ -112,7 +112,11 @@ static void run(void)

>  	SAFE_IOCTL(uffd, UFFDIO_REGISTER, &uffdio_register);

> -	SAFE_PTHREAD_CREATE(&thr, NULL, (void *) handle_thread, NULL);
> +	pid = SAFE_FORK();
> +		if (pid == 0) {
> +		pagefault_handler();
> +		_exit(0);
> +	}

>  	char c = page[0xf];

> @@ -121,7 +125,7 @@ static void run(void)
>  	else
>  		tst_res(TFAIL, "Pagefault not handled via /dev/userfaultfd");

> -	SAFE_PTHREAD_JOIN(thr, NULL);
> +	SAFE_WAITPID(pid, NULL, 0);
>  	reset_pages();
>  }

> @@ -132,5 +136,6 @@ static struct tst_test test = {
>  	.needs_kconfigs = (const char *[]) {
>  		"CONFIG_USERFAULTFD=y",
>  		NULL
> -	}
> +	},
> +	.forks_child = 1,
>  };
> diff --git a/testcases/kernel/syscalls/userfaultfd/userfaultfd04.c b/testcases/kernel/syscalls/userfaultfd/userfaultfd04.c
> index 4eb811e45..13883a711 100644
> --- a/testcases/kernel/syscalls/userfaultfd/userfaultfd04.c
> +++ b/testcases/kernel/syscalls/userfaultfd/userfaultfd04.c
> @@ -33,7 +33,7 @@ static void reset_pages(void)
>  	SAFE_MUNMAP(page, page_size);
>  }

> -static void *handle_thread(void)
> +static void *pagefault_handler(void)
>  {
>  	static struct uffd_msg msg;
>  	struct uffdio_zeropage uffdio_zeropage = {};
> @@ -64,7 +64,7 @@ static void *handle_thread(void)

>  static void run(void)
>  {
> -	pthread_t thr;
> +	pid_t pid;
>  	struct uffdio_api uffdio_api = {};
>  	struct uffdio_register uffdio_register;

> @@ -81,7 +81,11 @@ static void run(void)

>  	SAFE_IOCTL(uffd, UFFDIO_REGISTER, &uffdio_register);

> -	SAFE_PTHREAD_CREATE(&thr, NULL, (void *) handle_thread, NULL);
> +	pid = SAFE_FORK();
> +	if (pid == 0) {
> +		pagefault_handler();
> +		_exit(0);
> +	}

>  	for (int i = 0; i < page_size; i++) {
>  		if (page[i] != 0) {
> @@ -92,10 +96,11 @@ static void run(void)

>  	tst_res(TPASS, "Pagefault handled with UFFDIO_ZEROPAGE");

> -	SAFE_PTHREAD_JOIN(thr, NULL);
> +	SAFE_WAITPID(pid, NULL, 0);
>  	reset_pages();
>  }

>  static struct tst_test test = {
>  	.test_all = run,
> +	.forks_child = 1,
>  };

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  parent reply	other threads:[~2026-04-22  5:37 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-21 15:23 [LTP] [PATCH] Make userfaultfd0{1, 3, 4} LTP tests valgrind compatible Martin Cermak via ltp
2026-04-21 17:06 ` [LTP] " linuxtestproject.agent
2026-04-22  5:37 ` Petr Vorel [this message]
2026-04-22  7:54   ` [LTP] [Valgrind-developers] [PATCH] " Ricardo Branco
2026-04-22 12:17     ` Petr Vorel
2026-04-22 12:42       ` Ricardo Branco
2026-04-22 13:08       ` Martin Cermak via ltp
2026-04-23 14:44         ` Martin Cermak via ltp
2026-04-28  8:35           ` Andrea Cervesato via ltp
2026-04-28  8:51             ` Martin Cermak via ltp
2026-04-28  8:55               ` Andrea Cervesato via ltp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260422053712.GB392764@pevik \
    --to=pvorel@suse.cz \
    --cc=ltp@lists.linux.it \
    --cc=mcermak@redhat.com \
    --cc=valgrind-developers@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.