* FAILED: patch "[PATCH] kho: make sure scratch size is always aligned by" failed to apply to 6.18-stable tree
@ 2026-07-20 14:31 gregkh
2026-07-25 10:54 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Sasha Levin
0 siblings, 1 reply; 5+ messages in thread
From: gregkh @ 2026-07-20 14:31 UTC (permalink / raw)
To: pratyush, pasha.tatashin, rppt; +Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 0e39380a7316122e1b00012b3f3cd3e318b3e7d3
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026072031-lapping-tubby-5b19@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0e39380a7316122e1b00012b3f3cd3e318b3e7d3 Mon Sep 17 00:00:00 2001
From: "Pratyush Yadav (Google)" <pratyush@kernel.org>
Date: Tue, 19 May 2026 18:05:49 +0200
Subject: [PATCH] kho: make sure scratch size is always aligned by
CMA_MIN_ALIGNMENT_BYTES
When using scratch_scale, the scratch sizes are rounded up to
CMA_MIN_ALIGNMENT_BYTES since they will be released as MIGRATE_CMA. This
is not done when using fixed scratch sizes via command line. This can
result in user specifying a size which is not aligned, and thus kernel
releasing a pageblock that is only partially scratch.
Do the rounding up for both cases in scratch_size_update().
Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers")
Cc: stable@kernel.org
Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Link: https://patch.msgid.link/20260519160554.2713361-1-pratyush@kernel.org
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index eb8abd04e7ff..4834a809985a 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -618,20 +618,30 @@ early_param("kho_scratch", kho_parse_scratch_size);
static void __init scratch_size_update(void)
{
- phys_addr_t size;
+ /*
+ * If fixed sizes are not provided via command line, calculate them
+ * now.
+ */
+ if (scratch_scale) {
+ phys_addr_t size;
- if (!scratch_scale)
- return;
+ size = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT,
+ NUMA_NO_NODE);
+ size = size * scratch_scale / 100;
+ scratch_size_lowmem = size;
- size = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT,
- NUMA_NO_NODE);
- size = size * scratch_scale / 100;
- scratch_size_lowmem = round_up(size, CMA_MIN_ALIGNMENT_BYTES);
+ size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
+ NUMA_NO_NODE);
+ size = size * scratch_scale / 100 - scratch_size_lowmem;
+ scratch_size_global = size;
+ }
- size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
- NUMA_NO_NODE);
- size = size * scratch_scale / 100 - scratch_size_lowmem;
- scratch_size_global = round_up(size, CMA_MIN_ALIGNMENT_BYTES);
+ /*
+ * 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);
}
static phys_addr_t __init scratch_size_node(int nid)
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc 2026-07-20 14:31 FAILED: patch "[PATCH] kho: make sure scratch size is always aligned by" failed to apply to 6.18-stable tree gregkh @ 2026-07-25 10:54 ` Sasha Levin 2026-07-25 10:54 ` [PATCH 6.18.y 2/2] kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES Sasha Levin 2026-07-30 12:33 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Greg KH 0 siblings, 2 replies; 5+ messages in thread From: Sasha Levin @ 2026-07-25 10:54 UTC (permalink / raw) To: stable Cc: Pasha Tatashin, Pratyush Yadav, Mike Rapoport (Microsoft), Alexander Graf, Changyuan Lyu, Christian Brauner, Jason Gunthorpe, Jason Gunthorpe, Jonathan Corbet, Masahiro Yamada, Miguel Ojeda, Randy Dunlap, Simon Horman, Tejun Heo, Zhu Yanjun, Andrew Morton, Sasha Levin From: Pasha Tatashin <pasha.tatashin@soleen.com> [ Upstream commit 36f8f7ef7fd2f238922e9d217e86c69838319d8c ] Allow users of KHO to cancel the previous preservation by adding the necessary interfaces to unpreserve folio, pages, and vmallocs. Link: https://lkml.kernel.org/r/20251101142325.1326536-4-pasha.tatashin@soleen.com Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> Reviewed-by: Pratyush Yadav <pratyush@kernel.org> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: Alexander Graf <graf@amazon.com> Cc: Changyuan Lyu <changyuanl@google.com> Cc: Christian Brauner <brauner@kernel.org> Cc: Jason Gunthorpe <jgg@nvidia.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Masahiro Yamada <masahiroy@kernel.org> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Simon Horman <horms@kernel.org> Cc: Tejun Heo <tj@kernel.org> Cc: Zhu Yanjun <yanjun.zhu@linux.dev> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Stable-dep-of: 0e39380a7316 ("kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES") Signed-off-by: Sasha Levin <sashal@kernel.org> --- include/linux/kexec_handover.h | 18 ++++++ kernel/kexec_handover.c | 104 ++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 13 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 25042c1d8d54af..e1af332a262fba 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -52,8 +52,11 @@ bool kho_is_enabled(void); bool is_kho_boot(void); int kho_preserve_folio(struct folio *folio); +int kho_unpreserve_folio(struct folio *folio); int kho_preserve_pages(struct page *page, unsigned int nr_pages); +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages); int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation); +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation); struct folio *kho_restore_folio(phys_addr_t phys); struct page *kho_restore_pages(phys_addr_t phys, unsigned int nr_pages); void *kho_restore_vmalloc(const struct kho_vmalloc *preservation); @@ -83,17 +86,32 @@ static inline int kho_preserve_folio(struct folio *folio) return -EOPNOTSUPP; } +static inline int kho_unpreserve_folio(struct folio *folio) +{ + return -EOPNOTSUPP; +} + static inline int kho_preserve_pages(struct page *page, unsigned int nr_pages) { return -EOPNOTSUPP; } +static inline int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) +{ + return -EOPNOTSUPP; +} + static inline int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation) { return -EOPNOTSUPP; } +static inline int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) +{ + return -EOPNOTSUPP; +} + static inline struct folio *kho_restore_folio(phys_addr_t phys) { return NULL; diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index c13b99f7c9891e..37e6048118e8b7 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -153,26 +153,33 @@ static void *xa_load_or_alloc(struct xarray *xa, unsigned long index) return no_free_ptr(elm); } -static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, - unsigned long end_pfn) +static void __kho_unpreserve_order(struct kho_mem_track *track, unsigned long pfn, + unsigned int order) { struct kho_mem_phys_bits *bits; struct kho_mem_phys *physxa; + const unsigned long pfn_high = pfn >> order; - while (pfn < end_pfn) { - const unsigned int order = - min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); - const unsigned long pfn_high = pfn >> order; + physxa = xa_load(&track->orders, order); + if (WARN_ON_ONCE(!physxa)) + return; - physxa = xa_load(&track->orders, order); - if (WARN_ON_ONCE(!physxa)) - return; + bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); + if (WARN_ON_ONCE(!bits)) + return; + + clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); +} + +static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, + unsigned long end_pfn) +{ + unsigned int order; - bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); - if (WARN_ON_ONCE(!bits)) - return; + while (pfn < end_pfn) { + order = min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); - clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); + __kho_unpreserve_order(track, pfn, order); pfn += 1 << order; } @@ -739,6 +746,30 @@ int kho_preserve_folio(struct folio *folio) } EXPORT_SYMBOL_GPL(kho_preserve_folio); +/** + * kho_unpreserve_folio - unpreserve a folio. + * @folio: folio to unpreserve. + * + * Instructs KHO to unpreserve a folio that was preserved by + * kho_preserve_folio() before. The provided @folio (pfn and order) + * must exactly match a previously preserved folio. + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_folio(struct folio *folio) +{ + const unsigned long pfn = folio_pfn(folio); + const unsigned int order = folio_order(folio); + struct kho_mem_track *track = &kho_out.track; + + if (kho_out.finalized) + return -EBUSY; + + __kho_unpreserve_order(track, pfn, order); + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_folio); + /** * kho_preserve_pages - preserve contiguous pages across kexec * @page: first page in the list. @@ -783,6 +814,33 @@ int kho_preserve_pages(struct page *page, unsigned int nr_pages) } EXPORT_SYMBOL_GPL(kho_preserve_pages); +/** + * kho_unpreserve_pages - unpreserve contiguous pages. + * @page: first page in the list. + * @nr_pages: number of pages. + * + * Instructs KHO to unpreserve @nr_pages contiguous pages starting from @page. + * This must be called with the same @page and @nr_pages as the corresponding + * kho_preserve_pages() call. Unpreserving arbitrary sub-ranges of larger + * preserved blocks is not supported. + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) +{ + struct kho_mem_track *track = &kho_out.track; + const unsigned long start_pfn = page_to_pfn(page); + const unsigned long end_pfn = start_pfn + nr_pages; + + if (kho_out.finalized) + return -EBUSY; + + __kho_unpreserve(track, start_pfn, end_pfn); + + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_pages); + struct kho_vmalloc_hdr { DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *); }; @@ -944,6 +1002,26 @@ int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation) } EXPORT_SYMBOL_GPL(kho_preserve_vmalloc); +/** + * kho_unpreserve_vmalloc - unpreserve memory allocated with vmalloc() + * @preservation: preservation metadata returned by kho_preserve_vmalloc() + * + * Instructs KHO to unpreserve the area in vmalloc address space that was + * previously preserved with kho_preserve_vmalloc(). + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) +{ + if (kho_out.finalized) + return -EBUSY; + + kho_vmalloc_free_chunks(preservation); + + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_vmalloc); + /** * kho_restore_vmalloc - recreates and populates an area in vmalloc address * space from the preserved memory. -- 2.53.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 2/2] kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES 2026-07-25 10:54 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Sasha Levin @ 2026-07-25 10:54 ` Sasha Levin 2026-07-30 12:33 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Greg KH 1 sibling, 0 replies; 5+ messages in thread From: Sasha Levin @ 2026-07-25 10:54 UTC (permalink / raw) To: stable Cc: Pratyush Yadav (Google), stable, Pasha Tatashin, Mike Rapoport (Microsoft), Sasha Levin From: "Pratyush Yadav (Google)" <pratyush@kernel.org> [ Upstream commit 0e39380a7316122e1b00012b3f3cd3e318b3e7d3 ] When using scratch_scale, the scratch sizes are rounded up to CMA_MIN_ALIGNMENT_BYTES since they will be released as MIGRATE_CMA. This is not done when using fixed scratch sizes via command line. This can result in user specifying a size which is not aligned, and thus kernel releasing a pageblock that is only partially scratch. Do the rounding up for both cases in scratch_size_update(). Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers") Cc: stable@kernel.org Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org> Link: https://patch.msgid.link/20260519160554.2713361-1-pratyush@kernel.org Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> --- kernel/kexec_handover.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index 37e6048118e8b7..bd10660db469a2 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -569,20 +569,30 @@ early_param("kho_scratch", kho_parse_scratch_size); static void __init scratch_size_update(void) { - phys_addr_t size; + /* + * If fixed sizes are not provided via command line, calculate them + * now. + */ + if (scratch_scale) { + phys_addr_t size; - if (!scratch_scale) - return; + size = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT, + NUMA_NO_NODE); + size = size * scratch_scale / 100; + scratch_size_lowmem = size; - size = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT, - NUMA_NO_NODE); - size = size * scratch_scale / 100; - scratch_size_lowmem = round_up(size, CMA_MIN_ALIGNMENT_BYTES); + size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE, + NUMA_NO_NODE); + size = size * scratch_scale / 100 - scratch_size_lowmem; + scratch_size_global = size; + } - size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE, - NUMA_NO_NODE); - size = size * scratch_scale / 100 - scratch_size_lowmem; - scratch_size_global = round_up(size, CMA_MIN_ALIGNMENT_BYTES); + /* + * 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); } static phys_addr_t __init scratch_size_node(int nid) -- 2.53.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc 2026-07-25 10:54 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Sasha Levin 2026-07-25 10:54 ` [PATCH 6.18.y 2/2] kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES Sasha Levin @ 2026-07-30 12:33 ` Greg KH 2026-07-30 12:34 ` Greg KH 1 sibling, 1 reply; 5+ messages in thread From: Greg KH @ 2026-07-30 12:33 UTC (permalink / raw) To: Sasha Levin Cc: stable, Pasha Tatashin, Pratyush Yadav, Mike Rapoport (Microsoft), Alexander Graf, Changyuan Lyu, Christian Brauner, Jason Gunthorpe, Jason Gunthorpe, Jonathan Corbet, Masahiro Yamada, Miguel Ojeda, Randy Dunlap, Simon Horman, Tejun Heo, Zhu Yanjun, Andrew Morton On Sat, Jul 25, 2026 at 06:54:32AM -0400, Sasha Levin wrote: > From: Pasha Tatashin <pasha.tatashin@soleen.com> > > [ Upstream commit 36f8f7ef7fd2f238922e9d217e86c69838319d8c ] > > Allow users of KHO to cancel the previous preservation by adding the > necessary interfaces to unpreserve folio, pages, and vmallocs. > > Link: https://lkml.kernel.org/r/20251101142325.1326536-4-pasha.tatashin@soleen.com > Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> > Reviewed-by: Pratyush Yadav <pratyush@kernel.org> > Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> > Cc: Alexander Graf <graf@amazon.com> > Cc: Changyuan Lyu <changyuanl@google.com> > Cc: Christian Brauner <brauner@kernel.org> > Cc: Jason Gunthorpe <jgg@nvidia.com> > Cc: Jason Gunthorpe <jgg@ziepe.ca> > Cc: Jonathan Corbet <corbet@lwn.net> > Cc: Masahiro Yamada <masahiroy@kernel.org> > Cc: Miguel Ojeda <ojeda@kernel.org> > Cc: Randy Dunlap <rdunlap@infradead.org> > Cc: Simon Horman <horms@kernel.org> > Cc: Tejun Heo <tj@kernel.org> > Cc: Zhu Yanjun <yanjun.zhu@linux.dev> > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > Stable-dep-of: 0e39380a7316 ("kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES") > Signed-off-by: Sasha Levin <sashal@kernel.org> > --- > include/linux/kexec_handover.h | 18 ++++++ > kernel/kexec_handover.c | 104 ++++++++++++++++++++++++++++----- > 2 files changed, 109 insertions(+), 13 deletions(-) > > diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h > index 25042c1d8d54af..e1af332a262fba 100644 > --- a/include/linux/kexec_handover.h > +++ b/include/linux/kexec_handover.h > @@ -52,8 +52,11 @@ bool kho_is_enabled(void); > bool is_kho_boot(void); > > int kho_preserve_folio(struct folio *folio); > +int kho_unpreserve_folio(struct folio *folio); > int kho_preserve_pages(struct page *page, unsigned int nr_pages); > +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages); > int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation); > +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation); > struct folio *kho_restore_folio(phys_addr_t phys); > struct page *kho_restore_pages(phys_addr_t phys, unsigned int nr_pages); > void *kho_restore_vmalloc(const struct kho_vmalloc *preservation); > @@ -83,17 +86,32 @@ static inline int kho_preserve_folio(struct folio *folio) > return -EOPNOTSUPP; > } > > +static inline int kho_unpreserve_folio(struct folio *folio) > +{ > + return -EOPNOTSUPP; > +} > + > static inline int kho_preserve_pages(struct page *page, unsigned int nr_pages) > { > return -EOPNOTSUPP; > } > > +static inline int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) > +{ > + return -EOPNOTSUPP; > +} > + > static inline int kho_preserve_vmalloc(void *ptr, > struct kho_vmalloc *preservation) > { > return -EOPNOTSUPP; > } > > +static inline int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) > +{ > + return -EOPNOTSUPP; > +} > + > static inline struct folio *kho_restore_folio(phys_addr_t phys) > { > return NULL; > diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c > index c13b99f7c9891e..37e6048118e8b7 100644 > --- a/kernel/kexec_handover.c > +++ b/kernel/kexec_handover.c > @@ -153,26 +153,33 @@ static void *xa_load_or_alloc(struct xarray *xa, unsigned long index) > return no_free_ptr(elm); > } > > -static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, > - unsigned long end_pfn) > +static void __kho_unpreserve_order(struct kho_mem_track *track, unsigned long pfn, > + unsigned int order) > { > struct kho_mem_phys_bits *bits; > struct kho_mem_phys *physxa; > + const unsigned long pfn_high = pfn >> order; > > - while (pfn < end_pfn) { > - const unsigned int order = > - min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); > - const unsigned long pfn_high = pfn >> order; > + physxa = xa_load(&track->orders, order); > + if (WARN_ON_ONCE(!physxa)) > + return; > > - physxa = xa_load(&track->orders, order); > - if (WARN_ON_ONCE(!physxa)) > - return; > + bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); > + if (WARN_ON_ONCE(!bits)) > + return; > + > + clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); > +} > + > +static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, > + unsigned long end_pfn) > +{ > + unsigned int order; > > - bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); > - if (WARN_ON_ONCE(!bits)) > - return; > + while (pfn < end_pfn) { > + order = min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); > > - clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); > + __kho_unpreserve_order(track, pfn, order); > > pfn += 1 << order; > } > @@ -739,6 +746,30 @@ int kho_preserve_folio(struct folio *folio) > } > EXPORT_SYMBOL_GPL(kho_preserve_folio); > > +/** > + * kho_unpreserve_folio - unpreserve a folio. > + * @folio: folio to unpreserve. > + * > + * Instructs KHO to unpreserve a folio that was preserved by > + * kho_preserve_folio() before. The provided @folio (pfn and order) > + * must exactly match a previously preserved folio. > + * > + * Return: 0 on success, error code on failure > + */ > +int kho_unpreserve_folio(struct folio *folio) > +{ > + const unsigned long pfn = folio_pfn(folio); > + const unsigned int order = folio_order(folio); > + struct kho_mem_track *track = &kho_out.track; > + > + if (kho_out.finalized) > + return -EBUSY; > + > + __kho_unpreserve_order(track, pfn, order); > + return 0; > +} > +EXPORT_SYMBOL_GPL(kho_unpreserve_folio); > + > /** > * kho_preserve_pages - preserve contiguous pages across kexec > * @page: first page in the list. > @@ -783,6 +814,33 @@ int kho_preserve_pages(struct page *page, unsigned int nr_pages) > } > EXPORT_SYMBOL_GPL(kho_preserve_pages); > > +/** > + * kho_unpreserve_pages - unpreserve contiguous pages. > + * @page: first page in the list. > + * @nr_pages: number of pages. > + * > + * Instructs KHO to unpreserve @nr_pages contiguous pages starting from @page. > + * This must be called with the same @page and @nr_pages as the corresponding > + * kho_preserve_pages() call. Unpreserving arbitrary sub-ranges of larger > + * preserved blocks is not supported. > + * > + * Return: 0 on success, error code on failure > + */ > +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) > +{ > + struct kho_mem_track *track = &kho_out.track; > + const unsigned long start_pfn = page_to_pfn(page); > + const unsigned long end_pfn = start_pfn + nr_pages; > + > + if (kho_out.finalized) > + return -EBUSY; > + > + __kho_unpreserve(track, start_pfn, end_pfn); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(kho_unpreserve_pages); > + > struct kho_vmalloc_hdr { > DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *); > }; > @@ -944,6 +1002,26 @@ int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation) > } > EXPORT_SYMBOL_GPL(kho_preserve_vmalloc); > > +/** > + * kho_unpreserve_vmalloc - unpreserve memory allocated with vmalloc() > + * @preservation: preservation metadata returned by kho_preserve_vmalloc() > + * > + * Instructs KHO to unpreserve the area in vmalloc address space that was > + * previously preserved with kho_preserve_vmalloc(). > + * > + * Return: 0 on success, error code on failure > + */ > +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) > +{ > + if (kho_out.finalized) > + return -EBUSY; > + > + kho_vmalloc_free_chunks(preservation); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(kho_unpreserve_vmalloc); > + > /** > * kho_restore_vmalloc - recreates and populates an area in vmalloc address > * space from the preserved memory. > -- > 2.53.0 > > Oops, nope, dropped this and patch 2/2 as this causes a build error :( ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc 2026-07-30 12:33 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Greg KH @ 2026-07-30 12:34 ` Greg KH 0 siblings, 0 replies; 5+ messages in thread From: Greg KH @ 2026-07-30 12:34 UTC (permalink / raw) To: Sasha Levin Cc: stable, Pasha Tatashin, Pratyush Yadav, Mike Rapoport (Microsoft), Alexander Graf, Changyuan Lyu, Christian Brauner, Jason Gunthorpe, Jason Gunthorpe, Jonathan Corbet, Masahiro Yamada, Miguel Ojeda, Randy Dunlap, Simon Horman, Tejun Heo, Zhu Yanjun, Andrew Morton On Thu, Jul 30, 2026 at 02:33:30PM +0200, Greg KH wrote: > On Sat, Jul 25, 2026 at 06:54:32AM -0400, Sasha Levin wrote: > > From: Pasha Tatashin <pasha.tatashin@soleen.com> > > > > [ Upstream commit 36f8f7ef7fd2f238922e9d217e86c69838319d8c ] > > > > Allow users of KHO to cancel the previous preservation by adding the > > necessary interfaces to unpreserve folio, pages, and vmallocs. > > > > Link: https://lkml.kernel.org/r/20251101142325.1326536-4-pasha.tatashin@soleen.com > > Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> > > Reviewed-by: Pratyush Yadav <pratyush@kernel.org> > > Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> > > Cc: Alexander Graf <graf@amazon.com> > > Cc: Changyuan Lyu <changyuanl@google.com> > > Cc: Christian Brauner <brauner@kernel.org> > > Cc: Jason Gunthorpe <jgg@nvidia.com> > > Cc: Jason Gunthorpe <jgg@ziepe.ca> > > Cc: Jonathan Corbet <corbet@lwn.net> > > Cc: Masahiro Yamada <masahiroy@kernel.org> > > Cc: Miguel Ojeda <ojeda@kernel.org> > > Cc: Randy Dunlap <rdunlap@infradead.org> > > Cc: Simon Horman <horms@kernel.org> > > Cc: Tejun Heo <tj@kernel.org> > > Cc: Zhu Yanjun <yanjun.zhu@linux.dev> > > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > > Stable-dep-of: 0e39380a7316 ("kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES") > > Signed-off-by: Sasha Levin <sashal@kernel.org> > > --- > > include/linux/kexec_handover.h | 18 ++++++ > > kernel/kexec_handover.c | 104 ++++++++++++++++++++++++++++----- > > 2 files changed, 109 insertions(+), 13 deletions(-) > > > > diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h > > index 25042c1d8d54af..e1af332a262fba 100644 > > --- a/include/linux/kexec_handover.h > > +++ b/include/linux/kexec_handover.h > > @@ -52,8 +52,11 @@ bool kho_is_enabled(void); > > bool is_kho_boot(void); > > > > int kho_preserve_folio(struct folio *folio); > > +int kho_unpreserve_folio(struct folio *folio); > > int kho_preserve_pages(struct page *page, unsigned int nr_pages); > > +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages); > > int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation); > > +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation); > > struct folio *kho_restore_folio(phys_addr_t phys); > > struct page *kho_restore_pages(phys_addr_t phys, unsigned int nr_pages); > > void *kho_restore_vmalloc(const struct kho_vmalloc *preservation); > > @@ -83,17 +86,32 @@ static inline int kho_preserve_folio(struct folio *folio) > > return -EOPNOTSUPP; > > } > > > > +static inline int kho_unpreserve_folio(struct folio *folio) > > +{ > > + return -EOPNOTSUPP; > > +} > > + > > static inline int kho_preserve_pages(struct page *page, unsigned int nr_pages) > > { > > return -EOPNOTSUPP; > > } > > > > +static inline int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) > > +{ > > + return -EOPNOTSUPP; > > +} > > + > > static inline int kho_preserve_vmalloc(void *ptr, > > struct kho_vmalloc *preservation) > > { > > return -EOPNOTSUPP; > > } > > > > +static inline int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) > > +{ > > + return -EOPNOTSUPP; > > +} > > + > > static inline struct folio *kho_restore_folio(phys_addr_t phys) > > { > > return NULL; > > diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c > > index c13b99f7c9891e..37e6048118e8b7 100644 > > --- a/kernel/kexec_handover.c > > +++ b/kernel/kexec_handover.c > > @@ -153,26 +153,33 @@ static void *xa_load_or_alloc(struct xarray *xa, unsigned long index) > > return no_free_ptr(elm); > > } > > > > -static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, > > - unsigned long end_pfn) > > +static void __kho_unpreserve_order(struct kho_mem_track *track, unsigned long pfn, > > + unsigned int order) > > { > > struct kho_mem_phys_bits *bits; > > struct kho_mem_phys *physxa; > > + const unsigned long pfn_high = pfn >> order; > > > > - while (pfn < end_pfn) { > > - const unsigned int order = > > - min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); > > - const unsigned long pfn_high = pfn >> order; > > + physxa = xa_load(&track->orders, order); > > + if (WARN_ON_ONCE(!physxa)) > > + return; > > > > - physxa = xa_load(&track->orders, order); > > - if (WARN_ON_ONCE(!physxa)) > > - return; > > + bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); > > + if (WARN_ON_ONCE(!bits)) > > + return; > > + > > + clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); > > +} > > + > > +static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, > > + unsigned long end_pfn) > > +{ > > + unsigned int order; > > > > - bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); > > - if (WARN_ON_ONCE(!bits)) > > - return; > > + while (pfn < end_pfn) { > > + order = min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); > > > > - clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); > > + __kho_unpreserve_order(track, pfn, order); > > > > pfn += 1 << order; > > } > > @@ -739,6 +746,30 @@ int kho_preserve_folio(struct folio *folio) > > } > > EXPORT_SYMBOL_GPL(kho_preserve_folio); > > > > +/** > > + * kho_unpreserve_folio - unpreserve a folio. > > + * @folio: folio to unpreserve. > > + * > > + * Instructs KHO to unpreserve a folio that was preserved by > > + * kho_preserve_folio() before. The provided @folio (pfn and order) > > + * must exactly match a previously preserved folio. > > + * > > + * Return: 0 on success, error code on failure > > + */ > > +int kho_unpreserve_folio(struct folio *folio) > > +{ > > + const unsigned long pfn = folio_pfn(folio); > > + const unsigned int order = folio_order(folio); > > + struct kho_mem_track *track = &kho_out.track; > > + > > + if (kho_out.finalized) > > + return -EBUSY; > > + > > + __kho_unpreserve_order(track, pfn, order); > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(kho_unpreserve_folio); > > + > > /** > > * kho_preserve_pages - preserve contiguous pages across kexec > > * @page: first page in the list. > > @@ -783,6 +814,33 @@ int kho_preserve_pages(struct page *page, unsigned int nr_pages) > > } > > EXPORT_SYMBOL_GPL(kho_preserve_pages); > > > > +/** > > + * kho_unpreserve_pages - unpreserve contiguous pages. > > + * @page: first page in the list. > > + * @nr_pages: number of pages. > > + * > > + * Instructs KHO to unpreserve @nr_pages contiguous pages starting from @page. > > + * This must be called with the same @page and @nr_pages as the corresponding > > + * kho_preserve_pages() call. Unpreserving arbitrary sub-ranges of larger > > + * preserved blocks is not supported. > > + * > > + * Return: 0 on success, error code on failure > > + */ > > +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) > > +{ > > + struct kho_mem_track *track = &kho_out.track; > > + const unsigned long start_pfn = page_to_pfn(page); > > + const unsigned long end_pfn = start_pfn + nr_pages; > > + > > + if (kho_out.finalized) > > + return -EBUSY; > > + > > + __kho_unpreserve(track, start_pfn, end_pfn); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(kho_unpreserve_pages); > > + > > struct kho_vmalloc_hdr { > > DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *); > > }; > > @@ -944,6 +1002,26 @@ int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation) > > } > > EXPORT_SYMBOL_GPL(kho_preserve_vmalloc); > > > > +/** > > + * kho_unpreserve_vmalloc - unpreserve memory allocated with vmalloc() > > + * @preservation: preservation metadata returned by kho_preserve_vmalloc() > > + * > > + * Instructs KHO to unpreserve the area in vmalloc address space that was > > + * previously preserved with kho_preserve_vmalloc(). > > + * > > + * Return: 0 on success, error code on failure > > + */ > > +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) > > +{ > > + if (kho_out.finalized) > > + return -EBUSY; > > + > > + kho_vmalloc_free_chunks(preservation); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(kho_unpreserve_vmalloc); > > + > > /** > > * kho_restore_vmalloc - recreates and populates an area in vmalloc address > > * space from the preserved memory. > > -- > > 2.53.0 > > > > > > Oops, nope, dropped this and patch 2/2 as this causes a build error :( > > Actually patch 2/2 works just fine on it's own, so I've kept that. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-30 12:34 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-20 14:31 FAILED: patch "[PATCH] kho: make sure scratch size is always aligned by" failed to apply to 6.18-stable tree gregkh 2026-07-25 10:54 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Sasha Levin 2026-07-25 10:54 ` [PATCH 6.18.y 2/2] kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES Sasha Levin 2026-07-30 12:33 ` [PATCH 6.18.y 1/2] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Greg KH 2026-07-30 12:34 ` Greg KH
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox