[RFC PATCH v2 0/2] kho: support preserving unsplit high-order pages
Pranjal Shrivastava
praan at google.com
Mon Jul 13 13:49:33 PDT 2026
Introduction
============
This series is required for the ongoing effort to preserve DMA allocations
across KHO [1]. It addresses a fundamental mismatch between the current KHO
restoration logic and the physical reality of high-order buddy allocations.
The Problem
===========
The current KHO restore implementation treats all multi-page blocks as
split pages during restoration. Specifically, kho_restore_pages()
initializes every 4KB sub-page with a refcount of 1.
However, many kernel subsystems, most notably the DMA allocator (via
dma_alloc_coherent), frequently return high-order non-compound pages.
In this unsplit state, only the head page carries a refcount of 1, while
all tail pages have a refcount of 0.
Consequently, when these contiguous but unsplit blocks are restored by KHO in
the new kernel, the forced reference count of 1 on tail pages causes some
trouble with the buddy allocator. Downstream of the eventual free path,
__free_pages_prepare() [2] ends up calling page_expected_state() [3]
when is_check_pages_enabled() returns true (triggered when CONFIG_DEBUG_VM
is enabled or debug_pagealloc=on).
This detects the unexpected non-zero reference counts on tail pages [4] and
incorrectly taints the kernel while leaking the physical pages in question.
Proposed Solution
=================
Following feedback on the v1 RFC, this series moves away from auto type
detection and instead introduces explicit preserve / restore APIs for
high-order unsplit pages.
Callers are now explicitly specify if a block is unsplit & preserve it by using
kho_preserve_page() and kho_restore_page(). These functions apply a refcount
of 1 to the head page while leaving tail pages at 0.
The existing APIs (kho_preserve_pages / kho_restore_pages) remain as is
for ranges of independent 4KB pages, continuing to use the split refcount.
The internal initialization logic is refactored to provide a helper:
kho_init_unsplit_pages(), which is shared between folios and unsplit page
restore APIs.
[v2]
- Dropped automatic type detection via higher bits in Radix key.
- Introduced explicit kho_preserve_page and kho_restore_page helpers.
- Refactored internal init logic to share code between folios & unsplit pages.
[v1] https://lore.kernel.org/all/20260703020832.1731864-1-praan@google.com/
Thanks,
Praan
[1] https://lore.kernel.org/all/20260708234854.4044652-1-skhawaja@google.com/
[2] https://elixir.bootlin.com/linux/v7.1.1/source/mm/page_alloc.c#L1370
[3] https://elixir.bootlin.com/linux/v7.1.1/source/mm/page_alloc.c#L1027
[4] https://elixir.bootlin.com/linux/v7.1.1/source/mm/page_alloc.c#L1034
Pranjal Shrivastava (2):
kho: Introduce a helper to init unsplit pages
kho: Introduce preserve/restore APIs for unsplit pages
include/linux/kexec_handover.h | 10 +++
kernel/liveupdate/kexec_handover.c | 115 +++++++++++++++++++++++++----
2 files changed, 111 insertions(+), 14 deletions(-)
base-commit: 0f26556c5eeea62cc934fa8938b148aa5844a6b6
--
2.55.0.141.g00534a21ce-goog
More information about the kexec
mailing list