On Thu, Jan 15, 2026 at 07:44:32PM -0800, Jason Miu wrote: > Eliminate the `kho_finalize()` function and its associated state from > the KHO subsystem. The transition to a radix tree for memory tracking > makes the explicit "finalize" state and its serialization step > obsolete. > > Remove the `kho_finalize()` and `kho_finalized()` APIs and their stub > implementations. Update KHO client code and the debugfs interface to > no longer call or depend on the `kho_finalize()` mechanism. > > Complete the move towards a stateless KHO, simplifying the overall > design by removing unnecessary state management. > > Signed-off-by: Jason Miu <[email protected]>
Reviewed-by: Mike Rapoport (Microsoft) <[email protected]> > --- > Documentation/admin-guide/mm/kho.rst | 53 +++++---------------- > Documentation/core-api/kho/index.rst | 12 ----- > kernel/liveupdate/kexec_handover.c | 21 +------- > kernel/liveupdate/kexec_handover_debugfs.c | 23 --------- > kernel/liveupdate/kexec_handover_internal.h | 3 -- > kernel/liveupdate/luo_core.c | 12 +---- > kernel/liveupdate/luo_flb.c | 2 +- > tools/testing/selftests/kho/init.c | 20 -------- > 8 files changed, 14 insertions(+), 132 deletions(-) > > diff --git a/Documentation/admin-guide/mm/kho.rst > b/Documentation/admin-guide/mm/kho.rst > index 6dc18ed4b886..454b378cf239 100644 > --- a/Documentation/admin-guide/mm/kho.rst > +++ b/Documentation/admin-guide/mm/kho.rst > @@ -28,20 +28,10 @@ per NUMA node scratch regions on boot. > Perform a KHO kexec > =================== > > -First, before you perform a KHO kexec, you need to move the system into > -the :ref:`KHO finalization phase <kho-finalization-phase>` :: > - > - $ echo 1 > /sys/kernel/debug/kho/out/finalize > - > -After this command, the KHO FDT is available in > -``/sys/kernel/debug/kho/out/fdt``. Other subsystems may also register > -their own preserved sub FDTs under > -``/sys/kernel/debug/kho/out/sub_fdts/``. > - > -Next, load the target payload and kexec into it. It is important that you > -use the ``-s`` parameter to use the in-kernel kexec file loader, as user > -space kexec tooling currently has no support for KHO with the user space > -based file loader :: > +To perform a KHO kexec, load the target payload and kexec into it. It > +is important that you use the ``-s`` parameter to use the in-kernel > +kexec file loader, as user space kexec tooling currently has no > +support for KHO with the user space based file loader :: > > # kexec -l /path/to/bzImage --initrd /path/to/initrd -s > # kexec -e > @@ -52,40 +42,19 @@ For example, if you used ``reserve_mem`` command line > parameter to create > an early memory reservation, the new kernel will have that memory at the > same physical address as the old kernel. > > -Abort a KHO exec > -================ > - > -You can move the system out of KHO finalization phase again by calling :: > - > - $ echo 0 > /sys/kernel/debug/kho/out/active > - > -After this command, the KHO FDT is no longer available in > -``/sys/kernel/debug/kho/out/fdt``. > - > debugfs Interfaces > ================== > > +These debugfs interfaces are available when the kernel is compiled with > +``CONFIG_KEXEC_HANDOVER_DEBUGFS`` enabled. > + > Currently KHO creates the following debugfs interfaces. Notice that these > interfaces may change in the future. They will be moved to sysfs once KHO is > stabilized. > > -``/sys/kernel/debug/kho/out/finalize`` > - Kexec HandOver (KHO) allows Linux to transition the state of > - compatible drivers into the next kexec'ed kernel. To do so, > - device drivers will instruct KHO to preserve memory regions, > - which could contain serialized kernel state. > - While the state is serialized, they are unable to perform > - any modifications to state that was serialized, such as > - handed over memory allocations. > - > - When this file contains "1", the system is in the transition > - state. When contains "0", it is not. To switch between the > - two states, echo the respective number into this file. > - > ``/sys/kernel/debug/kho/out/fdt`` > - When KHO state tree is finalized, the kernel exposes the > - flattened device tree blob that carries its current KHO > - state in this file. Kexec user space tooling can use this > + The kernel exposes the flattened device tree blob that carries its > + current KHO state in this file. Kexec user space tooling can use this > as input file for the KHO payload image. > > ``/sys/kernel/debug/kho/out/scratch_len`` > @@ -100,8 +69,8 @@ stabilized. > it should place its payload images. > > ``/sys/kernel/debug/kho/out/sub_fdts/`` > - In the KHO finalization phase, KHO producers register their own > - FDT blob under this directory. > + KHO producers can register their own FDT blob another binary blob under Nit: ^ FDT or another binary blob > + this directory. > > ``/sys/kernel/debug/kho/in/fdt`` > When the kernel was booted with Kexec HandOver (KHO), > diff --git a/Documentation/core-api/kho/index.rst > b/Documentation/core-api/kho/index.rst > index 002bdf0beb2e..0a2dee4f8e7d 100644 > --- a/Documentation/core-api/kho/index.rst > +++ b/Documentation/core-api/kho/index.rst > @@ -71,18 +71,6 @@ for boot memory allocations and as target memory for kexec > blobs, some parts > of that memory region may be reserved. These reservations are irrelevant for > the next KHO, because kexec can overwrite even the original kernel. > > -.. _kho-finalization-phase: > - > -KHO finalization phase > -====================== > - > -To enable user space based kexec file loader, the kernel needs to be able to > -provide the FDT that describes the current kernel's state before > -performing the actual kexec. The process of generating that FDT is > -called serialization. When the FDT is generated, some properties > -of the system may become immutable because they are already written down > -in the FDT. That state is called the KHO finalization phase. > - > Kexec Handover Radix Tree > ========================= > > diff --git a/kernel/liveupdate/kexec_handover.c > b/kernel/liveupdate/kexec_handover.c > index 06adaf56cd69..14d2c66491a6 100644 > --- a/kernel/liveupdate/kexec_handover.c > +++ b/kernel/liveupdate/kexec_handover.c > @@ -68,8 +68,7 @@ early_param("kho", kho_parse_enable); > > struct kho_out { > void *fdt; > - bool finalized; > - struct mutex lock; /* protects KHO FDT finalization */ > + struct mutex lock; /* protects KHO FDT */ > > struct kho_radix_tree radix_tree; > struct kho_debugfs dbg; > @@ -80,7 +79,6 @@ static struct kho_out kho_out = { > .radix_tree = { > .lock = __MUTEX_INITIALIZER(kho_out.radix_tree.lock), > }, > - .finalized = false, > }; > > /** > @@ -1209,23 +1207,6 @@ void kho_restore_free(void *mem) > } > EXPORT_SYMBOL_GPL(kho_restore_free); > > -int kho_finalize(void) > -{ > - if (!kho_enable) > - return -EOPNOTSUPP; > - > - guard(mutex)(&kho_out.lock); > - kho_out.finalized = true; > - > - return 0; > -} > - > -bool kho_finalized(void) > -{ > - guard(mutex)(&kho_out.lock); > - return kho_out.finalized; > -} > - > struct kho_in { > phys_addr_t fdt_phys; > phys_addr_t scratch_phys; > diff --git a/kernel/liveupdate/kexec_handover_debugfs.c > b/kernel/liveupdate/kexec_handover_debugfs.c > index 2abbf62ba942..430c9521d59c 100644 > --- a/kernel/liveupdate/kexec_handover_debugfs.c > +++ b/kernel/liveupdate/kexec_handover_debugfs.c > @@ -75,24 +75,6 @@ void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, void > *fdt) > } > } > > -static int kho_out_finalize_get(void *data, u64 *val) > -{ > - *val = kho_finalized(); > - > - return 0; > -} > - > -static int kho_out_finalize_set(void *data, u64 val) > -{ > - if (val) > - return kho_finalize(); > - else > - return -EINVAL; > -} > - > -DEFINE_DEBUGFS_ATTRIBUTE(kho_out_finalize_fops, kho_out_finalize_get, > - kho_out_finalize_set, "%llu\n"); > - > static int scratch_phys_show(struct seq_file *m, void *v) > { > for (int i = 0; i < kho_scratch_cnt; i++) > @@ -198,11 +180,6 @@ __init int kho_out_debugfs_init(struct kho_debugfs *dbg) > if (IS_ERR(f)) > goto err_rmdir; > > - f = debugfs_create_file("finalize", 0600, dir, NULL, > - &kho_out_finalize_fops); > - if (IS_ERR(f)) > - goto err_rmdir; > - > dbg->dir = dir; > dbg->sub_fdt_dir = sub_fdt_dir; > return 0; > diff --git a/kernel/liveupdate/kexec_handover_internal.h > b/kernel/liveupdate/kexec_handover_internal.h > index 0202c85ad14f..9a832a35254c 100644 > --- a/kernel/liveupdate/kexec_handover_internal.h > +++ b/kernel/liveupdate/kexec_handover_internal.h > @@ -22,9 +22,6 @@ struct kho_debugfs {}; > extern struct kho_scratch *kho_scratch; > extern unsigned int kho_scratch_cnt; > > -bool kho_finalized(void); > -int kho_finalize(void); > - > #ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS > int kho_debugfs_init(void); > void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt); > diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c > index dda7bb57d421..84ac728d63ba 100644 > --- a/kernel/liveupdate/luo_core.c > +++ b/kernel/liveupdate/luo_core.c > @@ -230,17 +230,7 @@ int liveupdate_reboot(void) > > luo_flb_serialize(); > > - err = kho_finalize(); > - if (err) { > - pr_err("kho_finalize failed %d\n", err); > - /* > - * kho_finalize() may return libfdt errors, to aboid passing to > - * userspace unknown errors, change this to EAGAIN. > - */ > - err = -EAGAIN; > - } > - > - return err; > + return 0; > } > > /** > diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c > index 4c437de5c0b0..22f6409875c9 100644 > --- a/kernel/liveupdate/luo_flb.c > +++ b/kernel/liveupdate/luo_flb.c > @@ -630,7 +630,7 @@ int __init luo_flb_setup_incoming(void *fdt_in) > * data handle, and the final reference count. This allows the new kernel to > * find the appropriate handler and reconstruct the FLB's state. > * > - * Context: Called from liveupdate_reboot() just before kho_finalize(). > + * Context: Called from liveupdate_reboot(). > */ > void luo_flb_serialize(void) > { > diff --git a/tools/testing/selftests/kho/init.c > b/tools/testing/selftests/kho/init.c > index 6d9e91d55d68..88a41b6eba95 100644 > --- a/tools/testing/selftests/kho/init.c > +++ b/tools/testing/selftests/kho/init.c > @@ -11,7 +11,6 @@ > /* from arch/x86/include/asm/setup.h */ > #define COMMAND_LINE_SIZE 2048 > > -#define KHO_FINALIZE "/debugfs/kho/out/finalize" > #define KERNEL_IMAGE "/kernel" > > static int mount_filesystems(void) > @@ -22,22 +21,6 @@ static int mount_filesystems(void) > return mount("proc", "/proc", "proc", 0, NULL); > } > > -static int kho_enable(void) > -{ > - const char enable[] = "1"; > - int fd; > - > - fd = open(KHO_FINALIZE, O_RDWR); > - if (fd < 0) > - return -1; > - > - if (write(fd, enable, sizeof(enable)) != sizeof(enable)) > - return 1; > - > - close(fd); > - return 0; > -} > - > static long kexec_file_load(int kernel_fd, int initrd_fd, > unsigned long cmdline_len, const char *cmdline, > unsigned long flags) > @@ -78,9 +61,6 @@ int main(int argc, char *argv[]) > if (mount_filesystems()) > goto err_reboot; > > - if (kho_enable()) > - goto err_reboot; > - > if (kexec_load()) > goto err_reboot; > > -- > 2.52.0.457.g6b5491de43-goog > -- Sincerely yours, Mike.
