All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages
@ 2026-07-14 20:51 Michal Clapinski
  2026-07-15  6:42 ` Mike Rapoport
  0 siblings, 1 reply; 6+ messages in thread
From: Michal Clapinski @ 2026-07-14 20:51 UTC (permalink / raw)
  To: Mike Rapoport, Pasha Tatashin, Pratyush Yadav, Alexander Graf,
	Evangelos Petrongonas, kexec
  Cc: linux-mm, linux-kernel, Michal Clapinski

I caught this crash:
BUG: unable to handle page fault for address: ff19164fffff8328
RIP: 0010:__free_one_page+0x1a1/0x6b0
Call Trace:
 <TASK>
 [<ffffffff913208bf>] free_one_page+0xaf/0x240
 [<ffffffff93973288>] deferred_free_pages+0xa8/0xd0
 [<ffffffff93971b4f>] deferred_init_memmap_chunk+0x10f/0x1b0
 [<ffffffff9396e265>] padata_mt_helper+0x65/0xa0
 [<ffffffff90fac402>] process_scheduled_works+0x202/0x410
 [<ffffffff90fae739>] worker_thread+0x1f9/0x2d0
 [<ffffffff90fb62fd>] kthread+0x27d/0x2f0
 [<ffffffff90fae540>] ? __pfx_worker_thread+0x10/0x10
 [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
 [<ffffffff90efdc55>] ret_from_fork+0x145/0x280
 [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
 [<ffffffff90e2e46a>] ret_from_fork_asm+0x1a/0x30
 </TASK>

deferred_init_memmap_chunk() works fine without KHO because free
regions will never be neighbors. However, with KHO, free memory
will be split into (free && scratch) and (free && !scratch).
KHO scratch is aligned to CMA_MIN_ALIGNMENT_BYTES (which on my setup
is equal to 1 << 9 pages) but buddy can look at the neighborhood of
MAX_ORDER_NR_PAGES pages (which is equal to 1 << 10 pages).
This sometimes crashes when one half of the neighborhood is being
initialized but the other part is yet to be initialized.

To fix this, let's just align KHO scratch to MAX_ORDER_NR_PAGES pages.

Fixes: c6073743d0c7 ("kho: make preserved pages compatible with deferred struct page init")
Signed-off-by: Michal Clapinski <mclapinski@google.com>
---
Unfortunately, this is very hard to catch, so I don't have a good
reproducer. But I run the code with the fix through extensive testing
and it seems fine.
I think I've never caught it before because enabling HUGETLB is what
causes CMA_MIN_ALIGNMENT_PAGES to be 1 << 9, instead of 1 << 10.

If this passes review, please cherry-pick it to 7.2 so we don't release
a broken kernel.
---
 kernel/liveupdate/kexec_handover.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 4834a809985a..50928aaa3371 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -38,6 +38,16 @@
 #include "../kexec_internal.h"
 #include "kexec_handover_internal.h"
 
+/*
+ * This is the minimal alignment required by deferred struct page init.
+ * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks
+ * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.
+ * If KHO scratch is not aligned to that value, buddy can access uninitialized
+ * struct pages, which can cause a crash.
+ */
+#define SCRATCH_ALIGNMENT_BYTES (1 << (PAGE_SHIFT + MAX_PAGE_ORDER))
+static_assert(SCRATCH_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);
+
 /* The magic token for preserved pages */
 #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
 
@@ -640,8 +650,8 @@ static void __init scratch_size_update(void)
 	 * Scratch areas are released as MIGRATE_CMA. Round them up to the right
 	 * size.
 	 */
-	scratch_size_lowmem = round_up(scratch_size_lowmem, CMA_MIN_ALIGNMENT_BYTES);
-	scratch_size_global = round_up(scratch_size_global, CMA_MIN_ALIGNMENT_BYTES);
+	scratch_size_lowmem = round_up(scratch_size_lowmem, SCRATCH_ALIGNMENT_BYTES);
+	scratch_size_global = round_up(scratch_size_global, SCRATCH_ALIGNMENT_BYTES);
 }
 
 static phys_addr_t __init scratch_size_node(int nid)
@@ -656,7 +666,7 @@ static phys_addr_t __init scratch_size_node(int nid)
 		size = scratch_size_pernode;
 	}
 
-	return round_up(size, CMA_MIN_ALIGNMENT_BYTES);
+	return round_up(size, SCRATCH_ALIGNMENT_BYTES);
 }
 
 /**
@@ -692,7 +702,7 @@ static void __init kho_reserve_scratch(void)
 	 * next kernel
 	 */
 	size = scratch_size_lowmem;
-	addr = memblock_phys_alloc_range(size, CMA_MIN_ALIGNMENT_BYTES, 0,
+	addr = memblock_phys_alloc_range(size, SCRATCH_ALIGNMENT_BYTES, 0,
 					 ARCH_LOW_ADDRESS_LIMIT);
 	if (!addr) {
 		pr_err("Failed to reserve lowmem scratch buffer\n");
@@ -705,7 +715,7 @@ static void __init kho_reserve_scratch(void)
 
 	/* reserve large contiguous area for allocations without nid */
 	size = scratch_size_global;
-	addr = memblock_phys_alloc(size, CMA_MIN_ALIGNMENT_BYTES);
+	addr = memblock_phys_alloc(size, SCRATCH_ALIGNMENT_BYTES);
 	if (!addr) {
 		pr_err("Failed to reserve global scratch buffer\n");
 		goto err_free_scratch_areas;
@@ -721,7 +731,7 @@ static void __init kho_reserve_scratch(void)
 	 */
 	for_each_node_state(nid, N_MEMORY) {
 		size = scratch_size_node(nid);
-		addr = memblock_alloc_range_nid(size, CMA_MIN_ALIGNMENT_BYTES,
+		addr = memblock_alloc_range_nid(size, SCRATCH_ALIGNMENT_BYTES,
 						0, MEMBLOCK_ALLOC_ACCESSIBLE,
 						nid, true);
 		if (!addr) {
-- 
2.55.0.141.g00534a21ce-goog



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages
  2026-07-14 20:51 [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages Michal Clapinski
@ 2026-07-15  6:42 ` Mike Rapoport
  2026-07-15 16:34   ` Michał Cłapiński
  2026-07-16 15:04   ` Pasha Tatashin
  0 siblings, 2 replies; 6+ messages in thread
