kho: allow destroying KHO radix tree

Add kho_radix_destroy_tree() which allows destroying the radix tree and
freeing all its pages.

This is will be used by the upcoming scratch extension mechanism. It
creates a radix tree to track free blocks and then frees them after
telling memblock about them.

Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Link: https://patch.msgid.link/20260801084833.1897543-12-pratyush@kernel.org
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
This commit is contained in:
Pratyush Yadav (Google) 2026-08-01 10:48:20 +02:00 committed by Mike Rapoport (Microsoft)
parent 3ab43ce410
commit a8ea530d7d
2 changed files with 38 additions and 0 deletions

View File

@ -58,6 +58,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 */
@ -75,6 +76,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 */

View File

@ -301,6 +301,41 @@ 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);
tree->root = NULL;
}
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)
{