[PATCH 06/12] kho: allow early-boot usage of the KHO radix tree
Pasha Tatashin
pasha.tatashin at soleen.com
Thu May 21 16:37:03 PDT 2026
On 04-29 15:39, Pratyush Yadav wrote:
> From: "Pratyush Yadav (Google)" <pratyush at kernel.org>
>
> The KHO radix tree allocates memory for table pages from the buddy
> allocator using get_zeroed_page(). This is not available in early boot
> when memblock is still active.
>
> Using the radix tree in early boot is useful for KHO to track metadata
> about its memory. One such example is for tracking free blocks for
> memory allocation when scratch runs out of space. This feature will be
> added in the following commits.
>
> Add kho_radix_{alloc,free}_node() which allocate and free the table
> pages. They use slab_is_available() to decide which allocator to use.
> While slab_is_available() indicates availability of the slab allocator,
> it gets initialized right before buddy so it serves the same practical
> purpose.
>
> Signed-off-by: Pratyush Yadav (Google) <pratyush at kernel.org>
Reviewed-by: Pasha Tatashin <pasha.tatashin at soleen.com>
> ---
> kernel/liveupdate/kexec_handover.c | 24 ++++++++++++++++++++++--
> 1 file changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> index d0a4f78eccfe..47f7c4a2865e 100644
> --- a/kernel/liveupdate/kexec_handover.c
> +++ b/kernel/liveupdate/kexec_handover.c
> @@ -143,6 +143,26 @@ static unsigned long kho_radix_get_table_index(unsigned long key,
> return (key >> s) % (1 << KHO_TABLE_SIZE_LOG2);
> }
>
> +static void __ref *kho_radix_alloc_node(void)
> +{
> + struct kho_radix_node *node;
> +
> + if (slab_is_available())
> + node = (struct kho_radix_node *)get_zeroed_page(GFP_KERNEL);
> + else
> + node = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
> +
> + return node;
> +}
> +
> +static void __ref kho_radix_free_node(struct kho_radix_node *node)
> +{
> + if (slab_is_available())
> + free_page((unsigned long)node);
> + else
> + memblock_free(node, PAGE_SIZE);
> +}
> +
> /**
> * kho_radix_add_key - Add a key to the radix tree.
> * @tree: The KHO radix tree.
> @@ -183,7 +203,7 @@ int kho_radix_add_key(struct kho_radix_tree *tree, unsigned long key)
> }
>
> /* Next node is empty, create a new node for it */
> - new_node = (struct kho_radix_node *)get_zeroed_page(GFP_KERNEL);
> + new_node = kho_radix_alloc_node();
> if (!new_node) {
> err = -ENOMEM;
> goto err_free_nodes;
> @@ -214,7 +234,7 @@ int kho_radix_add_key(struct kho_radix_tree *tree, unsigned long key)
> err_free_nodes:
> for (i = KHO_TREE_MAX_DEPTH - 1; i > 0; i--) {
> if (intermediate_nodes[i])
> - free_page((unsigned long)intermediate_nodes[i]);
> + kho_radix_free_node(intermediate_nodes[i]);
> }
> if (anchor_node)
> anchor_node->table[anchor_idx] = 0;
> --
> 2.54.0.545.g6539524ca2-goog
>
More information about the kexec
mailing list