From: Mike Rapoport @ 2026-07-15  6:42 UTC (permalink / raw)
  To: Michal Clapinski
  Cc: Mike Rapoport, Pasha Tatashin, Pratyush Yadav, Alexander Graf,
	Evangelos Petrongonas, kexec, linux-mm, linux-kernel

Hi Michal,

> I caught this crash:
> BUG: unable to handle page fault for address: ff19164fffff8328
> RIP: 0010:__free_one_page+0x1a1/0x6b0
> Call Trace:
>  <TASK>
>  [<ffffffff913208bf>] free_one_page+0xaf/0x240
>  [<ffffffff93973288>] deferred_free_pages+0xa8/0xd0
>  [<ffffffff93971b4f>] deferred_init_memmap_chunk+0x10f/0x1b0
>  [<ffffffff9396e265>] padata_mt_helper+0x65/0xa0
>  [<ffffffff90fac402>] process_scheduled_works+0x202/0x410
>  [<ffffffff90fae739>] worker_thread+0x1f9/0x2d0
>  [<ffffffff90fb62fd>] kthread+0x27d/0x2f0
>  [<ffffffff90fae540>] ? __pfx_worker_thread+0x10/0x10
>  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
>  [<ffffffff90efdc55>] ret_from_fork+0x145/0x280
>  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
>  [<ffffffff90e2e46a>] ret_from_fork_asm+0x1a/0x30
>  </TASK>
> 
> deferred_init_memmap_chunk() works fine without KHO because free
> regions will never be neighbors. However, with KHO, free memory
> will be split into (free && scratch) and (free && !scratch).
> KHO scratch is aligned to CMA_MIN_ALIGNMENT_BYTES (which on my setup
> is equal to 1 << 9 pages) but buddy can look at the neighborhood of
> MAX_ORDER_NR_PAGES pages (which is equal to 1 << 10 pages).
> This sometimes crashes when one half of the neighborhood is being
> initialized but the other part is yet to be initialized.
> 
> To fix this, let's just align KHO scratch to MAX_ORDER_NR_PAGES pages.
> 
> Fixes: c6073743d0c7 ("kho: make preserved pages compatible with deferred struct page init")
> Signed-off-by: Michal Clapinski <mclapinski@google.com>
>
> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> index 4834a809985ab..50928aaa33710 100644
> --- a/kernel/liveupdate/kexec_handover.c
> +++ b/kernel/liveupdate/kexec_handover.c
> @@ -38,6 +38,16 @@
>  #include "../kexec_internal.h"
>  #include "kexec_handover_internal.h"
>  
> +/*
> + * This is the minimal alignment required by deferred struct page init.
> + * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks
> + * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.
> + * If KHO scratch is not aligned to that value, buddy can access uninitialized
> + * struct pages, which can cause a crash.
> + */
> +#define SCRATCH_ALIGNMENT_BYTES (1 << (PAGE_SHIFT + MAX_PAGE_ORDER))
> +static_assert(SCRATCH_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);

