From: "Pratyush Yadav (Google)" <[email protected]>

Move the initialization logic of the radix tree into
kho_radix_init_tree() instead of having users open-code it. Makes the
boundaries cleaner and reduces code duplication when a new user of the
radix tree will be added in a future commit.

Signed-off-by: Pratyush Yadav (Google) <[email protected]>
---
 include/linux/kho_radix_tree.h     |  7 ++++
 kernel/liveupdate/kexec_handover.c | 66 ++++++++++++++++++++++--------
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/include/linux/kho_radix_tree.h b/include/linux/kho_radix_tree.h
index 66ca936b3f06..5d6ae2893684 100644
--- a/include/linux/kho_radix_tree.h
+++ b/include/linux/kho_radix_tree.h
@@ -54,6 +54,7 @@ int kho_radix_add_key(struct kho_radix_tree *tree, unsigned 
long key);
 void kho_radix_del_key(struct kho_radix_tree *tree, unsigned long key);
 int kho_radix_walk_tree(struct kho_radix_tree *tree,
                        const struct kho_radix_walk_cb *cb, void *data);
+int kho_radix_init_tree(struct kho_radix_tree *tree, struct kho_radix_node 
*root);
 void kho_radix_destroy_tree(struct kho_radix_tree *tree);
 
 #else  /* #ifdef CONFIG_KEXEC_HANDOVER */
@@ -72,6 +73,12 @@ static inline int kho_radix_walk_tree(struct kho_radix_tree 
*tree,
        return -EOPNOTSUPP;
 }
 
+static inline int kho_radix_init_tree(struct kho_radix_tree *tree,
+                                     struct kho_radix_node *root)
+{
+       return 0;
+}
+
 static inline void kho_radix_destroy_tree(struct kho_radix_tree *tree) { }
 
 #endif /* #ifdef CONFIG_KEXEC_HANDOVER */
diff --git a/kernel/liveupdate/kexec_handover.c 
b/kernel/liveupdate/kexec_handover.c
index df3f5eb01bf1..8ab2c7e234e1 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -317,6 +317,34 @@ static void __kho_radix_destroy_tree(struct kho_radix_node 
*root,
        kho_radix_free_node(root);
 }
 
+/**
+ * kho_radix_init_tree - initialize the radix tree.
+ * @tree:   the tree to initialize.
+ * @root:   root table of the radix tree.
+ *
+ * Initialize the radix tree with the given root node. If root is %NULL, an
+ * empty root table is allocated. If root is not %NULL, it is the caller's
+ * responsibility to make sure the root is valid and in the correct format.
+ *
+ * Return: 0 on success, -errno on failure.
+ */
+int kho_radix_init_tree(struct kho_radix_tree *tree, struct kho_radix_node 
*root)
+{
+       /* Already initialized. */
+       if (tree->root)
+               return 0;
+
+       if (!root)
+               root = kho_radix_alloc_node();
+       if (!root)
+               return -ENOMEM;
+
+       tree->root = root;
+       mutex_init(&tree->lock);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(kho_radix_init_tree);
+
 /**
  * kho_radix_destroy_tree - Destroy the radix tree
  * @tree: The radix tree to destroy
@@ -1496,18 +1524,23 @@ static void __init kho_mem_retrieve(void)
         * catches that and never sets kho_in.scratch_phys, which stops memory
         * retrieval.
         */
-       kho_in.radix_tree.root = kho_get_mem_map(fdt);
-       mutex_init(&kho_in.radix_tree.lock);
+       err = kho_radix_init_tree(&kho_in.radix_tree, kho_get_mem_map(fdt));
+       if (err)
+               goto err;
 
        err = kho_radix_walk_tree(&kho_in.radix_tree, &cb, NULL);
-       if (err) {
-               /*
-                * Failed to initialize preserved memory. Clear FDT and radix
-                * so KHO users don't treat it as a KHO boot.
-                */
-               kho_in.fdt_phys = 0;
-               kho_in.radix_tree.root = NULL;
-       }
+       if (err)
+               goto err;
+
+       return;
+
+err:
+       /*
+        * Failed to initialize preserved memory. Clear FDT and radix so KHO
+        * users don't treat it as a KHO boot.
+        */
+       kho_in.fdt_phys = 0;
+       kho_in.radix_tree.root = NULL;
 }
 
 static __init int kho_out_fdt_setup(void)
@@ -1633,16 +1666,14 @@ static __init int kho_init(void)
        if (!kho_enable)
                return 0;
 
-       tree->root = kzalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!tree->root) {
-               err = -ENOMEM;
+       err = kho_radix_init_tree(tree, NULL);
+       if (err)
                goto err_free_scratch;
-       }
 
        kho_out.fdt = kho_alloc_preserve(PAGE_SIZE);
        if (IS_ERR(kho_out.fdt)) {
                err = PTR_ERR(kho_out.fdt);
-               goto err_free_kho_radix_tree_root;
+               goto err_free_kho_radix_tree;
        }
 
        err = kho_debugfs_init();
@@ -1693,9 +1724,8 @@ static __init int kho_init(void)
 
 err_free_fdt:
        kho_unpreserve_free(kho_out.fdt);
-err_free_kho_radix_tree_root:
-       kfree(tree->root);
-       tree->root = NULL;
+err_free_kho_radix_tree:
+       kho_radix_destroy_tree(tree);
 err_free_scratch:
        kho_out.fdt = NULL;
        for (int i = 0; i < kho_scratch_cnt; i++) {
-- 
2.54.0.1032.g2f8565e1d1-goog


Reply via email to