Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kho: check if kho is finalized in __kho_preserve_order()

Patch series "kho: add support for preserving vmalloc allocations", v5.

Following the discussion about preservation of memfd with LUO [1] these
patches add support for preserving vmalloc allocations.

Any KHO uses case presumes that there's a data structure that lists
physical addresses of preserved folios (and potentially some additional
metadata). Allowing vmalloc preservations with KHO allows scalable
preservation of such data structures.

For instance, instead of allocating array describing preserved folios in
the fdt, memfd preservation can use vmalloc:

preserved_folios = vmalloc_array(nr_folios, sizeof(*preserved_folios));
memfd_luo_preserve_folios(preserved_folios, folios, nr_folios);
kho_preserve_vmalloc(preserved_folios, &folios_info);


This patch (of 4):

Instead of checking if kho is finalized in each caller of
__kho_preserve_order(), do it in the core function itself.

Link: https://lkml.kernel.org/r/20250921054458.4043761-1-rppt@kernel.org
Link: https://lkml.kernel.org/r/20250921054458.4043761-2-rppt@kernel.org
Link: https://lore.kernel.org/all/20250807014442.3829950-30-pasha.tatashin@soleen.com [1]
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
Cc: Alexander Graf <graf@amazon.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Changyuan Lyu <changyuanl@google.com>
Cc: Chris Li <chrisl@kernel.org>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Mike Rapoport (Microsoft) and committed by
Andrew Morton
469661d0 fa02d505

+26 -29
+26 -29
kernel/kexec_handover.c
··· 107 107 struct khoser_mem_chunk *preserved_mem_map; 108 108 }; 109 109 110 + struct kho_out { 111 + struct blocking_notifier_head chain_head; 112 + 113 + struct dentry *dir; 114 + 115 + struct mutex lock; /* protects KHO FDT finalization */ 116 + 117 + struct kho_serialization ser; 118 + bool finalized; 119 + }; 120 + 121 + static struct kho_out kho_out = { 122 + .chain_head = BLOCKING_NOTIFIER_INIT(kho_out.chain_head), 123 + .lock = __MUTEX_INITIALIZER(kho_out.lock), 124 + .ser = { 125 + .fdt_list = LIST_HEAD_INIT(kho_out.ser.fdt_list), 126 + .track = { 127 + .orders = XARRAY_INIT(kho_out.ser.track.orders, 0), 128 + }, 129 + }, 130 + .finalized = false, 131 + }; 132 + 110 133 static void *xa_load_or_alloc(struct xarray *xa, unsigned long index, size_t sz) 111 134 { 112 135 void *elm, *res; ··· 187 164 const unsigned long pfn_high = pfn >> order; 188 165 189 166 might_sleep(); 167 + 168 + if (kho_out.finalized) 169 + return -EBUSY; 190 170 191 171 physxa = xa_load(&track->orders, order); 192 172 if (!physxa) { ··· 693 667 } 694 668 EXPORT_SYMBOL_GPL(kho_add_subtree); 695 669 696 - struct kho_out { 697 - struct blocking_notifier_head chain_head; 698 - 699 - struct dentry *dir; 700 - 701 - struct mutex lock; /* protects KHO FDT finalization */ 702 - 703 - struct kho_serialization ser; 704 - bool finalized; 705 - }; 706 - 707 - static struct kho_out kho_out = { 708 - .chain_head = BLOCKING_NOTIFIER_INIT(kho_out.chain_head), 709 - .lock = __MUTEX_INITIALIZER(kho_out.lock), 710 - .ser = { 711 - .fdt_list = LIST_HEAD_INIT(kho_out.ser.fdt_list), 712 - .track = { 713 - .orders = XARRAY_INIT(kho_out.ser.track.orders, 0), 714 - }, 715 - }, 716 - .finalized = false, 717 - }; 718 - 719 670 int register_kho_notifier(struct notifier_block *nb) 720 671 { 721 672 return blocking_notifier_chain_register(&kho_out.chain_head, nb); ··· 720 717 const unsigned int order = folio_order(folio); 721 718 struct kho_mem_track *track = &kho_out.ser.track; 722 719 723 - if (kho_out.finalized) 724 - return -EBUSY; 725 - 726 720 return __kho_preserve_order(track, pfn, order); 727 721 } 728 722 EXPORT_SYMBOL_GPL(kho_preserve_folio); ··· 742 742 const unsigned long end_pfn = PHYS_PFN(phys + size); 743 743 int err = 0; 744 744 struct kho_mem_track *track = &kho_out.ser.track; 745 - 746 - if (kho_out.finalized) 747 - return -EBUSY; 748 745 749 746 if (!PAGE_ALIGNED(phys) || !PAGE_ALIGNED(size)) 750 747 return -EINVAL;