Maybe make it a variable and set it at runtime?
We won't need to worry about different confugurations that override
MAX_ORDER and potentail divergence of pageblock size from MAX_ORDER in
the future.

-- 
Sincerely yours,
Mike.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages
  2026-07-15  6:42 ` Mike Rapoport
@ 2026-07-15 16:34   ` Michał Cłapiński
  2026-07-16 15:04   ` Pasha Tatashin
  1 sibling, 0 replies; 6+ messages in thread
From: Michał Cłapiński @ 2026-07-15 16:34 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Pasha Tatashin, Pratyush Yadav, Alexander Graf,
	Evangelos Petrongonas, kexec, linux-mm, linux-kernel

On Wed, Jul 15, 2026 at 8:43 AM Mike Rapoport <rppt@kernel.org> wrote:
>
> Hi Michal,
>
> > I caught this crash:
> > BUG: unable to handle page fault for address: ff19164fffff8328
> > RIP: 0010:__free_one_page+0x1a1/0x6b0
> > Call Trace:
> >  <TASK>
> >  [<ffffffff913208bf>] free_one_page+0xaf/0x240
> >  [<ffffffff93973288>] deferred_free_pages+0xa8/0xd0
> >  [<ffffffff93971b4f>] deferred_init_memmap_chunk+0x10f/0x1b0
> >  [<ffffffff9396e265>] padata_mt_helper+0x65/0xa0
> >  [<ffffffff90fac402>] process_scheduled_works+0x202/0x410
> >  [<ffffffff90fae739>] worker_thread+0x1f9/0x2d0
> >  [<ffffffff90fb62fd>] kthread+0x27d/0x2f0
> >  [<ffffffff90fae540>] ? __pfx_worker_thread+0x10/0x10
> >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> >  [<ffffffff90efdc55>] ret_from_fork+0x145/0x280
> >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> >  [<ffffffff90e2e46a>] ret_from_fork_asm+0x1a/0x30
> >  </TASK>
> >
> > deferred_init_memmap_chunk() works fine without KHO because free
> > regions will never be neighbors. However, with KHO, free memory
> > will be split into (free && scratch) and (free && !scratch).
> > KHO scratch is aligned to CMA_MIN_ALIGNMENT_BYTES (which on my setup
> > is equal to 1 << 9 pages) but buddy can look at the neighborhood of
> > MAX_ORDER_NR_PAGES pages (which is equal to 1 << 10 pages).
> > This sometimes crashes when one half of the neighborhood is being
> > initialized but the other part is yet to be initialized.
> >
> > To fix this, let's just align KHO scratch to MAX_ORDER_NR_PAGES pages.
> >
> > Fixes: c6073743d0c7 ("kho: make preserved pages compatible with deferred struct page init")
> > Signed-off-by: Michal Clapinski <mclapinski@google.com>
> >
> > diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> > index 4834a809985ab..50928aaa33710 100644
> > --- a/kernel/liveupdate/kexec_handover.c
> > +++ b/kernel/liveupdate/kexec_handover.c
> > @@ -38,6 +38,16 @@
> >  #include "../kexec_internal.h"
> >  #include "kexec_handover_internal.h"
> >
> > +/*
> > + * This is the minimal alignment required by deferred struct page init.
> > + * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks
> > + * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.
> > + * If KHO scratch is not aligned to that value, buddy can access uninitialized
> > + * struct pages, which can cause a crash.
> > + */
> > +#define SCRATCH_ALIGNMENT_BYTES (1 << (PAGE_SHIFT + MAX_PAGE_ORDER))
> > +static_assert(SCRATCH_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);
>
> Maybe make it a variable and set it at runtime?
> We won't need to worry about different confugurations that override
> MAX_ORDER and potentail divergence of pageblock size from MAX_ORDER in
> the future.

Sorry, I don't track. What would I set it to at runtime?
MAX_PAGE_ORDER must be >= PAGE_BLOCK_MAX_ORDER and I don't understand
what's the problem if some configurations override MAX_PAGE_ORDER.
They can't override it to be smaller than PAGE_BLOCK_MAX_ORDER.

Are you saying that in the future PAGE_BLOCK_MAX_ORDER could be bigger
than MAX_PAGE_ORDER?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages
  2026-07-15  6:42 ` Mike Rapoport
  2026-07-15 16:34   ` Michał Cłapiński
@ 2026-07-16 15:04   ` Pasha Tatashin
  2026-07-16 15:16     ` Michał Cłapiński
  2026-07-16 21:06     ` Mike Rapoport
  1 sibling, 2 replies; 6+ messages in thread
