Skip to content

Commit 9d87d0f

Browse files
committed
Merge tag 'liveupdate-fixes-2026-05-30' of git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux
Pull liveupdate fixes from Mike Rapoport: "Two kexec handover regression fixes: - fix order calculation for kho_unpreserve_pages() to make sure sure that the order calculation in kho_unpreserve_pages() mathes the order calculation in kho_preserve_pages(). - fix math in calculation of KHO_TREE_MAX_DEPTH to make it work with 16KB pages" * tag 'liveupdate-fixes-2026-05-30' of git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux: kho: fix order calculation for kho_unpreserve_pages() kho: fix KHO_TREE_MAX_DEPTH for non-4KB page sizes
2 parents a29c0b0 + 8fd2f26 commit 9d87d0f

2 files changed

Lines changed: 33 additions & 25 deletions

File tree

include/linux/kho/abi/kexec_handover.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ enum kho_radix_consts {
274274
* and 1 bitmap level.
275275
*/
276276
KHO_TREE_MAX_DEPTH =
277-
DIV_ROUND_UP(KHO_ORDER_0_LOG2 - KHO_BITMAP_SIZE_LOG2,
277+
DIV_ROUND_UP(KHO_ORDER_0_LOG2 - KHO_BITMAP_SIZE_LOG2 + 1,
278278
KHO_TABLE_SIZE_LOG2) + 1,
279279
};
280280

kernel/liveupdate/kexec_handover.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -357,20 +357,6 @@ int kho_radix_walk_tree(struct kho_radix_tree *tree,
357357
}
358358
EXPORT_SYMBOL_GPL(kho_radix_walk_tree);
359359

360-
static void __kho_unpreserve(struct kho_radix_tree *tree,
361-
unsigned long pfn, unsigned long end_pfn)
362-
{
363-
unsigned int order;
364-
365-
while (pfn < end_pfn) {
366-
order = min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn));
367-
368-
kho_radix_del_page(tree, pfn, order);
369-
370-
pfn += 1 << order;
371-
}
372-
}
373-
374360
/* For physically contiguous 0-order pages. */
375361
static void kho_init_pages(struct page *page, unsigned long nr_pages)
376362
{
@@ -860,6 +846,37 @@ void kho_unpreserve_folio(struct folio *folio)
860846
}
861847
EXPORT_SYMBOL_GPL(kho_unpreserve_folio);
862848

849+
static unsigned int __kho_preserve_pages_order(unsigned long start_pfn,
850+
unsigned long end_pfn)
851+
{
852+
unsigned int order = min(count_trailing_zeros(start_pfn),
853+
ilog2(end_pfn - start_pfn));
854+
855+
/*
856+
* Make sure all the pages in a single preservation are in the same NUMA
857+
* node. The restore machinery can not cope with a preservation spanning
858+
* multiple NUMA nodes.
859+
*/
860+
while (pfn_to_nid(start_pfn) != pfn_to_nid(start_pfn + (1UL << order) - 1))
861+
order--;
862+
863+
return order;
864+
}
865+
866+
static void __kho_unpreserve(struct kho_radix_tree *tree,
867+
unsigned long pfn, unsigned long end_pfn)
868+
{
869+
unsigned int order;
870+
871+
while (pfn < end_pfn) {
872+
order = __kho_preserve_pages_order(pfn, end_pfn);
873+
874+
kho_radix_del_page(tree, pfn, order);
875+
876+
pfn += 1 << order;
877+
}
878+
}
879+
863880
/**
864881
* kho_preserve_pages - preserve contiguous pages across kexec
865882
* @page: first page in the list.
@@ -885,16 +902,7 @@ int kho_preserve_pages(struct page *page, unsigned long nr_pages)
885902
}
886903

887904
while (pfn < end_pfn) {
888-
unsigned int order =
889-
min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn));
890-
891-
/*
892-
* Make sure all the pages in a single preservation are in the
893-
* same NUMA node. The restore machinery can not cope with a
894-
* preservation spanning multiple NUMA nodes.
895-
*/
896-
while (pfn_to_nid(pfn) != pfn_to_nid(pfn + (1UL << order) - 1))
897-
order--;
905+
unsigned int order = __kho_preserve_pages_order(pfn, end_pfn);
898906

899907
err = kho_radix_add_page(tree, pfn, order);
900908
if (err) {

0 commit comments

Comments
 (0)