[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