From: Pasha Tatashin @ 2026-07-16 15:04 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Michal Clapinski, Pasha Tatashin, Pratyush Yadav, Alexander Graf,
	Evangelos Petrongonas, kexec, linux-mm, linux-kernel

On 07-15 09:42, Mike Rapoport wrote:
> Hi Michal,
> 
> > I caught this crash:
> > BUG: unable to handle page fault for address: ff19164fffff8328
> > RIP: 0010:__free_one_page+0x1a1/0x6b0
> > Call Trace:
> >  <TASK>
> >  [<ffffffff913208bf>] free_one_page+0xaf/0x240
> >  [<ffffffff93973288>] deferred_free_pages+0xa8/0xd0
> >  [<ffffffff93971b4f>] deferred_init_memmap_chunk+0x10f/0x1b0
> >  [<ffffffff9396e265>] padata_mt_helper+0x65/0xa0
> >  [<ffffffff90fac402>] process_scheduled_works+0x202/0x410
> >  [<ffffffff90fae739>] worker_thread+0x1f9/0x2d0
> >  [<ffffffff90fb62fd>] kthread+0x27d/0x2f0
> >  [<ffffffff90fae540>] ? __pfx_worker_thread+0x10/0x10
> >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> >  [<ffffffff90efdc55>] ret_from_fork+0x145/0x280
> >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> >  [<ffffffff90e2e46a>] ret_from_fork_asm+0x1a/0x30
> >  </TASK>
> > 
> > deferred_init_memmap_chunk() works fine without KHO because free
> > regions will never be neighbors. However, with KHO, free memory
> > will be split into (free && scratch) and (free && !scratch).
> > KHO scratch is aligned to CMA_MIN_ALIGNMENT_BYTES (which on my setup
> > is equal to 1 << 9 pages) but buddy can look at the neighborhood of
> > MAX_ORDER_NR_PAGES pages (which is equal to 1 << 10 pages).
> > This sometimes crashes when one half of the neighborhood is being
> > initialized but the other part is yet to be initialized.
> > 
> > To fix this, let's just align KHO scratch to MAX_ORDER_NR_PAGES pages.
> > 
> > Fixes: c6073743d0c7 ("kho: make preserved pages compatible with deferred struct page init")
> > Signed-off-by: Michal Clapinski <mclapinski@google.com>
> >
> > diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> > index 4834a809985ab..50928aaa33710 100644
> > --- a/kernel/liveupdate/kexec_handover.c
> > +++ b/kernel/liveupdate/kexec_handover.c
> > @@ -38,6 +38,16 @@
> >  #include "../kexec_internal.h"
> >  #include "kexec_handover_internal.h"
> >  
> > +/*
> > + * This is the minimal alignment required by deferred struct page init.
> > + * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks
> > + * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.
> > + * If KHO scratch is not aligned to that value, buddy can access uninitialized
> > + * struct pages, which can cause a crash.
> > + */
> > +#define SCRATCH_ALIGNMENT_BYTES (1 << (PAGE_SHIFT + MAX_PAGE_ORDER))
> > +static_assert(SCRATCH_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);
> 
> Maybe make it a variable and set it at runtime?
> We won't need to worry about different confugurations that override
> MAX_ORDER and potentail divergence of pageblock size from MAX_ORDER in

Do those architectures reduce MAX_ORDER when they override it? I would 
hope we could set the alignment once and make it large enough to work 
everywhere, rather than depending on dynamic changes even during boot...

