Re: [PATCH v5 8/9] mm/memory-failure: add hwpoison_boot_page() to flag an inherited frame

From: Shaikh Kamaluddin

Date: Sat Sep 19 2026 - 06:30:13 EST


On Tue, Sep 15, 2026 at 05:53:42AM -0700, Breno Leitao wrote:
> A frame the previous kernel recorded as poisoned has to be flagged before
> it reaches the allocator, which is long before memory_failure() can run.
> Add a helper that leaves it in the state a frame poisoned by this kernel
> would be in, so everything that already understands PG_hwpoison covers it,
> the kexec segment placement check included.
>
> num_poisoned_pages_inc() does not work at boot: its per memory block half
> looks the block up by pfn, and memory_dev_init() has not run, so it
> divides by zero. Take only the global counter there. A hotplugged block is
> already there, so that path takes both counters as usual.
>
> The caller comes later in this series.
>
> Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
> ---
> include/linux/mm.h | 7 +++++++
> mm/memory-failure.c | 26 ++++++++++++++++++++++++++
> 2 files changed, 33 insertions(+)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index b68824fcfbef19..8039830998dd4b 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -5225,6 +5225,8 @@ extern const struct attribute_group memory_failure_attr_group;
> extern void memory_failure_queue(unsigned long pfn, int flags);
> void num_poisoned_pages_inc(unsigned long pfn);
> void num_poisoned_pages_sub(unsigned long pfn, long i);
> +void __meminit hwpoison_boot_page(struct page *page,
> + enum meminit_context context);
> phys_addr_t range_first_hwpoison(phys_addr_t start, unsigned long size);
> phys_addr_t range_last_hwpoison(phys_addr_t start, unsigned long size);
> #else
> @@ -5232,6 +5234,11 @@ static inline void memory_failure_queue(unsigned long pfn, int flags)
> {
> }
>
> +static inline void hwpoison_boot_page(struct page *page,
> + enum meminit_context context)
> +{
> +}
> +
> static inline void num_poisoned_pages_inc(unsigned long pfn)
> {
> }
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index d9b8be696aac38..60e9682434700b 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -137,6 +137,32 @@ phys_addr_t range_last_hwpoison(phys_addr_t start, unsigned long size)
> return range_hwpoison(start, size, false);
> }
>
> +static void update_per_node_mf_stats(unsigned long pfn, enum mf_result result);
> +
> +void __meminit hwpoison_boot_page(struct page *page,
> + enum meminit_context context)
> +{
> + unsigned long pfn = page_to_pfn(page);
> +
> + if (PageHWPoison(page))
> + return;
> +
> + SetPageHWPoison(page);
> + set_page_count(page, 1);
> + /* The page has been completely isolated == MF_RECOVERED */
> + update_per_node_mf_stats(pfn, MF_RECOVERED);


snip

> +
> + /*
> + * The per memory block half of num_poisoned_pages_inc() has no block to
> + * find at boot, and divides by zero looking for one. A hotplugged block
> + * is already there.
> + */
> + if (context == MEMINIT_HOTPLUG)
> + num_poisoned_pages_inc(pfn);
> + else
> + atomic_long_inc(&num_poisoned_pages);
> +}

Hi Breno,

num_poisoned_pages_inc() currently assumes that the supplied PFN can
be used for per-memory-block accounting and therefore calls
memblk_nr_poison_inc() unconditionally. The early-boot path needs
global-only accounting because the memory-block infrastructure is not
initialized yet.

Could num_poisoned_pages_inc() treat -1UL as global-only accounting,
matching num_poisoned_pages_sub()?

Example as below:

void num_poisoned_pages_inc(unsigned long pfn)
{
atomic_long_inc(&num_poisoned_pages);

if (pfn != -1UL)
memblk_nr_poison_inc(pfn);
}


The caller could then use:

num_poisoned_pages_inc(context == MEMINIT_HOTPLUG ? pfn : -1UL);

This would keep updates to `num_poisoned_pages` encapsulated rather than
manipulating the counter directly here, while also making the increment
and decrement interfaces consistent.

Thanks,
Shaikh Kamaluddin.
> +
> /**
> * MF_ATTR_RO - Create sysfs entry for each memory failure statistics.
> * @_name: name of the file in the per NUMA sysfs directory.
>
> --
> 2.53.0-Meta
>