[PATCH 07/12] kho: allow destroying KHO radix tree

Pasha Tatashin pasha.tatashin at soleen.com
Thu May 21 16:46:23 PDT 2026


On 04-29 15:39, Pratyush Yadav wrote:
> From: "Pratyush Yadav (Google)" <pratyush at kernel.org>
> 
> Add kho_radix_destroy_tree() which allows destroying the radix tree and
> freeing all its pages.
> 
> Signed-off-by: Pratyush Yadav (Google) <pratyush at kernel.org>
> ---
>  include/linux/kho_radix_tree.h     |  3 +++
>  kernel/liveupdate/kexec_handover.c | 34 ++++++++++++++++++++++++++++++
>  2 files changed, 37 insertions(+)

Generally, in Linux, recursion is avoided due to statically sized kernel 
stacks. However, here we are bound by a relatively shallow KHO tree, and 
kho_radix_walk_tree() is already recursive, so I think it is alright. We 
just need to be mindful of local variable usage (frame sizes) within these 
recursive functions.

Reviewed-by: Pasha Tatashin <pasha.tatashin at soleen.com> 

> 
> diff --git a/include/linux/kho_radix_tree.h b/include/linux/kho_radix_tree.h
> index 6c0f7d82716b..617395a6647a 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);
> +void kho_radix_destroy_tree(struct kho_radix_tree *tree);
>  
>  #else  /* #ifdef CONFIG_KEXEC_HANDOVER */
>  
> @@ -71,6 +72,8 @@ static inline int kho_radix_walk_tree(struct kho_radix_tree *tree,
>  	return -EOPNOTSUPP;
>  }
>  
> +static inline void kho_radix_destroy_tree(struct kho_radix_tree *tree) { }
> +
>  #endif /* #ifdef CONFIG_KEXEC_HANDOVER */
>  
>  #endif	/* _LINUX_KHO_RADIX_TREE_H */
> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> index 47f7c4a2865e..29479534f65d 100644
> --- a/kernel/liveupdate/kexec_handover.c
> +++ b/kernel/liveupdate/kexec_handover.c
> @@ -286,6 +286,40 @@ void kho_radix_del_key(struct kho_radix_tree *tree, unsigned long key)
>  }
>  EXPORT_SYMBOL_GPL(kho_radix_del_key);
>  
> +static void __kho_radix_destroy_tree(struct kho_radix_node *root,
> +				     unsigned int level)
> +{
> +	unsigned long i;
> +
> +	if (level == 0) {
> +		kho_radix_free_node(root);
> +		return;
> +	}
> +
> +	for (i = 0; i < PAGE_SIZE / sizeof(phys_addr_t); i++) {
> +		if (root->table[i])
> +			__kho_radix_destroy_tree(phys_to_virt(root->table[i]),
> +						 level - 1);
> +	}
> +
> +	kho_radix_free_node(root);
> +}
> +
> +/**
> + * kho_radix_destroy_tree - Destroy the radix tree
> + * @tree: The radix tree to destroy
> + *
> + * Walk @tree and free all its nodes.
> + */
> +void kho_radix_destroy_tree(struct kho_radix_tree *tree)
> +{
> +	if (!tree->root)
> +		return;
> +
> +	__kho_radix_destroy_tree(tree->root, KHO_TREE_MAX_DEPTH - 1);
> +}
> +EXPORT_SYMBOL_GPL(kho_radix_destroy_tree);
> +
>  static int kho_radix_walk_leaf(struct kho_radix_leaf *leaf, unsigned long key,
>  			       const struct kho_radix_walk_cb *cb, void *data)
>  {
> -- 
> 2.54.0.545.g6539524ca2-goog
> 



More information about the kexec mailing list