> the future.
> 
> -- 
> Sincerely yours,
> Mike.
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages
  2026-07-16 15:04   ` Pasha Tatashin
@ 2026-07-16 15:16     ` Michał Cłapiński
  2026-07-16 21:06     ` Mike Rapoport
  1 sibling, 0 replies; 6+ messages in thread
From: Michał Cłapiński @ 2026-07-16 15:16 UTC (permalink / raw)
  To: Pasha Tatashin
  Cc: Mike Rapoport, Pratyush Yadav, Alexander Graf,
	Evangelos Petrongonas, kexec, linux-mm, linux-kernel

On Thu, Jul 16, 2026 at 5:04 PM Pasha Tatashin
<pasha.tatashin@soleen.com> wrote:
>
> On 07-15 09:42, Mike Rapoport wrote:
> > Hi Michal,
> >
> > > I caught this crash:
> > > BUG: unable to handle page fault for address: ff19164fffff8328
> > > RIP: 0010:__free_one_page+0x1a1/0x6b0
> > > Call Trace:
> > >  <TASK>
> > >  [<ffffffff913208bf>] free_one_page+0xaf/0x240
> > >  [<ffffffff93973288>] deferred_free_pages+0xa8/0xd0
> > >  [<ffffffff93971b4f>] deferred_init_memmap_chunk+0x10f/0x1b0
> > >  [<ffffffff9396e265>] padata_mt_helper+0x65/0xa0
> > >  [<ffffffff90fac402>] process_scheduled_works+0x202/0x410
> > >  [<ffffffff90fae739>] worker_thread+0x1f9/0x2d0
> > >  [<ffffffff90fb62fd>] kthread+0x27d/0x2f0
> > >  [<ffffffff90fae540>] ? __pfx_worker_thread+0x10/0x10
> > >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> > >  [<ffffffff90efdc55>] ret_from_fork+0x145/0x280
> > >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> > >  [<ffffffff90e2e46a>] ret_from_fork_asm+0x1a/0x30
> > >  </TASK>
> > >
> > > deferred_init_memmap_chunk() works fine without KHO because free
> > > regions will never be neighbors. However, with KHO, free memory
> > > will be split into (free && scratch) and (free && !scratch).
> > > KHO scratch is aligned to CMA_MIN_ALIGNMENT_BYTES (which on my setup
> > > is equal to 1 << 9 pages) but buddy can look at the neighborhood of
> > > MAX_ORDER_NR_PAGES pages (which is equal to 1 << 10 pages).
> > > This sometimes crashes when one half of the neighborhood is being
> > > initialized but the other part is yet to be initialized.
> > >
> > > To fix this, let's just align KHO scratch to MAX_ORDER_NR_PAGES pages.
> > >
> > > Fixes: c6073743d0c7 ("kho: make preserved pages compatible with deferred struct page init")
> > > Signed-off-by: Michal Clapinski <mclapinski@google.com>
> > >
> > > diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> > > index 4834a809985ab..50928aaa33710 100644
> > > --- a/kernel/liveupdate/kexec_handover.c
> > > +++ b/kernel/liveupdate/kexec_handover.c
> > > @@ -38,6 +38,16 @@
> > >  #include "../kexec_internal.h"
> > >  #include "kexec_handover_internal.h"
> > >
> > > +/*
> > > + * This is the minimal alignment required by deferred struct page init.
> > > + * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks
> > > + * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.
> > > + * If KHO scratch is not aligned to that value, buddy can access uninitialized
> > > + * struct pages, which can cause a crash.
> > > + */
> > > +#define SCRATCH_ALIGNMENT_BYTES (1 << (PAGE_SHIFT + MAX_PAGE_ORDER))
> > > +static_assert(SCRATCH_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);
> >
> > Maybe make it a variable and set it at runtime?
> > We won't need to worry about different confugurations that override
> > MAX_ORDER and potentail divergence of pageblock size from MAX_ORDER in
>
> Do those architectures reduce MAX_ORDER when they override it? I would
> hope we could set the alignment once and make it large enough to work
> everywhere, rather than depending on dynamic changes even during boot...

MAX_PAGE_ORDER can't be modified at runtime. It's either 10 or it's
CONFIG_ARCH_FORCE_MAX_ORDER.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages
  2026-07-16 15:04   ` Pasha Tatashin
  2026-07-16 15:16     ` Michał Cłapiński
@ 2026-07-16 21:06     ` Mike Rapoport
  1 sibling, 0 replies; 6+ messages in thread
