All of lore.kernel.org
 help / color / mirror / Atom feed
From: SJ Park <sj@kernel.org>
To: Breno Leitao <leitao@debian.org>
Cc: SJ Park <sj@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Miaohe Lin <linmiaohe@huawei.com>,
	Naoya Horiguchi <nao.horiguchi@gmail.com>,
	Paul Walmsley <pjw@kernel.org>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>,
	david@kernel.org, linux-kernel@vger.kernel.org,
	linux-mm@kvack.org, linux-riscv@lists.infradead.org,
	kernel-team@meta.com
Subject: Re: [PATCH] tools/mm: add hwpoison-panic tool
Date: Fri, 31 Jul 2026 17:58:22 -0700	[thread overview]
Message-ID: <20260801005822.85110-1-sj@kernel.org> (raw)
In-Reply-To: <20260731-memory_failure_rewrite_test-v1-1-6aa8c6435693@debian.org>

On Fri, 31 Jul 2026 06:16:12 -0700 Breno Leitao <leitao@debian.org> wrote:

> Add a tool that enables the vm.panic_on_unrecoverable_memory_failure
> sysctl, picks a kernel-owned PFN and writes its physical address to
> hard_offline_page.  Three page kinds are selectable with -k: rodata
> (default), slab or pgtable. In all cases the host should panic.
> 
> Example:
> 
>         # ./hwpoison-panic  -k slab -f
>         injecting hwpoison at phys 0x100032000 (pfn 0x100032, kind=slab)
>         expecting kernel panic: 'Memory failure: <pfn>: unrecoverable page'
> 
> In dmesg, you will see:
> 
>         Memory failure: 0x100032: unhandlable page.
>         Memory failure: 0x100032: recovery action for reserved kernel page: Ignored
>         Kernel panic - not syncing: Memory failure: 0x100032: unrecoverable page
> 
> This lives in tools/mm rather than selftests/mm because every successful
> run crashes the machine, which is not something to run from CI.

If the purpose of the new program is testing, would it make more sense to put
it under tools/testing/ ?

Also, does this test really need to be end-to-end test that cause panic?  How
about doing unit test of core functions, using tools like kunit?  Or,
live-patching panic() to only print messages and return before running the
test?

> 
> Argument -f is required so an accidental invocation does not take the
> box down.
> 
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
>  MAINTAINERS                              |   1 +
>  tools/mm/.gitignore                      |   1 +
>  tools/mm/Makefile                        |   2 +
>  tools/mm/memory-failure/hwpoison-panic.c | 353 +++++++++++++++++++++++++++++++
>  4 files changed, 357 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 56b337a064478..799c4883d5b0b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -12094,6 +12094,7 @@ F:	include/linux/memory-failure.h
>  F:	include/trace/events/memory-failure.h
>  F:	mm/hwpoison-inject.c
>  F:	mm/memory-failure.c
> +F:	tools/mm/memory-failure/
>  F:	tools/testing/selftests/mm/memory-failure.c
>  
>  HYCON HY46XX TOUCHSCREEN SUPPORT
> diff --git a/tools/mm/.gitignore b/tools/mm/.gitignore
> index 1446a659e5408..b9b80d909db4a 100644
> --- a/tools/mm/.gitignore
> +++ b/tools/mm/.gitignore
> @@ -3,3 +3,4 @@ slabinfo
>  page-types
>  page_owner_sort
>  thp_swap_allocator_test
> +memory-failure/hwpoison-panic
> diff --git a/tools/mm/Makefile b/tools/mm/Makefile
> index 858186a6eefdb..9f6de957a95a0 100644
> --- a/tools/mm/Makefile
> +++ b/tools/mm/Makefile
> @@ -4,6 +4,7 @@
>  include ../scripts/Makefile.include
>  
>  BUILD_TARGETS=page-types slabinfo page_owner_sort page_owner_filter thp_swap_allocator_test
> +BUILD_TARGETS+=memory-failure/hwpoison-panic

I was initially thought why not underscore but dash on the name?  But, I
realize it is obviously too persoanl taste.

[...]
> diff --git a/tools/mm/memory-failure/hwpoison-panic.c b/tools/mm/memory-failure/hwpoison-panic.c
> new file mode 100644
> index 0000000000000..b8076d86da15b
> --- /dev/null
> +++ b/tools/mm/memory-failure/hwpoison-panic.c
> @@ -0,0 +1,353 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * hwpoison-panic: verify vm.panic_on_unrecoverable_memory_failure by
> + * injecting a hwpoison error on a kernel-owned page and confirming the
> + * kernel panics.

While reading the above explanation, I was expecting this program will directly
say me if the kernel panic-ed or not.  But this only says if it was not
panic-ed iiuc?  How about saying, like, "Trigger intentional kernel panic by
..." ?

No strong opinion.  I'm never a good English reader.

