kho: make sure preservations do not span multiple NUMA nodes

The KHO restoration machinery is not capable of dealing with preservations
that span multiple NUMA nodes.  kho_preserve_folio() guarantees the
preservation will only span one NUMA node since folios can't span multiple
nodes.

This leaves kho_preserve_pages().  While semantically kho_preserve_pages()
only deals with 0-order pages, so all preservations should be single page
only, in practice it combines preservations to higher orders for
efficiency.  This can result in a preservation spanning multiple nodes. 
Break up the preservations into a smaller order if that happens.

Link: https://lkml.kernel.org/r/20260309123410.382308-1-pratyush@kernel.org
Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Suggested-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: Alexander Graf <graf@amazon.com>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Pratyush Yadav (Google) 2026-03-09 12:34:06 +00:00 committed by Andrew Morton
parent 396042fb2b
commit 91e74fa8b1

View File

@ -870,9 +870,17 @@ int kho_preserve_pages(struct page *page, unsigned long nr_pages)
} }
while (pfn < end_pfn) { while (pfn < end_pfn) {
const unsigned int order = unsigned int order =
min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn));
/*
* Make sure all the pages in a single preservation are in the
* same NUMA node. The restore machinery can not cope with a
* preservation spanning multiple NUMA nodes.
*/
while (pfn_to_nid(pfn) != pfn_to_nid(pfn + (1UL << order) - 1))
order--;
err = kho_radix_add_page(tree, pfn, order); err = kho_radix_add_page(tree, pfn, order);
if (err) { if (err) {
failed_pfn = pfn; failed_pfn = pfn;