From: Mike Rapoport @ 2026-07-16 21:06 UTC (permalink / raw)
  To: Pasha Tatashin
  Cc: Michal Clapinski, Pratyush Yadav, Alexander Graf,
	Evangelos Petrongonas, kexec, linux-mm, linux-kernel

On Thu, Jul 16, 2026 at 11:04:31AM -0400, Pasha Tatashin wrote:
> On 07-15 09:42, Mike Rapoport wrote:
> > Hi Michal,
> > 
> > > I caught this crash:
> > > BUG: unable to handle page fault for address: ff19164fffff8328
> > > RIP: 0010:__free_one_page+0x1a1/0x6b0
> > > Call Trace:
> > >  <TASK>
> > >  [<ffffffff913208bf>] free_one_page+0xaf/0x240
> > >  [<ffffffff93973288>] deferred_free_pages+0xa8/0xd0
> > >  [<ffffffff93971b4f>] deferred_init_memmap_chunk+0x10f/0x1b0
> > >  [<ffffffff9396e265>] padata_mt_helper+0x65/0xa0
> > >  [<ffffffff90fac402>] process_scheduled_works+0x202/0x410
> > >  [<ffffffff90fae739>] worker_thread+0x1f9/0x2d0
> > >  [<ffffffff90fb62fd>] kthread+0x27d/0x2f0
> > >  [<ffffffff90fae540>] ? __pfx_worker_thread+0x10/0x10
> > >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> > >  [<ffffffff90efdc55>] ret_from_fork+0x145/0x280
> > >  [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
> > >  [<ffffffff90e2e46a>] ret_from_fork_asm+0x1a/0x30
> > >  </TASK>
> > > 
> > > deferred_init_memmap_chunk() works fine without KHO because free
> > > regions will never be neighbors. However, with KHO, free memory
> > > will be split into (free && scratch) and (free && !scratch).
> > > KHO scratch is aligned to CMA_MIN_ALIGNMENT_BYTES (which on my setup
> > > is equal to 1 << 9 pages) but buddy can look at the neighborhood of
> > > MAX_ORDER_NR_PAGES pages (which is equal to 1 << 10 pages).
> > > This sometimes crashes when one half of the neighborhood is being
> > > initialized but the other part is yet to be initialized.
> > > 
> > > To fix this, let's just align KHO scratch to MAX_ORDER_NR_PAGES pages.
> > > 
> > > Fixes: c6073743d0c7 ("kho: make preserved pages compatible with deferred struct page init")
> > > Signed-off-by: Michal Clapinski <mclapinski@google.com>
> > >
> > > diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> > > index 4834a809985ab..50928aaa33710 100644
> > > --- a/kernel/liveupdate/kexec_handover.c
> > > +++ b/kernel/liveupdate/kexec_handover.c
> > > @@ -38,6 +38,16 @@
> > >  #include "../kexec_internal.h"
> > >  #include "kexec_handover_internal.h"
> > >  
> > > +/*
> > > + * This is the minimal alignment required by deferred struct page init.
> > > + * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks
> > > + * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.
> > > + * If KHO scratch is not aligned to that value, buddy can access uninitialized
> > > + * struct pages, which can cause a crash.
> > > + */
> > > +#define SCRATCH_ALIGNMENT_BYTES (1 << (PAGE_SHIFT + MAX_PAGE_ORDER))
> > > +static_assert(SCRATCH_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);
> > 
> > Maybe make it a variable and set it at runtime?
> > We won't need to worry about different confugurations that override
> > MAX_ORDER and potentail divergence of pageblock size from MAX_ORDER in
> 
> Do those architectures reduce MAX_ORDER when they override it? I would 
> hope we could set the alignment once and make it large enough to work 
> everywhere, rather than depending on dynamic changes even during boot...

They could, e.g. arm64 has this:

config ARCH_FORCE_MAX_ORDER
	int
	default "13" if ARM64_64K_PAGES
	default "11" if ARM64_16K_PAGES
	default "10"
 
> > the future.
> > 
> > -- 
> > Sincerely yours,
> > Mike.
> > 

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-07-16 21:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14 20:51 [PATCH] kho: align kho_scratch to MAX_ORDER_NR_PAGES pages Michal Clapinski
2026-07-15  6:42 ` Mike Rapoport
2026-07-15 16:34   ` Michał Cłapiński
2026-07-16 15:04   ` Pasha Tatashin
2026-07-16 15:16     ` Michał Cłapiński
2026-07-16 21:06     ` Mike Rapoport

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.