[...]
> +static const struct page_kind *parse_args(int argc, char **argv, int *force)
> +{
> +	const struct page_kind *kind;
> +	const char *name = "rodata";
> +	int c;
> +
> +	while ((c = getopt_long(argc, argv, "k:fh", opts, NULL)) != -1) {
> +		switch (c) {
> +		case 'k':
> +			name = optarg;
> +			break;
> +		case 'f':
> +			*force = 1;
> +			break;
> +		case 'h':
> +			usage();
> +			exit(EXIT_SUCCESS);
> +		default:
> +			usage();
> +			exit(EXIT_FAILURE);
> +		}
> +	}
> +
> +	kind = lookup_kind(name);
> +	if (!kind)
> +		fatal("unknown kind '%s' (expected: rodata|slab|pgtable)\n",
> +		      name);
> +
> +	return kind;
> +}
> +
> +static void check_prereqs(int force)
> +{
> +	if (geteuid())
> +		fatal("must run as root\n");
> +	if (access(SYSCTL_PATH, W_OK))
> +		fatal("%s not present (kernel without the sysctl?)\n",
> +		      SYSCTL_PATH);
> +	if (access(INJECT_PATH, W_OK))
> +		fatal("%s not present (no MEMORY_HOTPLUG?)\n", INJECT_PATH);
> +	if (!force)
> +		fatal("this panics the kernel; pass -f to run it in a disposable VM\n");

I personally feel like this option is not very intuitive to me.  I think the
name could be better to be intuitive.  Just removing the option also seems fine
to me.  If we really want to warn the brave root user, adding an interactive
prompt (E.g., "This will panic the kernel.  Proceed? [y/N]") also be an
intuitive and safer way in my opinion.

No strong opinion.  My user experience design skill is undoubtedly bad.  Feel
free to keep this as is.

> +}
[...]
> +int main(int argc, char **argv)
> +{
> +	unsigned long phys_addr, pfn, prior;
> +	const struct page_kind *kind;
> +	const char *verdict;
> +	int force = 0;
> +
> +	kind = parse_args(argc, argv, &force);
> +	page_size = getpagesize();
> +	check_prereqs(force);

Maybe check_prereqs() can be called before getpagesize()?

[...]


Thanks,
SJ

WARNING: multiple messages have this Message-ID (diff)
From: SJ Park <sj@kernel.org>
To: Breno Leitao <leitao@debian.org>
Cc: SJ Park <sj@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Miaohe Lin <linmiaohe@huawei.com>,
	Naoya Horiguchi <nao.horiguchi@gmail.com>,
	Paul Walmsley <pjw@kernel.org>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>,
	david@kernel.org, linux-kernel@vger.kernel.org,
	linux-mm@kvack.org, linux-riscv@lists.infradead.org,
	kernel-team@meta.com
Subject: Re: [PATCH] tools/mm: add hwpoison-panic tool
Date: Fri, 31 Jul 2026 17:58:22 -0700	[thread overview]
Message-ID: <20260801005822.85110-1-sj@kernel.org> (raw)
In-Reply-To: <20260731-memory_failure_rewrite_test-v1-1-6aa8c6435693@debian.org>

On Fri, 31 Jul 2026 06:16:12 -0700 Breno Leitao <leitao@debian.org> wrote:

> Add a tool that enables the vm.panic_on_unrecoverable_memory_failure
> sysctl, picks a kernel-owned PFN and writes its physical address to
> hard_offline_page.  Three page kinds are selectable with -k: rodata
> (default), slab or pgtable. In all cases the host should panic.
> 
> Example:
> 
>         # ./hwpoison-panic  -k slab -f
>         injecting hwpoison at phys 0x100032000 (pfn 0x100032, kind=slab)
>         expecting kernel panic: 'Memory failure: <pfn>: unrecoverable page'
> 
> In dmesg, you will see:
> 
>         Memory failure: 0x100032: unhandlable page.
>         Memory failure: 0x100032: recovery action for reserved kernel page: Ignored
>         Kernel panic - not syncing: Memory failure: 0x100032: unrecoverable page
> 
> This lives in tools/mm rather than selftests/mm because every successful
> run crashes the machine, which is not something to run from CI.

If the purpose of the new program is testing, would it make more sense to put
it under tools/testing/ ?

Also, does this test really need to be end-to-end test that cause panic?  How
about doing unit test of core functions, using tools like kunit?  Or,
live-patching panic() to only print messages and return before running the
test?

> 
> Argument -f is required so an accidental invocation does not take the
> box down.
> 
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
>  MAINTAINERS                              |   1 +
>  tools/mm/.gitignore                      |   1 +
>  tools/mm/Makefile                        |   2 +
>  tools/mm/memory-failure/hwpoison-panic.c | 353 +++++++++++++++++++++++++++++++
>  4 files changed, 357 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 56b337a064478..799c4883d5b0b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -12094,6 +12094,7 @@ F:	include/linux/memory-failure.h
>  F:	include/trace/events/memory-failure.h
>  F:	mm/hwpoison-inject.c
>  F:	mm/memory-failure.c
> +F:	tools/mm/memory-failure/
>  F:	tools/testing/selftests/mm/memory-failure.c
>  
>  HYCON HY46XX TOUCHSCREEN SUPPORT
> diff --git a/tools/mm/.gitignore b/tools/mm/.gitignore
> index 1446a659e5408..b9b80d909db4a 100644
> --- a/tools/mm/.gitignore
> +++ b/tools/mm/.gitignore
> @@ -3,3 +3,4 @@ slabinfo
>  page-types
>  page_owner_sort
>  thp_swap_allocator_test
> +memory-failure/hwpoison-panic
> diff --git a/tools/mm/Makefile b/tools/mm/Makefile
> index 858186a6eefdb..9f6de957a95a0 100644
> --- a/tools/mm/Makefile
> +++ b/tools/mm/Makefile
> @@ -4,6 +4,7 @@
>  include ../scripts/Makefile.include
>  
>  BUILD_TARGETS=page-types slabinfo page_owner_sort page_owner_filter thp_swap_allocator_test
> +BUILD_TARGETS+=memory-failure/hwpoison-panic

I was initially thought why not underscore but dash on the name?  But, I
realize it is obviously too persoanl taste.

[...]
> diff --git a/tools/mm/memory-failure/hwpoison-panic.c b/tools/mm/memory-failure/hwpoison-panic.c
> new file mode 100644
> index 0000000000000..b8076d86da15b
> --- /dev/null
> +++ b/tools/mm/memory-failure/hwpoison-panic.c
> @@ -0,0 +1,353 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * hwpoison-panic: verify vm.panic_on_unrecoverable_memory_failure by
> + * injecting a hwpoison error on a kernel-owned page and confirming the
> + * kernel panics.

While reading the above explanation, I was expecting this program will directly
say me if the kernel panic-ed or not.  But this only says if it was not
panic-ed iiuc?  How about saying, like, "Trigger intentional kernel panic by
..." ?

No strong opinion.  I'm never a good English reader.

[...]
> +static const struct page_kind *parse_args(int argc, char **argv, int *force)
> +{
> +	const struct page_kind *kind;
> +	const char *name = "rodata";
> +	int c;
> +
> +	while ((c = getopt_long(argc, argv, "k:fh", opts, NULL)) != -1) {
> +		switch (c) {
> +		case 'k':
> +			name = optarg;
> +			break;
> +		case 'f':
> +			*force = 1;
> +			break;
> +		case 'h':
> +			usage();
> +			exit(EXIT_SUCCESS);
> +		default:
> +			usage();
> +			exit(EXIT_FAILURE);
> +		}
> +	}
> +
> +	kind = lookup_kind(name);
> +	if (!kind)
> +		fatal("unknown kind '%s' (expected: rodata|slab|pgtable)\n",
> +		      name);
> +
> +	return kind;
> +}
> +
> +static void check_prereqs(int force)
> +{
> +	if (geteuid())
> +		fatal("must run as root\n");
> +	if (access(SYSCTL_PATH, W_OK))
> +		fatal("%s not present (kernel without the sysctl?)\n",
> +		      SYSCTL_PATH);
> +	if (access(INJECT_PATH, W_OK))
> +		fatal("%s not present (no MEMORY_HOTPLUG?)\n", INJECT_PATH);
> +	if (!force)
> +		fatal("this panics the kernel; pass -f to run it in a disposable VM\n");

I personally feel like this option is not very intuitive to me.  I think the
name could be better to be intuitive.  Just removing the option also seems fine
to me.  If we really want to warn the brave root user, adding an interactive
prompt (E.g., "This will panic the kernel.  Proceed? [y/N]") also be an
intuitive and safer way in my opinion.

No strong opinion.  My user experience design skill is undoubtedly bad.  Feel
free to keep this as is.

> +}
[...]
> +int main(int argc, char **argv)
> +{
> +	unsigned long phys_addr, pfn, prior;
> +	const struct page_kind *kind;
> +	const char *verdict;
> +	int force = 0;
> +
> +	kind = parse_args(argc, argv, &force);
> +	page_size = getpagesize();
> +	check_prereqs(force);

Maybe check_prereqs() can be called before getpagesize()?

[...]


Thanks,
SJ

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  reply	other threads:[~2026-08-01  0:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 13:16 [PATCH] tools/mm: add hwpoison-panic tool Breno Leitao
2026-07-31 13:16 ` Breno Leitao
2026-08-01  0:58 ` SJ Park [this message]
2026-08-01  0:58   ` SJ Park

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=20260801005822.85110-1-sj@kernel.org \
    --to=sj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=alex@ghiti.fr \
    --cc=aou@eecs.berkeley.edu \
    --cc=david@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=leitao@debian.org \
    --cc=linmiaohe@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=nao.horiguchi@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=pjw@kernel.org \
    /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.