kernel/liveupdate/kexec_handover.c | 32 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-)
From: Long Wei <longwei27@huawei.com>
Replace the chained error accumulation (err |= func()) with immediate
per-step error checking and early return in kho_out_fdt_setup().
Two problems with the current approach:
1. It continues executing FDT operations even after a failure, which
is pointless and potentially unsafe on an invalid FDT context.
2. Bitwise OR of multiple negative error codes produces a result that
may not represent any actual error, making debugging misleading.
Early return fails fast and preserves the original error code for
accurate diagnosis.
No functional change intended.
Signed-off-by: Long Wei <longwei27@huawei.com>
---
kernel/liveupdate/kexec_handover.c | 32 +++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 175c08a6e..93443ad84 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -1438,20 +1438,34 @@ static __init int kho_out_fdt_setup(void)
int err;
err = fdt_create(root, PAGE_SIZE);
- err |= fdt_finish_reservemap(root);
- err |= fdt_begin_node(root, "");
- err |= fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE);
+ if (err)
+ return err;
+ err = fdt_finish_reservemap(root);
+ if (err)
+ return err;
+ err = fdt_begin_node(root, "");
+ if (err)
+ return err;
+ err = fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE);
+ if (err)
+ return err;
preserved_mem_tree_pa = virt_to_phys(tree->root);
- err |= fdt_property(root, KHO_FDT_MEMORY_MAP_PROP_NAME,
- &preserved_mem_tree_pa,
- sizeof(preserved_mem_tree_pa));
+ err = fdt_property(root, KHO_FDT_MEMORY_MAP_PROP_NAME,
+ &preserved_mem_tree_pa,
+ sizeof(preserved_mem_tree_pa));
+ if (err)
+ return err;
- err |= fdt_end_node(root);
- err |= fdt_finish(root);
+ err = fdt_end_node(root);
+ if (err)
+ return err;
+ err = fdt_finish(root);
+ if (err)
+ return err;
- return err;
+ return 0;
}
static void __init kho_in_kexec_metadata(void)
--
2.43.0
Hi, > Replace the chained error accumulation (err |= func()) with immediate > per-step error checking and early return in kho_out_fdt_setup(). > > Two problems with the current approach: > 1. It continues executing FDT operations even after a failure, which > is pointless and potentially unsafe on an invalid FDT context. Did you actually see failures here or was it an LLM suggesting that they may happen? > 2. Bitwise OR of multiple negative error codes produces a result that > may not represent any actual error, making debugging misleading. > > Early return fails fast and preserves the original error code for > accurate diagnosis. The caller does not care about the exact error value, so the diagnosis statement is moot at best. Moreover, libfdt does not return Linux error values. -- Sincerely yours, Mike.
Hi Mike Rapoport, Thanks for the review. To be honest, I haven't observed any actual failures in this path in our production environment. This change was identified during our internal team code review—the err |= func() pattern looked concerning to us at first glance, so we attempted to clean it up. However, I agree with your assessment: the caller doesn't care about the exact error value, libfdt uses its own error codes, and this is a cold path where failures are unlikely. The change is indeed unnecessary churn without a concrete bug to fix. I'll drop this patch. Please ignore this submission. Thanks, Long Wei 在 2026/8/31 19:28, Mike Rapoport 写道: > Hi, > > >> Replace the chained error accumulation (err |= func()) with immediate >> per-step error checking and early return in kho_out_fdt_setup(). >> >> Two problems with the current approach: >> 1. It continues executing FDT operations even after a failure, which >> is pointless and potentially unsafe on an invalid FDT context. > > Did you actually see failures here or was it an LLM suggesting that they > may happen? > >> 2. Bitwise OR of multiple negative error codes produces a result that >> may not represent any actual error, making debugging misleading. >> >> Early return fails fast and preserves the original error code for >> accurate diagnosis. > > The caller does not care about the exact error value, so the diagnosis > statement is moot at best. > Moreover, libfdt does not return Linux error values. >
On Mon, Aug 24, 2026 at 10:44:48AM +0800, LongWei27 wrote: > +++ b/kernel/liveupdate/kexec_handover.c > @@ -1438,20 +1438,34 @@ static __init int kho_out_fdt_setup(void) > int err; > > err = fdt_create(root, PAGE_SIZE); > - err |= fdt_finish_reservemap(root); > - err |= fdt_begin_node(root, ""); > - err |= fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); > + if (err) > + return err; > + err = fdt_finish_reservemap(root); > + if (err) > + return err; > + err = fdt_begin_node(root, ""); > + if (err) > + return err; > + err = fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); > + if (err) > + return err; Less verbose: err = fdt_create(root, PAGE_SIZE); - err |= fdt_finish_reservemap(root); - err |= fdt_begin_node(root, ""); - err |= fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); + if (!err) + err = fdt_finish_reservemap(root); + if (!err) + err = fdt_begin_node(root, ""); + if (!err) + err = fdt_property_string(root, "compatible", + KHO_FDT_COMPATIBLE); up to the maintainer which one they prefer ...
Hi Matthew, Thanks for the review. I chose the explicit `if (err) return err` pattern for clarity and "fail fast" behavior. However, I'm happy to adopt the chained pattern if the maintainer prefers it. Thanks, Long Wei 在 2026/8/24 10:54, Matthew Wilcox 写道: > On Mon, Aug 24, 2026 at 10:44:48AM +0800, LongWei27 wrote: >> +++ b/kernel/liveupdate/kexec_handover.c >> @@ -1438,20 +1438,34 @@ static __init int kho_out_fdt_setup(void) >> int err; >> >> err = fdt_create(root, PAGE_SIZE); >> - err |= fdt_finish_reservemap(root); >> - err |= fdt_begin_node(root, ""); >> - err |= fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); >> + if (err) >> + return err; >> + err = fdt_finish_reservemap(root); >> + if (err) >> + return err; >> + err = fdt_begin_node(root, ""); >> + if (err) >> + return err; >> + err = fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); >> + if (err) >> + return err; > > Less verbose: > > err = fdt_create(root, PAGE_SIZE); > - err |= fdt_finish_reservemap(root); > - err |= fdt_begin_node(root, ""); > - err |= fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); > + if (!err) > + err = fdt_finish_reservemap(root); > + if (!err) > + err = fdt_begin_node(root, ""); > + if (!err) > + err = fdt_property_string(root, "compatible", > + KHO_FDT_COMPATIBLE); > > up to the maintainer which one they prefer ...
© 2016 - 2026 Red Hat, Inc.