xref: /kernel/linux/linux-6.6/lib/radix-tree.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2001 Momchil Velikov
462306a36Sopenharmony_ci * Portions Copyright (C) 2001 Christoph Hellwig
562306a36Sopenharmony_ci * Copyright (C) 2005 SGI, Christoph Lameter
662306a36Sopenharmony_ci * Copyright (C) 2006 Nick Piggin
762306a36Sopenharmony_ci * Copyright (C) 2012 Konstantin Khlebnikov
862306a36Sopenharmony_ci * Copyright (C) 2016 Intel, Matthew Wilcox
962306a36Sopenharmony_ci * Copyright (C) 2016 Intel, Ross Zwisler
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/bitmap.h>
1362306a36Sopenharmony_ci#include <linux/bitops.h>
1462306a36Sopenharmony_ci#include <linux/bug.h>
1562306a36Sopenharmony_ci#include <linux/cpu.h>
1662306a36Sopenharmony_ci#include <linux/errno.h>
1762306a36Sopenharmony_ci#include <linux/export.h>
1862306a36Sopenharmony_ci#include <linux/idr.h>
1962306a36Sopenharmony_ci#include <linux/init.h>
2062306a36Sopenharmony_ci#include <linux/kernel.h>
2162306a36Sopenharmony_ci#include <linux/kmemleak.h>
2262306a36Sopenharmony_ci#include <linux/percpu.h>
2362306a36Sopenharmony_ci#include <linux/preempt.h>		/* in_interrupt() */
2462306a36Sopenharmony_ci#include <linux/radix-tree.h>
2562306a36Sopenharmony_ci#include <linux/rcupdate.h>
2662306a36Sopenharmony_ci#include <linux/slab.h>
2762306a36Sopenharmony_ci#include <linux/string.h>
2862306a36Sopenharmony_ci#include <linux/xarray.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include "radix-tree.h"
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/*
3362306a36Sopenharmony_ci * Radix tree node cache.
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_cistruct kmem_cache *radix_tree_node_cachep;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/*
3862306a36Sopenharmony_ci * The radix tree is variable-height, so an insert operation not only has
3962306a36Sopenharmony_ci * to build the branch to its corresponding item, it also has to build the
4062306a36Sopenharmony_ci * branch to existing items if the size has to be increased (by
4162306a36Sopenharmony_ci * radix_tree_extend).
4262306a36Sopenharmony_ci *
4362306a36Sopenharmony_ci * The worst case is a zero height tree with just a single item at index 0,
4462306a36Sopenharmony_ci * and then inserting an item at index ULONG_MAX. This requires 2 new branches
4562306a36Sopenharmony_ci * of RADIX_TREE_MAX_PATH size to be created, with only the root node shared.
4662306a36Sopenharmony_ci * Hence:
4762306a36Sopenharmony_ci */
4862306a36Sopenharmony_ci#define RADIX_TREE_PRELOAD_SIZE (RADIX_TREE_MAX_PATH * 2 - 1)
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/*
5162306a36Sopenharmony_ci * The IDR does not have to be as high as the radix tree since it uses
5262306a36Sopenharmony_ci * signed integers, not unsigned longs.
5362306a36Sopenharmony_ci */
5462306a36Sopenharmony_ci#define IDR_INDEX_BITS		(8 /* CHAR_BIT */ * sizeof(int) - 1)
5562306a36Sopenharmony_ci#define IDR_MAX_PATH		(DIV_ROUND_UP(IDR_INDEX_BITS, \
5662306a36Sopenharmony_ci						RADIX_TREE_MAP_SHIFT))
5762306a36Sopenharmony_ci#define IDR_PRELOAD_SIZE	(IDR_MAX_PATH * 2 - 1)
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/*
6062306a36Sopenharmony_ci * Per-cpu pool of preloaded nodes
6162306a36Sopenharmony_ci */
6262306a36Sopenharmony_ciDEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = {
6362306a36Sopenharmony_ci	.lock = INIT_LOCAL_LOCK(lock),
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ciEXPORT_PER_CPU_SYMBOL_GPL(radix_tree_preloads);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic inline struct radix_tree_node *entry_to_node(void *ptr)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	return (void *)((unsigned long)ptr & ~RADIX_TREE_INTERNAL_NODE);
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_cistatic inline void *node_to_entry(void *ptr)
7362306a36Sopenharmony_ci{
7462306a36Sopenharmony_ci	return (void *)((unsigned long)ptr | RADIX_TREE_INTERNAL_NODE);
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define RADIX_TREE_RETRY	XA_RETRY_ENTRY
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic inline unsigned long
8062306a36Sopenharmony_ciget_slot_offset(const struct radix_tree_node *parent, void __rcu **slot)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	return parent ? slot - parent->slots : 0;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic unsigned int radix_tree_descend(const struct radix_tree_node *parent,
8662306a36Sopenharmony_ci			struct radix_tree_node **nodep, unsigned long index)
8762306a36Sopenharmony_ci{
8862306a36Sopenharmony_ci	unsigned int offset = (index >> parent->shift) & RADIX_TREE_MAP_MASK;
8962306a36Sopenharmony_ci	void __rcu **entry = rcu_dereference_raw(parent->slots[offset]);
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	*nodep = (void *)entry;
9262306a36Sopenharmony_ci	return offset;
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic inline gfp_t root_gfp_mask(const struct radix_tree_root *root)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	return root->xa_flags & (__GFP_BITS_MASK & ~GFP_ZONEMASK);
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic inline void tag_set(struct radix_tree_node *node, unsigned int tag,
10162306a36Sopenharmony_ci		int offset)
10262306a36Sopenharmony_ci{
10362306a36Sopenharmony_ci	__set_bit(offset, node->tags[tag]);
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic inline void tag_clear(struct radix_tree_node *node, unsigned int tag,
10762306a36Sopenharmony_ci		int offset)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	__clear_bit(offset, node->tags[tag]);
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistatic inline int tag_get(const struct radix_tree_node *node, unsigned int tag,
11362306a36Sopenharmony_ci		int offset)
11462306a36Sopenharmony_ci{
11562306a36Sopenharmony_ci	return test_bit(offset, node->tags[tag]);
11662306a36Sopenharmony_ci}
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_cistatic inline void root_tag_set(struct radix_tree_root *root, unsigned tag)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci	root->xa_flags |= (__force gfp_t)(1 << (tag + ROOT_TAG_SHIFT));
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistatic inline void root_tag_clear(struct radix_tree_root *root, unsigned tag)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	root->xa_flags &= (__force gfp_t)~(1 << (tag + ROOT_TAG_SHIFT));
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistatic inline void root_tag_clear_all(struct radix_tree_root *root)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	root->xa_flags &= (__force gfp_t)((1 << ROOT_TAG_SHIFT) - 1);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic inline int root_tag_get(const struct radix_tree_root *root, unsigned tag)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	return (__force int)root->xa_flags & (1 << (tag + ROOT_TAG_SHIFT));
13662306a36Sopenharmony_ci}
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_cistatic inline unsigned root_tags_get(const struct radix_tree_root *root)
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	return (__force unsigned)root->xa_flags >> ROOT_TAG_SHIFT;
14162306a36Sopenharmony_ci}
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistatic inline bool is_idr(const struct radix_tree_root *root)
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci	return !!(root->xa_flags & ROOT_IS_IDR);
14662306a36Sopenharmony_ci}
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/*
14962306a36Sopenharmony_ci * Returns 1 if any slot in the node has this tag set.
15062306a36Sopenharmony_ci * Otherwise returns 0.
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_cistatic inline int any_tag_set(const struct radix_tree_node *node,
15362306a36Sopenharmony_ci							unsigned int tag)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	unsigned idx;
15662306a36Sopenharmony_ci	for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
15762306a36Sopenharmony_ci		if (node->tags[tag][idx])
15862306a36Sopenharmony_ci			return 1;
15962306a36Sopenharmony_ci	}
16062306a36Sopenharmony_ci	return 0;
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic inline void all_tag_set(struct radix_tree_node *node, unsigned int tag)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	bitmap_fill(node->tags[tag], RADIX_TREE_MAP_SIZE);
16662306a36Sopenharmony_ci}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci/**
16962306a36Sopenharmony_ci * radix_tree_find_next_bit - find the next set bit in a memory region
17062306a36Sopenharmony_ci *
17162306a36Sopenharmony_ci * @node: where to begin the search
17262306a36Sopenharmony_ci * @tag: the tag index
17362306a36Sopenharmony_ci * @offset: the bitnumber to start searching at
17462306a36Sopenharmony_ci *
17562306a36Sopenharmony_ci * Unrollable variant of find_next_bit() for constant size arrays.
17662306a36Sopenharmony_ci * Tail bits starting from size to roundup(size, BITS_PER_LONG) must be zero.
17762306a36Sopenharmony_ci * Returns next bit offset, or size if nothing found.
17862306a36Sopenharmony_ci */
17962306a36Sopenharmony_cistatic __always_inline unsigned long
18062306a36Sopenharmony_ciradix_tree_find_next_bit(struct radix_tree_node *node, unsigned int tag,
18162306a36Sopenharmony_ci			 unsigned long offset)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	const unsigned long *addr = node->tags[tag];
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	if (offset < RADIX_TREE_MAP_SIZE) {
18662306a36Sopenharmony_ci		unsigned long tmp;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci		addr += offset / BITS_PER_LONG;
18962306a36Sopenharmony_ci		tmp = *addr >> (offset % BITS_PER_LONG);
19062306a36Sopenharmony_ci		if (tmp)
19162306a36Sopenharmony_ci			return __ffs(tmp) + offset;
19262306a36Sopenharmony_ci		offset = (offset + BITS_PER_LONG) & ~(BITS_PER_LONG - 1);
19362306a36Sopenharmony_ci		while (offset < RADIX_TREE_MAP_SIZE) {
19462306a36Sopenharmony_ci			tmp = *++addr;
19562306a36Sopenharmony_ci			if (tmp)
19662306a36Sopenharmony_ci				return __ffs(tmp) + offset;
19762306a36Sopenharmony_ci			offset += BITS_PER_LONG;
19862306a36Sopenharmony_ci		}
19962306a36Sopenharmony_ci	}
20062306a36Sopenharmony_ci	return RADIX_TREE_MAP_SIZE;
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_cistatic unsigned int iter_offset(const struct radix_tree_iter *iter)
20462306a36Sopenharmony_ci{
20562306a36Sopenharmony_ci	return iter->index & RADIX_TREE_MAP_MASK;
20662306a36Sopenharmony_ci}
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci/*
20962306a36Sopenharmony_ci * The maximum index which can be stored in a radix tree
21062306a36Sopenharmony_ci */
21162306a36Sopenharmony_cistatic inline unsigned long shift_maxindex(unsigned int shift)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	return (RADIX_TREE_MAP_SIZE << shift) - 1;
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistatic inline unsigned long node_maxindex(const struct radix_tree_node *node)
21762306a36Sopenharmony_ci{
21862306a36Sopenharmony_ci	return shift_maxindex(node->shift);
21962306a36Sopenharmony_ci}
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistatic unsigned long next_index(unsigned long index,
22262306a36Sopenharmony_ci				const struct radix_tree_node *node,
22362306a36Sopenharmony_ci				unsigned long offset)
22462306a36Sopenharmony_ci{
22562306a36Sopenharmony_ci	return (index & ~node_maxindex(node)) + (offset << node->shift);
22662306a36Sopenharmony_ci}
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci/*
22962306a36Sopenharmony_ci * This assumes that the caller has performed appropriate preallocation, and
23062306a36Sopenharmony_ci * that the caller has pinned this thread of control to the current CPU.
23162306a36Sopenharmony_ci */
23262306a36Sopenharmony_cistatic struct radix_tree_node *
23362306a36Sopenharmony_ciradix_tree_node_alloc(gfp_t gfp_mask, struct radix_tree_node *parent,
23462306a36Sopenharmony_ci			struct radix_tree_root *root,
23562306a36Sopenharmony_ci			unsigned int shift, unsigned int offset,
23662306a36Sopenharmony_ci			unsigned int count, unsigned int nr_values)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	struct radix_tree_node *ret = NULL;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	/*
24162306a36Sopenharmony_ci	 * Preload code isn't irq safe and it doesn't make sense to use
24262306a36Sopenharmony_ci	 * preloading during an interrupt anyway as all the allocations have
24362306a36Sopenharmony_ci	 * to be atomic. So just do normal allocation when in interrupt.
24462306a36Sopenharmony_ci	 */
24562306a36Sopenharmony_ci	if (!gfpflags_allow_blocking(gfp_mask) && !in_interrupt()) {
24662306a36Sopenharmony_ci		struct radix_tree_preload *rtp;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci		/*
24962306a36Sopenharmony_ci		 * Even if the caller has preloaded, try to allocate from the
25062306a36Sopenharmony_ci		 * cache first for the new node to get accounted to the memory
25162306a36Sopenharmony_ci		 * cgroup.
25262306a36Sopenharmony_ci		 */
25362306a36Sopenharmony_ci		ret = kmem_cache_alloc(radix_tree_node_cachep,
25462306a36Sopenharmony_ci				       gfp_mask | __GFP_NOWARN);
25562306a36Sopenharmony_ci		if (ret)
25662306a36Sopenharmony_ci			goto out;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci		/*
25962306a36Sopenharmony_ci		 * Provided the caller has preloaded here, we will always
26062306a36Sopenharmony_ci		 * succeed in getting a node here (and never reach
26162306a36Sopenharmony_ci		 * kmem_cache_alloc)
26262306a36Sopenharmony_ci		 */
26362306a36Sopenharmony_ci		rtp = this_cpu_ptr(&radix_tree_preloads);
26462306a36Sopenharmony_ci		if (rtp->nr) {
26562306a36Sopenharmony_ci			ret = rtp->nodes;
26662306a36Sopenharmony_ci			rtp->nodes = ret->parent;
26762306a36Sopenharmony_ci			rtp->nr--;
26862306a36Sopenharmony_ci		}
26962306a36Sopenharmony_ci		/*
27062306a36Sopenharmony_ci		 * Update the allocation stack trace as this is more useful
27162306a36Sopenharmony_ci		 * for debugging.
27262306a36Sopenharmony_ci		 */
27362306a36Sopenharmony_ci		kmemleak_update_trace(ret);
27462306a36Sopenharmony_ci		goto out;
27562306a36Sopenharmony_ci	}
27662306a36Sopenharmony_ci	ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
27762306a36Sopenharmony_ciout:
27862306a36Sopenharmony_ci	BUG_ON(radix_tree_is_internal_node(ret));
27962306a36Sopenharmony_ci	if (ret) {
28062306a36Sopenharmony_ci		ret->shift = shift;
28162306a36Sopenharmony_ci		ret->offset = offset;
28262306a36Sopenharmony_ci		ret->count = count;
28362306a36Sopenharmony_ci		ret->nr_values = nr_values;
28462306a36Sopenharmony_ci		ret->parent = parent;
28562306a36Sopenharmony_ci		ret->array = root;
28662306a36Sopenharmony_ci	}
28762306a36Sopenharmony_ci	return ret;
28862306a36Sopenharmony_ci}
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_civoid radix_tree_node_rcu_free(struct rcu_head *head)
29162306a36Sopenharmony_ci{
29262306a36Sopenharmony_ci	struct radix_tree_node *node =
29362306a36Sopenharmony_ci			container_of(head, struct radix_tree_node, rcu_head);
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	/*
29662306a36Sopenharmony_ci	 * Must only free zeroed nodes into the slab.  We can be left with
29762306a36Sopenharmony_ci	 * non-NULL entries by radix_tree_free_nodes, so clear the entries
29862306a36Sopenharmony_ci	 * and tags here.
29962306a36Sopenharmony_ci	 */
30062306a36Sopenharmony_ci	memset(node->slots, 0, sizeof(node->slots));
30162306a36Sopenharmony_ci	memset(node->tags, 0, sizeof(node->tags));
30262306a36Sopenharmony_ci	INIT_LIST_HEAD(&node->private_list);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	kmem_cache_free(radix_tree_node_cachep, node);
30562306a36Sopenharmony_ci}
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_cistatic inline void
30862306a36Sopenharmony_ciradix_tree_node_free(struct radix_tree_node *node)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	call_rcu(&node->rcu_head, radix_tree_node_rcu_free);
31162306a36Sopenharmony_ci}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci/*
31462306a36Sopenharmony_ci * Load up this CPU's radix_tree_node buffer with sufficient objects to
31562306a36Sopenharmony_ci * ensure that the addition of a single element in the tree cannot fail.  On
31662306a36Sopenharmony_ci * success, return zero, with preemption disabled.  On error, return -ENOMEM
31762306a36Sopenharmony_ci * with preemption not disabled.
31862306a36Sopenharmony_ci *
31962306a36Sopenharmony_ci * To make use of this facility, the radix tree must be initialised without
32062306a36Sopenharmony_ci * __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE().
32162306a36Sopenharmony_ci */
32262306a36Sopenharmony_cistatic __must_check int __radix_tree_preload(gfp_t gfp_mask, unsigned nr)
32362306a36Sopenharmony_ci{
32462306a36Sopenharmony_ci	struct radix_tree_preload *rtp;
32562306a36Sopenharmony_ci	struct radix_tree_node *node;
32662306a36Sopenharmony_ci	int ret = -ENOMEM;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	/*
32962306a36Sopenharmony_ci	 * Nodes preloaded by one cgroup can be used by another cgroup, so
33062306a36Sopenharmony_ci	 * they should never be accounted to any particular memory cgroup.
33162306a36Sopenharmony_ci	 */
33262306a36Sopenharmony_ci	gfp_mask &= ~__GFP_ACCOUNT;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	local_lock(&radix_tree_preloads.lock);
33562306a36Sopenharmony_ci	rtp = this_cpu_ptr(&radix_tree_preloads);
33662306a36Sopenharmony_ci	while (rtp->nr < nr) {
33762306a36Sopenharmony_ci		local_unlock(&radix_tree_preloads.lock);
33862306a36Sopenharmony_ci		node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
33962306a36Sopenharmony_ci		if (node == NULL)
34062306a36Sopenharmony_ci			goto out;
34162306a36Sopenharmony_ci		local_lock(&radix_tree_preloads.lock);
34262306a36Sopenharmony_ci		rtp = this_cpu_ptr(&radix_tree_preloads);
34362306a36Sopenharmony_ci		if (rtp->nr < nr) {
34462306a36Sopenharmony_ci			node->parent = rtp->nodes;
34562306a36Sopenharmony_ci			rtp->nodes = node;
34662306a36Sopenharmony_ci			rtp->nr++;
34762306a36Sopenharmony_ci		} else {
34862306a36Sopenharmony_ci			kmem_cache_free(radix_tree_node_cachep, node);
34962306a36Sopenharmony_ci		}
35062306a36Sopenharmony_ci	}
35162306a36Sopenharmony_ci	ret = 0;
35262306a36Sopenharmony_ciout:
35362306a36Sopenharmony_ci	return ret;
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci/*
35762306a36Sopenharmony_ci * Load up this CPU's radix_tree_node buffer with sufficient objects to
35862306a36Sopenharmony_ci * ensure that the addition of a single element in the tree cannot fail.  On
35962306a36Sopenharmony_ci * success, return zero, with preemption disabled.  On error, return -ENOMEM
36062306a36Sopenharmony_ci * with preemption not disabled.
36162306a36Sopenharmony_ci *
36262306a36Sopenharmony_ci * To make use of this facility, the radix tree must be initialised without
36362306a36Sopenharmony_ci * __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE().
36462306a36Sopenharmony_ci */
36562306a36Sopenharmony_ciint radix_tree_preload(gfp_t gfp_mask)
36662306a36Sopenharmony_ci{
36762306a36Sopenharmony_ci	/* Warn on non-sensical use... */
36862306a36Sopenharmony_ci	WARN_ON_ONCE(!gfpflags_allow_blocking(gfp_mask));
36962306a36Sopenharmony_ci	return __radix_tree_preload(gfp_mask, RADIX_TREE_PRELOAD_SIZE);
37062306a36Sopenharmony_ci}
37162306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_preload);
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci/*
37462306a36Sopenharmony_ci * The same as above function, except we don't guarantee preloading happens.
37562306a36Sopenharmony_ci * We do it, if we decide it helps. On success, return zero with preemption
37662306a36Sopenharmony_ci * disabled. On error, return -ENOMEM with preemption not disabled.
37762306a36Sopenharmony_ci */
37862306a36Sopenharmony_ciint radix_tree_maybe_preload(gfp_t gfp_mask)
37962306a36Sopenharmony_ci{
38062306a36Sopenharmony_ci	if (gfpflags_allow_blocking(gfp_mask))
38162306a36Sopenharmony_ci		return __radix_tree_preload(gfp_mask, RADIX_TREE_PRELOAD_SIZE);
38262306a36Sopenharmony_ci	/* Preloading doesn't help anything with this gfp mask, skip it */
38362306a36Sopenharmony_ci	local_lock(&radix_tree_preloads.lock);
38462306a36Sopenharmony_ci	return 0;
38562306a36Sopenharmony_ci}
38662306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_maybe_preload);
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistatic unsigned radix_tree_load_root(const struct radix_tree_root *root,
38962306a36Sopenharmony_ci		struct radix_tree_node **nodep, unsigned long *maxindex)
39062306a36Sopenharmony_ci{
39162306a36Sopenharmony_ci	struct radix_tree_node *node = rcu_dereference_raw(root->xa_head);
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	*nodep = node;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	if (likely(radix_tree_is_internal_node(node))) {
39662306a36Sopenharmony_ci		node = entry_to_node(node);
39762306a36Sopenharmony_ci		*maxindex = node_maxindex(node);
39862306a36Sopenharmony_ci		return node->shift + RADIX_TREE_MAP_SHIFT;
39962306a36Sopenharmony_ci	}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	*maxindex = 0;
40262306a36Sopenharmony_ci	return 0;
40362306a36Sopenharmony_ci}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci/*
40662306a36Sopenharmony_ci *	Extend a radix tree so it can store key @index.
40762306a36Sopenharmony_ci */
40862306a36Sopenharmony_cistatic int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp,
40962306a36Sopenharmony_ci				unsigned long index, unsigned int shift)
41062306a36Sopenharmony_ci{
41162306a36Sopenharmony_ci	void *entry;
41262306a36Sopenharmony_ci	unsigned int maxshift;
41362306a36Sopenharmony_ci	int tag;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	/* Figure out what the shift should be.  */
41662306a36Sopenharmony_ci	maxshift = shift;
41762306a36Sopenharmony_ci	while (index > shift_maxindex(maxshift))
41862306a36Sopenharmony_ci		maxshift += RADIX_TREE_MAP_SHIFT;
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	entry = rcu_dereference_raw(root->xa_head);
42162306a36Sopenharmony_ci	if (!entry && (!is_idr(root) || root_tag_get(root, IDR_FREE)))
42262306a36Sopenharmony_ci		goto out;
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	do {
42562306a36Sopenharmony_ci		struct radix_tree_node *node = radix_tree_node_alloc(gfp, NULL,
42662306a36Sopenharmony_ci							root, shift, 0, 1, 0);
42762306a36Sopenharmony_ci		if (!node)
42862306a36Sopenharmony_ci			return -ENOMEM;
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci		if (is_idr(root)) {
43162306a36Sopenharmony_ci			all_tag_set(node, IDR_FREE);
43262306a36Sopenharmony_ci			if (!root_tag_get(root, IDR_FREE)) {
43362306a36Sopenharmony_ci				tag_clear(node, IDR_FREE, 0);
43462306a36Sopenharmony_ci				root_tag_set(root, IDR_FREE);
43562306a36Sopenharmony_ci			}
43662306a36Sopenharmony_ci		} else {
43762306a36Sopenharmony_ci			/* Propagate the aggregated tag info to the new child */
43862306a36Sopenharmony_ci			for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {
43962306a36Sopenharmony_ci				if (root_tag_get(root, tag))
44062306a36Sopenharmony_ci					tag_set(node, tag, 0);
44162306a36Sopenharmony_ci			}
44262306a36Sopenharmony_ci		}
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci		BUG_ON(shift > BITS_PER_LONG);
44562306a36Sopenharmony_ci		if (radix_tree_is_internal_node(entry)) {
44662306a36Sopenharmony_ci			entry_to_node(entry)->parent = node;
44762306a36Sopenharmony_ci		} else if (xa_is_value(entry)) {
44862306a36Sopenharmony_ci			/* Moving a value entry root->xa_head to a node */
44962306a36Sopenharmony_ci			node->nr_values = 1;
45062306a36Sopenharmony_ci		}
45162306a36Sopenharmony_ci		/*
45262306a36Sopenharmony_ci		 * entry was already in the radix tree, so we do not need
45362306a36Sopenharmony_ci		 * rcu_assign_pointer here
45462306a36Sopenharmony_ci		 */
45562306a36Sopenharmony_ci		node->slots[0] = (void __rcu *)entry;
45662306a36Sopenharmony_ci		entry = node_to_entry(node);
45762306a36Sopenharmony_ci		rcu_assign_pointer(root->xa_head, entry);
45862306a36Sopenharmony_ci		shift += RADIX_TREE_MAP_SHIFT;
45962306a36Sopenharmony_ci	} while (shift <= maxshift);
46062306a36Sopenharmony_ciout:
46162306a36Sopenharmony_ci	return maxshift + RADIX_TREE_MAP_SHIFT;
46262306a36Sopenharmony_ci}
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci/**
46562306a36Sopenharmony_ci *	radix_tree_shrink    -    shrink radix tree to minimum height
46662306a36Sopenharmony_ci *	@root:		radix tree root
46762306a36Sopenharmony_ci */
46862306a36Sopenharmony_cistatic inline bool radix_tree_shrink(struct radix_tree_root *root)
46962306a36Sopenharmony_ci{
47062306a36Sopenharmony_ci	bool shrunk = false;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	for (;;) {
47362306a36Sopenharmony_ci		struct radix_tree_node *node = rcu_dereference_raw(root->xa_head);
47462306a36Sopenharmony_ci		struct radix_tree_node *child;
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci		if (!radix_tree_is_internal_node(node))
47762306a36Sopenharmony_ci			break;
47862306a36Sopenharmony_ci		node = entry_to_node(node);
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci		/*
48162306a36Sopenharmony_ci		 * The candidate node has more than one child, or its child
48262306a36Sopenharmony_ci		 * is not at the leftmost slot, we cannot shrink.
48362306a36Sopenharmony_ci		 */
48462306a36Sopenharmony_ci		if (node->count != 1)
48562306a36Sopenharmony_ci			break;
48662306a36Sopenharmony_ci		child = rcu_dereference_raw(node->slots[0]);
48762306a36Sopenharmony_ci		if (!child)
48862306a36Sopenharmony_ci			break;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci		/*
49162306a36Sopenharmony_ci		 * For an IDR, we must not shrink entry 0 into the root in
49262306a36Sopenharmony_ci		 * case somebody calls idr_replace() with a pointer that
49362306a36Sopenharmony_ci		 * appears to be an internal entry
49462306a36Sopenharmony_ci		 */
49562306a36Sopenharmony_ci		if (!node->shift && is_idr(root))
49662306a36Sopenharmony_ci			break;
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci		if (radix_tree_is_internal_node(child))
49962306a36Sopenharmony_ci			entry_to_node(child)->parent = NULL;
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci		/*
50262306a36Sopenharmony_ci		 * We don't need rcu_assign_pointer(), since we are simply
50362306a36Sopenharmony_ci		 * moving the node from one part of the tree to another: if it
50462306a36Sopenharmony_ci		 * was safe to dereference the old pointer to it
50562306a36Sopenharmony_ci		 * (node->slots[0]), it will be safe to dereference the new
50662306a36Sopenharmony_ci		 * one (root->xa_head) as far as dependent read barriers go.
50762306a36Sopenharmony_ci		 */
50862306a36Sopenharmony_ci		root->xa_head = (void __rcu *)child;
50962306a36Sopenharmony_ci		if (is_idr(root) && !tag_get(node, IDR_FREE, 0))
51062306a36Sopenharmony_ci			root_tag_clear(root, IDR_FREE);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci		/*
51362306a36Sopenharmony_ci		 * We have a dilemma here. The node's slot[0] must not be
51462306a36Sopenharmony_ci		 * NULLed in case there are concurrent lookups expecting to
51562306a36Sopenharmony_ci		 * find the item. However if this was a bottom-level node,
51662306a36Sopenharmony_ci		 * then it may be subject to the slot pointer being visible
51762306a36Sopenharmony_ci		 * to callers dereferencing it. If item corresponding to
51862306a36Sopenharmony_ci		 * slot[0] is subsequently deleted, these callers would expect
51962306a36Sopenharmony_ci		 * their slot to become empty sooner or later.
52062306a36Sopenharmony_ci		 *
52162306a36Sopenharmony_ci		 * For example, lockless pagecache will look up a slot, deref
52262306a36Sopenharmony_ci		 * the page pointer, and if the page has 0 refcount it means it
52362306a36Sopenharmony_ci		 * was concurrently deleted from pagecache so try the deref
52462306a36Sopenharmony_ci		 * again. Fortunately there is already a requirement for logic
52562306a36Sopenharmony_ci		 * to retry the entire slot lookup -- the indirect pointer
52662306a36Sopenharmony_ci		 * problem (replacing direct root node with an indirect pointer
52762306a36Sopenharmony_ci		 * also results in a stale slot). So tag the slot as indirect
52862306a36Sopenharmony_ci		 * to force callers to retry.
52962306a36Sopenharmony_ci		 */
53062306a36Sopenharmony_ci		node->count = 0;
53162306a36Sopenharmony_ci		if (!radix_tree_is_internal_node(child)) {
53262306a36Sopenharmony_ci			node->slots[0] = (void __rcu *)RADIX_TREE_RETRY;
53362306a36Sopenharmony_ci		}
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci		WARN_ON_ONCE(!list_empty(&node->private_list));
53662306a36Sopenharmony_ci		radix_tree_node_free(node);
53762306a36Sopenharmony_ci		shrunk = true;
53862306a36Sopenharmony_ci	}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	return shrunk;
54162306a36Sopenharmony_ci}
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_cistatic bool delete_node(struct radix_tree_root *root,
54462306a36Sopenharmony_ci			struct radix_tree_node *node)
54562306a36Sopenharmony_ci{
54662306a36Sopenharmony_ci	bool deleted = false;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	do {
54962306a36Sopenharmony_ci		struct radix_tree_node *parent;
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci		if (node->count) {
55262306a36Sopenharmony_ci			if (node_to_entry(node) ==
55362306a36Sopenharmony_ci					rcu_dereference_raw(root->xa_head))
55462306a36Sopenharmony_ci				deleted |= radix_tree_shrink(root);
55562306a36Sopenharmony_ci			return deleted;
55662306a36Sopenharmony_ci		}
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci		parent = node->parent;
55962306a36Sopenharmony_ci		if (parent) {
56062306a36Sopenharmony_ci			parent->slots[node->offset] = NULL;
56162306a36Sopenharmony_ci			parent->count--;
56262306a36Sopenharmony_ci		} else {
56362306a36Sopenharmony_ci			/*
56462306a36Sopenharmony_ci			 * Shouldn't the tags already have all been cleared
56562306a36Sopenharmony_ci			 * by the caller?
56662306a36Sopenharmony_ci			 */
56762306a36Sopenharmony_ci			if (!is_idr(root))
56862306a36Sopenharmony_ci				root_tag_clear_all(root);
56962306a36Sopenharmony_ci			root->xa_head = NULL;
57062306a36Sopenharmony_ci		}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci		WARN_ON_ONCE(!list_empty(&node->private_list));
57362306a36Sopenharmony_ci		radix_tree_node_free(node);
57462306a36Sopenharmony_ci		deleted = true;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci		node = parent;
57762306a36Sopenharmony_ci	} while (node);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	return deleted;
58062306a36Sopenharmony_ci}
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci/**
58362306a36Sopenharmony_ci *	__radix_tree_create	-	create a slot in a radix tree
58462306a36Sopenharmony_ci *	@root:		radix tree root
58562306a36Sopenharmony_ci *	@index:		index key
58662306a36Sopenharmony_ci *	@nodep:		returns node
58762306a36Sopenharmony_ci *	@slotp:		returns slot
58862306a36Sopenharmony_ci *
58962306a36Sopenharmony_ci *	Create, if necessary, and return the node and slot for an item
59062306a36Sopenharmony_ci *	at position @index in the radix tree @root.
59162306a36Sopenharmony_ci *
59262306a36Sopenharmony_ci *	Until there is more than one item in the tree, no nodes are
59362306a36Sopenharmony_ci *	allocated and @root->xa_head is used as a direct slot instead of
59462306a36Sopenharmony_ci *	pointing to a node, in which case *@nodep will be NULL.
59562306a36Sopenharmony_ci *
59662306a36Sopenharmony_ci *	Returns -ENOMEM, or 0 for success.
59762306a36Sopenharmony_ci */
59862306a36Sopenharmony_cistatic int __radix_tree_create(struct radix_tree_root *root,
59962306a36Sopenharmony_ci		unsigned long index, struct radix_tree_node **nodep,
60062306a36Sopenharmony_ci		void __rcu ***slotp)
60162306a36Sopenharmony_ci{
60262306a36Sopenharmony_ci	struct radix_tree_node *node = NULL, *child;
60362306a36Sopenharmony_ci	void __rcu **slot = (void __rcu **)&root->xa_head;
60462306a36Sopenharmony_ci	unsigned long maxindex;
60562306a36Sopenharmony_ci	unsigned int shift, offset = 0;
60662306a36Sopenharmony_ci	unsigned long max = index;
60762306a36Sopenharmony_ci	gfp_t gfp = root_gfp_mask(root);
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci	shift = radix_tree_load_root(root, &child, &maxindex);
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	/* Make sure the tree is high enough.  */
61262306a36Sopenharmony_ci	if (max > maxindex) {
61362306a36Sopenharmony_ci		int error = radix_tree_extend(root, gfp, max, shift);
61462306a36Sopenharmony_ci		if (error < 0)
61562306a36Sopenharmony_ci			return error;
61662306a36Sopenharmony_ci		shift = error;
61762306a36Sopenharmony_ci		child = rcu_dereference_raw(root->xa_head);
61862306a36Sopenharmony_ci	}
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci	while (shift > 0) {
62162306a36Sopenharmony_ci		shift -= RADIX_TREE_MAP_SHIFT;
62262306a36Sopenharmony_ci		if (child == NULL) {
62362306a36Sopenharmony_ci			/* Have to add a child node.  */
62462306a36Sopenharmony_ci			child = radix_tree_node_alloc(gfp, node, root, shift,
62562306a36Sopenharmony_ci							offset, 0, 0);
62662306a36Sopenharmony_ci			if (!child)
62762306a36Sopenharmony_ci				return -ENOMEM;
62862306a36Sopenharmony_ci			rcu_assign_pointer(*slot, node_to_entry(child));
62962306a36Sopenharmony_ci			if (node)
63062306a36Sopenharmony_ci				node->count++;
63162306a36Sopenharmony_ci		} else if (!radix_tree_is_internal_node(child))
63262306a36Sopenharmony_ci			break;
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci		/* Go a level down */
63562306a36Sopenharmony_ci		node = entry_to_node(child);
63662306a36Sopenharmony_ci		offset = radix_tree_descend(node, &child, index);
63762306a36Sopenharmony_ci		slot = &node->slots[offset];
63862306a36Sopenharmony_ci	}
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	if (nodep)
64162306a36Sopenharmony_ci		*nodep = node;
64262306a36Sopenharmony_ci	if (slotp)
64362306a36Sopenharmony_ci		*slotp = slot;
64462306a36Sopenharmony_ci	return 0;
64562306a36Sopenharmony_ci}
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci/*
64862306a36Sopenharmony_ci * Free any nodes below this node.  The tree is presumed to not need
64962306a36Sopenharmony_ci * shrinking, and any user data in the tree is presumed to not need a
65062306a36Sopenharmony_ci * destructor called on it.  If we need to add a destructor, we can
65162306a36Sopenharmony_ci * add that functionality later.  Note that we may not clear tags or
65262306a36Sopenharmony_ci * slots from the tree as an RCU walker may still have a pointer into
65362306a36Sopenharmony_ci * this subtree.  We could replace the entries with RADIX_TREE_RETRY,
65462306a36Sopenharmony_ci * but we'll still have to clear those in rcu_free.
65562306a36Sopenharmony_ci */
65662306a36Sopenharmony_cistatic void radix_tree_free_nodes(struct radix_tree_node *node)
65762306a36Sopenharmony_ci{
65862306a36Sopenharmony_ci	unsigned offset = 0;
65962306a36Sopenharmony_ci	struct radix_tree_node *child = entry_to_node(node);
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	for (;;) {
66262306a36Sopenharmony_ci		void *entry = rcu_dereference_raw(child->slots[offset]);
66362306a36Sopenharmony_ci		if (xa_is_node(entry) && child->shift) {
66462306a36Sopenharmony_ci			child = entry_to_node(entry);
66562306a36Sopenharmony_ci			offset = 0;
66662306a36Sopenharmony_ci			continue;
66762306a36Sopenharmony_ci		}
66862306a36Sopenharmony_ci		offset++;
66962306a36Sopenharmony_ci		while (offset == RADIX_TREE_MAP_SIZE) {
67062306a36Sopenharmony_ci			struct radix_tree_node *old = child;
67162306a36Sopenharmony_ci			offset = child->offset + 1;
67262306a36Sopenharmony_ci			child = child->parent;
67362306a36Sopenharmony_ci			WARN_ON_ONCE(!list_empty(&old->private_list));
67462306a36Sopenharmony_ci			radix_tree_node_free(old);
67562306a36Sopenharmony_ci			if (old == entry_to_node(node))
67662306a36Sopenharmony_ci				return;
67762306a36Sopenharmony_ci		}
67862306a36Sopenharmony_ci	}
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cistatic inline int insert_entries(struct radix_tree_node *node,
68262306a36Sopenharmony_ci		void __rcu **slot, void *item)
68362306a36Sopenharmony_ci{
68462306a36Sopenharmony_ci	if (*slot)
68562306a36Sopenharmony_ci		return -EEXIST;
68662306a36Sopenharmony_ci	rcu_assign_pointer(*slot, item);
68762306a36Sopenharmony_ci	if (node) {
68862306a36Sopenharmony_ci		node->count++;
68962306a36Sopenharmony_ci		if (xa_is_value(item))
69062306a36Sopenharmony_ci			node->nr_values++;
69162306a36Sopenharmony_ci	}
69262306a36Sopenharmony_ci	return 1;
69362306a36Sopenharmony_ci}
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci/**
69662306a36Sopenharmony_ci *	radix_tree_insert    -    insert into a radix tree
69762306a36Sopenharmony_ci *	@root:		radix tree root
69862306a36Sopenharmony_ci *	@index:		index key
69962306a36Sopenharmony_ci *	@item:		item to insert
70062306a36Sopenharmony_ci *
70162306a36Sopenharmony_ci *	Insert an item into the radix tree at position @index.
70262306a36Sopenharmony_ci */
70362306a36Sopenharmony_ciint radix_tree_insert(struct radix_tree_root *root, unsigned long index,
70462306a36Sopenharmony_ci			void *item)
70562306a36Sopenharmony_ci{
70662306a36Sopenharmony_ci	struct radix_tree_node *node;
70762306a36Sopenharmony_ci	void __rcu **slot;
70862306a36Sopenharmony_ci	int error;
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	BUG_ON(radix_tree_is_internal_node(item));
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci	error = __radix_tree_create(root, index, &node, &slot);
71362306a36Sopenharmony_ci	if (error)
71462306a36Sopenharmony_ci		return error;
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	error = insert_entries(node, slot, item);
71762306a36Sopenharmony_ci	if (error < 0)
71862306a36Sopenharmony_ci		return error;
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	if (node) {
72162306a36Sopenharmony_ci		unsigned offset = get_slot_offset(node, slot);
72262306a36Sopenharmony_ci		BUG_ON(tag_get(node, 0, offset));
72362306a36Sopenharmony_ci		BUG_ON(tag_get(node, 1, offset));
72462306a36Sopenharmony_ci		BUG_ON(tag_get(node, 2, offset));
72562306a36Sopenharmony_ci	} else {
72662306a36Sopenharmony_ci		BUG_ON(root_tags_get(root));
72762306a36Sopenharmony_ci	}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci	return 0;
73062306a36Sopenharmony_ci}
73162306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_insert);
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci/**
73462306a36Sopenharmony_ci *	__radix_tree_lookup	-	lookup an item in a radix tree
73562306a36Sopenharmony_ci *	@root:		radix tree root
73662306a36Sopenharmony_ci *	@index:		index key
73762306a36Sopenharmony_ci *	@nodep:		returns node
73862306a36Sopenharmony_ci *	@slotp:		returns slot
73962306a36Sopenharmony_ci *
74062306a36Sopenharmony_ci *	Lookup and return the item at position @index in the radix
74162306a36Sopenharmony_ci *	tree @root.
74262306a36Sopenharmony_ci *
74362306a36Sopenharmony_ci *	Until there is more than one item in the tree, no nodes are
74462306a36Sopenharmony_ci *	allocated and @root->xa_head is used as a direct slot instead of
74562306a36Sopenharmony_ci *	pointing to a node, in which case *@nodep will be NULL.
74662306a36Sopenharmony_ci */
74762306a36Sopenharmony_civoid *__radix_tree_lookup(const struct radix_tree_root *root,
74862306a36Sopenharmony_ci			  unsigned long index, struct radix_tree_node **nodep,
74962306a36Sopenharmony_ci			  void __rcu ***slotp)
75062306a36Sopenharmony_ci{
75162306a36Sopenharmony_ci	struct radix_tree_node *node, *parent;
75262306a36Sopenharmony_ci	unsigned long maxindex;
75362306a36Sopenharmony_ci	void __rcu **slot;
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci restart:
75662306a36Sopenharmony_ci	parent = NULL;
75762306a36Sopenharmony_ci	slot = (void __rcu **)&root->xa_head;
75862306a36Sopenharmony_ci	radix_tree_load_root(root, &node, &maxindex);
75962306a36Sopenharmony_ci	if (index > maxindex)
76062306a36Sopenharmony_ci		return NULL;
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	while (radix_tree_is_internal_node(node)) {
76362306a36Sopenharmony_ci		unsigned offset;
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci		parent = entry_to_node(node);
76662306a36Sopenharmony_ci		offset = radix_tree_descend(parent, &node, index);
76762306a36Sopenharmony_ci		slot = parent->slots + offset;
76862306a36Sopenharmony_ci		if (node == RADIX_TREE_RETRY)
76962306a36Sopenharmony_ci			goto restart;
77062306a36Sopenharmony_ci		if (parent->shift == 0)
77162306a36Sopenharmony_ci			break;
77262306a36Sopenharmony_ci	}
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci	if (nodep)
77562306a36Sopenharmony_ci		*nodep = parent;
77662306a36Sopenharmony_ci	if (slotp)
77762306a36Sopenharmony_ci		*slotp = slot;
77862306a36Sopenharmony_ci	return node;
77962306a36Sopenharmony_ci}
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci/**
78262306a36Sopenharmony_ci *	radix_tree_lookup_slot    -    lookup a slot in a radix tree
78362306a36Sopenharmony_ci *	@root:		radix tree root
78462306a36Sopenharmony_ci *	@index:		index key
78562306a36Sopenharmony_ci *
78662306a36Sopenharmony_ci *	Returns:  the slot corresponding to the position @index in the
78762306a36Sopenharmony_ci *	radix tree @root. This is useful for update-if-exists operations.
78862306a36Sopenharmony_ci *
78962306a36Sopenharmony_ci *	This function can be called under rcu_read_lock iff the slot is not
79062306a36Sopenharmony_ci *	modified by radix_tree_replace_slot, otherwise it must be called
79162306a36Sopenharmony_ci *	exclusive from other writers. Any dereference of the slot must be done
79262306a36Sopenharmony_ci *	using radix_tree_deref_slot.
79362306a36Sopenharmony_ci */
79462306a36Sopenharmony_civoid __rcu **radix_tree_lookup_slot(const struct radix_tree_root *root,
79562306a36Sopenharmony_ci				unsigned long index)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	void __rcu **slot;
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	if (!__radix_tree_lookup(root, index, NULL, &slot))
80062306a36Sopenharmony_ci		return NULL;
80162306a36Sopenharmony_ci	return slot;
80262306a36Sopenharmony_ci}
80362306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_lookup_slot);
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci/**
80662306a36Sopenharmony_ci *	radix_tree_lookup    -    perform lookup operation on a radix tree
80762306a36Sopenharmony_ci *	@root:		radix tree root
80862306a36Sopenharmony_ci *	@index:		index key
80962306a36Sopenharmony_ci *
81062306a36Sopenharmony_ci *	Lookup the item at the position @index in the radix tree @root.
81162306a36Sopenharmony_ci *
81262306a36Sopenharmony_ci *	This function can be called under rcu_read_lock, however the caller
81362306a36Sopenharmony_ci *	must manage lifetimes of leaf nodes (eg. RCU may also be used to free
81462306a36Sopenharmony_ci *	them safely). No RCU barriers are required to access or modify the
81562306a36Sopenharmony_ci *	returned item, however.
81662306a36Sopenharmony_ci */
81762306a36Sopenharmony_civoid *radix_tree_lookup(const struct radix_tree_root *root, unsigned long index)
81862306a36Sopenharmony_ci{
81962306a36Sopenharmony_ci	return __radix_tree_lookup(root, index, NULL, NULL);
82062306a36Sopenharmony_ci}
82162306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_lookup);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_cistatic void replace_slot(void __rcu **slot, void *item,
82462306a36Sopenharmony_ci		struct radix_tree_node *node, int count, int values)
82562306a36Sopenharmony_ci{
82662306a36Sopenharmony_ci	if (node && (count || values)) {
82762306a36Sopenharmony_ci		node->count += count;
82862306a36Sopenharmony_ci		node->nr_values += values;
82962306a36Sopenharmony_ci	}
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	rcu_assign_pointer(*slot, item);
83262306a36Sopenharmony_ci}
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_cistatic bool node_tag_get(const struct radix_tree_root *root,
83562306a36Sopenharmony_ci				const struct radix_tree_node *node,
83662306a36Sopenharmony_ci				unsigned int tag, unsigned int offset)
83762306a36Sopenharmony_ci{
83862306a36Sopenharmony_ci	if (node)
83962306a36Sopenharmony_ci		return tag_get(node, tag, offset);
84062306a36Sopenharmony_ci	return root_tag_get(root, tag);
84162306a36Sopenharmony_ci}
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci/*
84462306a36Sopenharmony_ci * IDR users want to be able to store NULL in the tree, so if the slot isn't
84562306a36Sopenharmony_ci * free, don't adjust the count, even if it's transitioning between NULL and
84662306a36Sopenharmony_ci * non-NULL.  For the IDA, we mark slots as being IDR_FREE while they still
84762306a36Sopenharmony_ci * have empty bits, but it only stores NULL in slots when they're being
84862306a36Sopenharmony_ci * deleted.
84962306a36Sopenharmony_ci */
85062306a36Sopenharmony_cistatic int calculate_count(struct radix_tree_root *root,
85162306a36Sopenharmony_ci				struct radix_tree_node *node, void __rcu **slot,
85262306a36Sopenharmony_ci				void *item, void *old)
85362306a36Sopenharmony_ci{
85462306a36Sopenharmony_ci	if (is_idr(root)) {
85562306a36Sopenharmony_ci		unsigned offset = get_slot_offset(node, slot);
85662306a36Sopenharmony_ci		bool free = node_tag_get(root, node, IDR_FREE, offset);
85762306a36Sopenharmony_ci		if (!free)
85862306a36Sopenharmony_ci			return 0;
85962306a36Sopenharmony_ci		if (!old)
86062306a36Sopenharmony_ci			return 1;
86162306a36Sopenharmony_ci	}
86262306a36Sopenharmony_ci	return !!item - !!old;
86362306a36Sopenharmony_ci}
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci/**
86662306a36Sopenharmony_ci * __radix_tree_replace		- replace item in a slot
86762306a36Sopenharmony_ci * @root:		radix tree root
86862306a36Sopenharmony_ci * @node:		pointer to tree node
86962306a36Sopenharmony_ci * @slot:		pointer to slot in @node
87062306a36Sopenharmony_ci * @item:		new item to store in the slot.
87162306a36Sopenharmony_ci *
87262306a36Sopenharmony_ci * For use with __radix_tree_lookup().  Caller must hold tree write locked
87362306a36Sopenharmony_ci * across slot lookup and replacement.
87462306a36Sopenharmony_ci */
87562306a36Sopenharmony_civoid __radix_tree_replace(struct radix_tree_root *root,
87662306a36Sopenharmony_ci			  struct radix_tree_node *node,
87762306a36Sopenharmony_ci			  void __rcu **slot, void *item)
87862306a36Sopenharmony_ci{
87962306a36Sopenharmony_ci	void *old = rcu_dereference_raw(*slot);
88062306a36Sopenharmony_ci	int values = !!xa_is_value(item) - !!xa_is_value(old);
88162306a36Sopenharmony_ci	int count = calculate_count(root, node, slot, item, old);
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	/*
88462306a36Sopenharmony_ci	 * This function supports replacing value entries and
88562306a36Sopenharmony_ci	 * deleting entries, but that needs accounting against the
88662306a36Sopenharmony_ci	 * node unless the slot is root->xa_head.
88762306a36Sopenharmony_ci	 */
88862306a36Sopenharmony_ci	WARN_ON_ONCE(!node && (slot != (void __rcu **)&root->xa_head) &&
88962306a36Sopenharmony_ci			(count || values));
89062306a36Sopenharmony_ci	replace_slot(slot, item, node, count, values);
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci	if (!node)
89362306a36Sopenharmony_ci		return;
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	delete_node(root, node);
89662306a36Sopenharmony_ci}
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci/**
89962306a36Sopenharmony_ci * radix_tree_replace_slot	- replace item in a slot
90062306a36Sopenharmony_ci * @root:	radix tree root
90162306a36Sopenharmony_ci * @slot:	pointer to slot
90262306a36Sopenharmony_ci * @item:	new item to store in the slot.
90362306a36Sopenharmony_ci *
90462306a36Sopenharmony_ci * For use with radix_tree_lookup_slot() and
90562306a36Sopenharmony_ci * radix_tree_gang_lookup_tag_slot().  Caller must hold tree write locked
90662306a36Sopenharmony_ci * across slot lookup and replacement.
90762306a36Sopenharmony_ci *
90862306a36Sopenharmony_ci * NOTE: This cannot be used to switch between non-entries (empty slots),
90962306a36Sopenharmony_ci * regular entries, and value entries, as that requires accounting
91062306a36Sopenharmony_ci * inside the radix tree node. When switching from one type of entry or
91162306a36Sopenharmony_ci * deleting, use __radix_tree_lookup() and __radix_tree_replace() or
91262306a36Sopenharmony_ci * radix_tree_iter_replace().
91362306a36Sopenharmony_ci */
91462306a36Sopenharmony_civoid radix_tree_replace_slot(struct radix_tree_root *root,
91562306a36Sopenharmony_ci			     void __rcu **slot, void *item)
91662306a36Sopenharmony_ci{
91762306a36Sopenharmony_ci	__radix_tree_replace(root, NULL, slot, item);
91862306a36Sopenharmony_ci}
91962306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_replace_slot);
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci/**
92262306a36Sopenharmony_ci * radix_tree_iter_replace - replace item in a slot
92362306a36Sopenharmony_ci * @root:	radix tree root
92462306a36Sopenharmony_ci * @iter:	iterator state
92562306a36Sopenharmony_ci * @slot:	pointer to slot
92662306a36Sopenharmony_ci * @item:	new item to store in the slot.
92762306a36Sopenharmony_ci *
92862306a36Sopenharmony_ci * For use with radix_tree_for_each_slot().
92962306a36Sopenharmony_ci * Caller must hold tree write locked.
93062306a36Sopenharmony_ci */
93162306a36Sopenharmony_civoid radix_tree_iter_replace(struct radix_tree_root *root,
93262306a36Sopenharmony_ci				const struct radix_tree_iter *iter,
93362306a36Sopenharmony_ci				void __rcu **slot, void *item)
93462306a36Sopenharmony_ci{
93562306a36Sopenharmony_ci	__radix_tree_replace(root, iter->node, slot, item);
93662306a36Sopenharmony_ci}
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_cistatic void node_tag_set(struct radix_tree_root *root,
93962306a36Sopenharmony_ci				struct radix_tree_node *node,
94062306a36Sopenharmony_ci				unsigned int tag, unsigned int offset)
94162306a36Sopenharmony_ci{
94262306a36Sopenharmony_ci	while (node) {
94362306a36Sopenharmony_ci		if (tag_get(node, tag, offset))
94462306a36Sopenharmony_ci			return;
94562306a36Sopenharmony_ci		tag_set(node, tag, offset);
94662306a36Sopenharmony_ci		offset = node->offset;
94762306a36Sopenharmony_ci		node = node->parent;
94862306a36Sopenharmony_ci	}
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	if (!root_tag_get(root, tag))
95162306a36Sopenharmony_ci		root_tag_set(root, tag);
95262306a36Sopenharmony_ci}
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci/**
95562306a36Sopenharmony_ci *	radix_tree_tag_set - set a tag on a radix tree node
95662306a36Sopenharmony_ci *	@root:		radix tree root
95762306a36Sopenharmony_ci *	@index:		index key
95862306a36Sopenharmony_ci *	@tag:		tag index
95962306a36Sopenharmony_ci *
96062306a36Sopenharmony_ci *	Set the search tag (which must be < RADIX_TREE_MAX_TAGS)
96162306a36Sopenharmony_ci *	corresponding to @index in the radix tree.  From
96262306a36Sopenharmony_ci *	the root all the way down to the leaf node.
96362306a36Sopenharmony_ci *
96462306a36Sopenharmony_ci *	Returns the address of the tagged item.  Setting a tag on a not-present
96562306a36Sopenharmony_ci *	item is a bug.
96662306a36Sopenharmony_ci */
96762306a36Sopenharmony_civoid *radix_tree_tag_set(struct radix_tree_root *root,
96862306a36Sopenharmony_ci			unsigned long index, unsigned int tag)
96962306a36Sopenharmony_ci{
97062306a36Sopenharmony_ci	struct radix_tree_node *node, *parent;
97162306a36Sopenharmony_ci	unsigned long maxindex;
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	radix_tree_load_root(root, &node, &maxindex);
97462306a36Sopenharmony_ci	BUG_ON(index > maxindex);
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	while (radix_tree_is_internal_node(node)) {
97762306a36Sopenharmony_ci		unsigned offset;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci		parent = entry_to_node(node);
98062306a36Sopenharmony_ci		offset = radix_tree_descend(parent, &node, index);
98162306a36Sopenharmony_ci		BUG_ON(!node);
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci		if (!tag_get(parent, tag, offset))
98462306a36Sopenharmony_ci			tag_set(parent, tag, offset);
98562306a36Sopenharmony_ci	}
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_ci	/* set the root's tag bit */
98862306a36Sopenharmony_ci	if (!root_tag_get(root, tag))
98962306a36Sopenharmony_ci		root_tag_set(root, tag);
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	return node;
99262306a36Sopenharmony_ci}
99362306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_tag_set);
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_cistatic void node_tag_clear(struct radix_tree_root *root,
99662306a36Sopenharmony_ci				struct radix_tree_node *node,
99762306a36Sopenharmony_ci				unsigned int tag, unsigned int offset)
99862306a36Sopenharmony_ci{
99962306a36Sopenharmony_ci	while (node) {
100062306a36Sopenharmony_ci		if (!tag_get(node, tag, offset))
100162306a36Sopenharmony_ci			return;
100262306a36Sopenharmony_ci		tag_clear(node, tag, offset);
100362306a36Sopenharmony_ci		if (any_tag_set(node, tag))
100462306a36Sopenharmony_ci			return;
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci		offset = node->offset;
100762306a36Sopenharmony_ci		node = node->parent;
100862306a36Sopenharmony_ci	}
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	/* clear the root's tag bit */
101162306a36Sopenharmony_ci	if (root_tag_get(root, tag))
101262306a36Sopenharmony_ci		root_tag_clear(root, tag);
101362306a36Sopenharmony_ci}
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci/**
101662306a36Sopenharmony_ci *	radix_tree_tag_clear - clear a tag on a radix tree node
101762306a36Sopenharmony_ci *	@root:		radix tree root
101862306a36Sopenharmony_ci *	@index:		index key
101962306a36Sopenharmony_ci *	@tag:		tag index
102062306a36Sopenharmony_ci *
102162306a36Sopenharmony_ci *	Clear the search tag (which must be < RADIX_TREE_MAX_TAGS)
102262306a36Sopenharmony_ci *	corresponding to @index in the radix tree.  If this causes
102362306a36Sopenharmony_ci *	the leaf node to have no tags set then clear the tag in the
102462306a36Sopenharmony_ci *	next-to-leaf node, etc.
102562306a36Sopenharmony_ci *
102662306a36Sopenharmony_ci *	Returns the address of the tagged item on success, else NULL.  ie:
102762306a36Sopenharmony_ci *	has the same return value and semantics as radix_tree_lookup().
102862306a36Sopenharmony_ci */
102962306a36Sopenharmony_civoid *radix_tree_tag_clear(struct radix_tree_root *root,
103062306a36Sopenharmony_ci			unsigned long index, unsigned int tag)
103162306a36Sopenharmony_ci{
103262306a36Sopenharmony_ci	struct radix_tree_node *node, *parent;
103362306a36Sopenharmony_ci	unsigned long maxindex;
103462306a36Sopenharmony_ci	int offset = 0;
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci	radix_tree_load_root(root, &node, &maxindex);
103762306a36Sopenharmony_ci	if (index > maxindex)
103862306a36Sopenharmony_ci		return NULL;
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci	parent = NULL;
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_ci	while (radix_tree_is_internal_node(node)) {
104362306a36Sopenharmony_ci		parent = entry_to_node(node);
104462306a36Sopenharmony_ci		offset = radix_tree_descend(parent, &node, index);
104562306a36Sopenharmony_ci	}
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	if (node)
104862306a36Sopenharmony_ci		node_tag_clear(root, parent, tag, offset);
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_ci	return node;
105162306a36Sopenharmony_ci}
105262306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_tag_clear);
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci/**
105562306a36Sopenharmony_ci  * radix_tree_iter_tag_clear - clear a tag on the current iterator entry
105662306a36Sopenharmony_ci  * @root: radix tree root
105762306a36Sopenharmony_ci  * @iter: iterator state
105862306a36Sopenharmony_ci  * @tag: tag to clear
105962306a36Sopenharmony_ci  */
106062306a36Sopenharmony_civoid radix_tree_iter_tag_clear(struct radix_tree_root *root,
106162306a36Sopenharmony_ci			const struct radix_tree_iter *iter, unsigned int tag)
106262306a36Sopenharmony_ci{
106362306a36Sopenharmony_ci	node_tag_clear(root, iter->node, tag, iter_offset(iter));
106462306a36Sopenharmony_ci}
106562306a36Sopenharmony_ci
106662306a36Sopenharmony_ci/**
106762306a36Sopenharmony_ci * radix_tree_tag_get - get a tag on a radix tree node
106862306a36Sopenharmony_ci * @root:		radix tree root
106962306a36Sopenharmony_ci * @index:		index key
107062306a36Sopenharmony_ci * @tag:		tag index (< RADIX_TREE_MAX_TAGS)
107162306a36Sopenharmony_ci *
107262306a36Sopenharmony_ci * Return values:
107362306a36Sopenharmony_ci *
107462306a36Sopenharmony_ci *  0: tag not present or not set
107562306a36Sopenharmony_ci *  1: tag set
107662306a36Sopenharmony_ci *
107762306a36Sopenharmony_ci * Note that the return value of this function may not be relied on, even if
107862306a36Sopenharmony_ci * the RCU lock is held, unless tag modification and node deletion are excluded
107962306a36Sopenharmony_ci * from concurrency.
108062306a36Sopenharmony_ci */
108162306a36Sopenharmony_ciint radix_tree_tag_get(const struct radix_tree_root *root,
108262306a36Sopenharmony_ci			unsigned long index, unsigned int tag)
108362306a36Sopenharmony_ci{
108462306a36Sopenharmony_ci	struct radix_tree_node *node, *parent;
108562306a36Sopenharmony_ci	unsigned long maxindex;
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci	if (!root_tag_get(root, tag))
108862306a36Sopenharmony_ci		return 0;
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	radix_tree_load_root(root, &node, &maxindex);
109162306a36Sopenharmony_ci	if (index > maxindex)
109262306a36Sopenharmony_ci		return 0;
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci	while (radix_tree_is_internal_node(node)) {
109562306a36Sopenharmony_ci		unsigned offset;
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci		parent = entry_to_node(node);
109862306a36Sopenharmony_ci		offset = radix_tree_descend(parent, &node, index);
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci		if (!tag_get(parent, tag, offset))
110162306a36Sopenharmony_ci			return 0;
110262306a36Sopenharmony_ci		if (node == RADIX_TREE_RETRY)
110362306a36Sopenharmony_ci			break;
110462306a36Sopenharmony_ci	}
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci	return 1;
110762306a36Sopenharmony_ci}
110862306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_tag_get);
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci/* Construct iter->tags bit-mask from node->tags[tag] array */
111162306a36Sopenharmony_cistatic void set_iter_tags(struct radix_tree_iter *iter,
111262306a36Sopenharmony_ci				struct radix_tree_node *node, unsigned offset,
111362306a36Sopenharmony_ci				unsigned tag)
111462306a36Sopenharmony_ci{
111562306a36Sopenharmony_ci	unsigned tag_long = offset / BITS_PER_LONG;
111662306a36Sopenharmony_ci	unsigned tag_bit  = offset % BITS_PER_LONG;
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci	if (!node) {
111962306a36Sopenharmony_ci		iter->tags = 1;
112062306a36Sopenharmony_ci		return;
112162306a36Sopenharmony_ci	}
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci	iter->tags = node->tags[tag][tag_long] >> tag_bit;
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	/* This never happens if RADIX_TREE_TAG_LONGS == 1 */
112662306a36Sopenharmony_ci	if (tag_long < RADIX_TREE_TAG_LONGS - 1) {
112762306a36Sopenharmony_ci		/* Pick tags from next element */
112862306a36Sopenharmony_ci		if (tag_bit)
112962306a36Sopenharmony_ci			iter->tags |= node->tags[tag][tag_long + 1] <<
113062306a36Sopenharmony_ci						(BITS_PER_LONG - tag_bit);
113162306a36Sopenharmony_ci		/* Clip chunk size, here only BITS_PER_LONG tags */
113262306a36Sopenharmony_ci		iter->next_index = __radix_tree_iter_add(iter, BITS_PER_LONG);
113362306a36Sopenharmony_ci	}
113462306a36Sopenharmony_ci}
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_civoid __rcu **radix_tree_iter_resume(void __rcu **slot,
113762306a36Sopenharmony_ci					struct radix_tree_iter *iter)
113862306a36Sopenharmony_ci{
113962306a36Sopenharmony_ci	iter->index = __radix_tree_iter_add(iter, 1);
114062306a36Sopenharmony_ci	iter->next_index = iter->index;
114162306a36Sopenharmony_ci	iter->tags = 0;
114262306a36Sopenharmony_ci	return NULL;
114362306a36Sopenharmony_ci}
114462306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_iter_resume);
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci/**
114762306a36Sopenharmony_ci * radix_tree_next_chunk - find next chunk of slots for iteration
114862306a36Sopenharmony_ci *
114962306a36Sopenharmony_ci * @root:	radix tree root
115062306a36Sopenharmony_ci * @iter:	iterator state
115162306a36Sopenharmony_ci * @flags:	RADIX_TREE_ITER_* flags and tag index
115262306a36Sopenharmony_ci * Returns:	pointer to chunk first slot, or NULL if iteration is over
115362306a36Sopenharmony_ci */
115462306a36Sopenharmony_civoid __rcu **radix_tree_next_chunk(const struct radix_tree_root *root,
115562306a36Sopenharmony_ci			     struct radix_tree_iter *iter, unsigned flags)
115662306a36Sopenharmony_ci{
115762306a36Sopenharmony_ci	unsigned tag = flags & RADIX_TREE_ITER_TAG_MASK;
115862306a36Sopenharmony_ci	struct radix_tree_node *node, *child;
115962306a36Sopenharmony_ci	unsigned long index, offset, maxindex;
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	if ((flags & RADIX_TREE_ITER_TAGGED) && !root_tag_get(root, tag))
116262306a36Sopenharmony_ci		return NULL;
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci	/*
116562306a36Sopenharmony_ci	 * Catch next_index overflow after ~0UL. iter->index never overflows
116662306a36Sopenharmony_ci	 * during iterating; it can be zero only at the beginning.
116762306a36Sopenharmony_ci	 * And we cannot overflow iter->next_index in a single step,
116862306a36Sopenharmony_ci	 * because RADIX_TREE_MAP_SHIFT < BITS_PER_LONG.
116962306a36Sopenharmony_ci	 *
117062306a36Sopenharmony_ci	 * This condition also used by radix_tree_next_slot() to stop
117162306a36Sopenharmony_ci	 * contiguous iterating, and forbid switching to the next chunk.
117262306a36Sopenharmony_ci	 */
117362306a36Sopenharmony_ci	index = iter->next_index;
117462306a36Sopenharmony_ci	if (!index && iter->index)
117562306a36Sopenharmony_ci		return NULL;
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ci restart:
117862306a36Sopenharmony_ci	radix_tree_load_root(root, &child, &maxindex);
117962306a36Sopenharmony_ci	if (index > maxindex)
118062306a36Sopenharmony_ci		return NULL;
118162306a36Sopenharmony_ci	if (!child)
118262306a36Sopenharmony_ci		return NULL;
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_ci	if (!radix_tree_is_internal_node(child)) {
118562306a36Sopenharmony_ci		/* Single-slot tree */
118662306a36Sopenharmony_ci		iter->index = index;
118762306a36Sopenharmony_ci		iter->next_index = maxindex + 1;
118862306a36Sopenharmony_ci		iter->tags = 1;
118962306a36Sopenharmony_ci		iter->node = NULL;
119062306a36Sopenharmony_ci		return (void __rcu **)&root->xa_head;
119162306a36Sopenharmony_ci	}
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci	do {
119462306a36Sopenharmony_ci		node = entry_to_node(child);
119562306a36Sopenharmony_ci		offset = radix_tree_descend(node, &child, index);
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci		if ((flags & RADIX_TREE_ITER_TAGGED) ?
119862306a36Sopenharmony_ci				!tag_get(node, tag, offset) : !child) {
119962306a36Sopenharmony_ci			/* Hole detected */
120062306a36Sopenharmony_ci			if (flags & RADIX_TREE_ITER_CONTIG)
120162306a36Sopenharmony_ci				return NULL;
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci			if (flags & RADIX_TREE_ITER_TAGGED)
120462306a36Sopenharmony_ci				offset = radix_tree_find_next_bit(node, tag,
120562306a36Sopenharmony_ci						offset + 1);
120662306a36Sopenharmony_ci			else
120762306a36Sopenharmony_ci				while (++offset	< RADIX_TREE_MAP_SIZE) {
120862306a36Sopenharmony_ci					void *slot = rcu_dereference_raw(
120962306a36Sopenharmony_ci							node->slots[offset]);
121062306a36Sopenharmony_ci					if (slot)
121162306a36Sopenharmony_ci						break;
121262306a36Sopenharmony_ci				}
121362306a36Sopenharmony_ci			index &= ~node_maxindex(node);
121462306a36Sopenharmony_ci			index += offset << node->shift;
121562306a36Sopenharmony_ci			/* Overflow after ~0UL */
121662306a36Sopenharmony_ci			if (!index)
121762306a36Sopenharmony_ci				return NULL;
121862306a36Sopenharmony_ci			if (offset == RADIX_TREE_MAP_SIZE)
121962306a36Sopenharmony_ci				goto restart;
122062306a36Sopenharmony_ci			child = rcu_dereference_raw(node->slots[offset]);
122162306a36Sopenharmony_ci		}
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci		if (!child)
122462306a36Sopenharmony_ci			goto restart;
122562306a36Sopenharmony_ci		if (child == RADIX_TREE_RETRY)
122662306a36Sopenharmony_ci			break;
122762306a36Sopenharmony_ci	} while (node->shift && radix_tree_is_internal_node(child));
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	/* Update the iterator state */
123062306a36Sopenharmony_ci	iter->index = (index &~ node_maxindex(node)) | offset;
123162306a36Sopenharmony_ci	iter->next_index = (index | node_maxindex(node)) + 1;
123262306a36Sopenharmony_ci	iter->node = node;
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_ci	if (flags & RADIX_TREE_ITER_TAGGED)
123562306a36Sopenharmony_ci		set_iter_tags(iter, node, offset, tag);
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_ci	return node->slots + offset;
123862306a36Sopenharmony_ci}
123962306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_next_chunk);
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci/**
124262306a36Sopenharmony_ci *	radix_tree_gang_lookup - perform multiple lookup on a radix tree
124362306a36Sopenharmony_ci *	@root:		radix tree root
124462306a36Sopenharmony_ci *	@results:	where the results of the lookup are placed
124562306a36Sopenharmony_ci *	@first_index:	start the lookup from this key
124662306a36Sopenharmony_ci *	@max_items:	place up to this many items at *results
124762306a36Sopenharmony_ci *
124862306a36Sopenharmony_ci *	Performs an index-ascending scan of the tree for present items.  Places
124962306a36Sopenharmony_ci *	them at *@results and returns the number of items which were placed at
125062306a36Sopenharmony_ci *	*@results.
125162306a36Sopenharmony_ci *
125262306a36Sopenharmony_ci *	The implementation is naive.
125362306a36Sopenharmony_ci *
125462306a36Sopenharmony_ci *	Like radix_tree_lookup, radix_tree_gang_lookup may be called under
125562306a36Sopenharmony_ci *	rcu_read_lock. In this case, rather than the returned results being
125662306a36Sopenharmony_ci *	an atomic snapshot of the tree at a single point in time, the
125762306a36Sopenharmony_ci *	semantics of an RCU protected gang lookup are as though multiple
125862306a36Sopenharmony_ci *	radix_tree_lookups have been issued in individual locks, and results
125962306a36Sopenharmony_ci *	stored in 'results'.
126062306a36Sopenharmony_ci */
126162306a36Sopenharmony_ciunsigned int
126262306a36Sopenharmony_ciradix_tree_gang_lookup(const struct radix_tree_root *root, void **results,
126362306a36Sopenharmony_ci			unsigned long first_index, unsigned int max_items)
126462306a36Sopenharmony_ci{
126562306a36Sopenharmony_ci	struct radix_tree_iter iter;
126662306a36Sopenharmony_ci	void __rcu **slot;
126762306a36Sopenharmony_ci	unsigned int ret = 0;
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_ci	if (unlikely(!max_items))
127062306a36Sopenharmony_ci		return 0;
127162306a36Sopenharmony_ci
127262306a36Sopenharmony_ci	radix_tree_for_each_slot(slot, root, &iter, first_index) {
127362306a36Sopenharmony_ci		results[ret] = rcu_dereference_raw(*slot);
127462306a36Sopenharmony_ci		if (!results[ret])
127562306a36Sopenharmony_ci			continue;
127662306a36Sopenharmony_ci		if (radix_tree_is_internal_node(results[ret])) {
127762306a36Sopenharmony_ci			slot = radix_tree_iter_retry(&iter);
127862306a36Sopenharmony_ci			continue;
127962306a36Sopenharmony_ci		}
128062306a36Sopenharmony_ci		if (++ret == max_items)
128162306a36Sopenharmony_ci			break;
128262306a36Sopenharmony_ci	}
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	return ret;
128562306a36Sopenharmony_ci}
128662306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_gang_lookup);
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci/**
128962306a36Sopenharmony_ci *	radix_tree_gang_lookup_tag - perform multiple lookup on a radix tree
129062306a36Sopenharmony_ci *	                             based on a tag
129162306a36Sopenharmony_ci *	@root:		radix tree root
129262306a36Sopenharmony_ci *	@results:	where the results of the lookup are placed
129362306a36Sopenharmony_ci *	@first_index:	start the lookup from this key
129462306a36Sopenharmony_ci *	@max_items:	place up to this many items at *results
129562306a36Sopenharmony_ci *	@tag:		the tag index (< RADIX_TREE_MAX_TAGS)
129662306a36Sopenharmony_ci *
129762306a36Sopenharmony_ci *	Performs an index-ascending scan of the tree for present items which
129862306a36Sopenharmony_ci *	have the tag indexed by @tag set.  Places the items at *@results and
129962306a36Sopenharmony_ci *	returns the number of items which were placed at *@results.
130062306a36Sopenharmony_ci */
130162306a36Sopenharmony_ciunsigned int
130262306a36Sopenharmony_ciradix_tree_gang_lookup_tag(const struct radix_tree_root *root, void **results,
130362306a36Sopenharmony_ci		unsigned long first_index, unsigned int max_items,
130462306a36Sopenharmony_ci		unsigned int tag)
130562306a36Sopenharmony_ci{
130662306a36Sopenharmony_ci	struct radix_tree_iter iter;
130762306a36Sopenharmony_ci	void __rcu **slot;
130862306a36Sopenharmony_ci	unsigned int ret = 0;
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_ci	if (unlikely(!max_items))
131162306a36Sopenharmony_ci		return 0;
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci	radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
131462306a36Sopenharmony_ci		results[ret] = rcu_dereference_raw(*slot);
131562306a36Sopenharmony_ci		if (!results[ret])
131662306a36Sopenharmony_ci			continue;
131762306a36Sopenharmony_ci		if (radix_tree_is_internal_node(results[ret])) {
131862306a36Sopenharmony_ci			slot = radix_tree_iter_retry(&iter);
131962306a36Sopenharmony_ci			continue;
132062306a36Sopenharmony_ci		}
132162306a36Sopenharmony_ci		if (++ret == max_items)
132262306a36Sopenharmony_ci			break;
132362306a36Sopenharmony_ci	}
132462306a36Sopenharmony_ci
132562306a36Sopenharmony_ci	return ret;
132662306a36Sopenharmony_ci}
132762306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_gang_lookup_tag);
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci/**
133062306a36Sopenharmony_ci *	radix_tree_gang_lookup_tag_slot - perform multiple slot lookup on a
133162306a36Sopenharmony_ci *					  radix tree based on a tag
133262306a36Sopenharmony_ci *	@root:		radix tree root
133362306a36Sopenharmony_ci *	@results:	where the results of the lookup are placed
133462306a36Sopenharmony_ci *	@first_index:	start the lookup from this key
133562306a36Sopenharmony_ci *	@max_items:	place up to this many items at *results
133662306a36Sopenharmony_ci *	@tag:		the tag index (< RADIX_TREE_MAX_TAGS)
133762306a36Sopenharmony_ci *
133862306a36Sopenharmony_ci *	Performs an index-ascending scan of the tree for present items which
133962306a36Sopenharmony_ci *	have the tag indexed by @tag set.  Places the slots at *@results and
134062306a36Sopenharmony_ci *	returns the number of slots which were placed at *@results.
134162306a36Sopenharmony_ci */
134262306a36Sopenharmony_ciunsigned int
134362306a36Sopenharmony_ciradix_tree_gang_lookup_tag_slot(const struct radix_tree_root *root,
134462306a36Sopenharmony_ci		void __rcu ***results, unsigned long first_index,
134562306a36Sopenharmony_ci		unsigned int max_items, unsigned int tag)
134662306a36Sopenharmony_ci{
134762306a36Sopenharmony_ci	struct radix_tree_iter iter;
134862306a36Sopenharmony_ci	void __rcu **slot;
134962306a36Sopenharmony_ci	unsigned int ret = 0;
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	if (unlikely(!max_items))
135262306a36Sopenharmony_ci		return 0;
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci	radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
135562306a36Sopenharmony_ci		results[ret] = slot;
135662306a36Sopenharmony_ci		if (++ret == max_items)
135762306a36Sopenharmony_ci			break;
135862306a36Sopenharmony_ci	}
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	return ret;
136162306a36Sopenharmony_ci}
136262306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot);
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_cistatic bool __radix_tree_delete(struct radix_tree_root *root,
136562306a36Sopenharmony_ci				struct radix_tree_node *node, void __rcu **slot)
136662306a36Sopenharmony_ci{
136762306a36Sopenharmony_ci	void *old = rcu_dereference_raw(*slot);
136862306a36Sopenharmony_ci	int values = xa_is_value(old) ? -1 : 0;
136962306a36Sopenharmony_ci	unsigned offset = get_slot_offset(node, slot);
137062306a36Sopenharmony_ci	int tag;
137162306a36Sopenharmony_ci
137262306a36Sopenharmony_ci	if (is_idr(root))
137362306a36Sopenharmony_ci		node_tag_set(root, node, IDR_FREE, offset);
137462306a36Sopenharmony_ci	else
137562306a36Sopenharmony_ci		for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++)
137662306a36Sopenharmony_ci			node_tag_clear(root, node, tag, offset);
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	replace_slot(slot, NULL, node, -1, values);
137962306a36Sopenharmony_ci	return node && delete_node(root, node);
138062306a36Sopenharmony_ci}
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_ci/**
138362306a36Sopenharmony_ci * radix_tree_iter_delete - delete the entry at this iterator position
138462306a36Sopenharmony_ci * @root: radix tree root
138562306a36Sopenharmony_ci * @iter: iterator state
138662306a36Sopenharmony_ci * @slot: pointer to slot
138762306a36Sopenharmony_ci *
138862306a36Sopenharmony_ci * Delete the entry at the position currently pointed to by the iterator.
138962306a36Sopenharmony_ci * This may result in the current node being freed; if it is, the iterator
139062306a36Sopenharmony_ci * is advanced so that it will not reference the freed memory.  This
139162306a36Sopenharmony_ci * function may be called without any locking if there are no other threads
139262306a36Sopenharmony_ci * which can access this tree.
139362306a36Sopenharmony_ci */
139462306a36Sopenharmony_civoid radix_tree_iter_delete(struct radix_tree_root *root,
139562306a36Sopenharmony_ci				struct radix_tree_iter *iter, void __rcu **slot)
139662306a36Sopenharmony_ci{
139762306a36Sopenharmony_ci	if (__radix_tree_delete(root, iter->node, slot))
139862306a36Sopenharmony_ci		iter->index = iter->next_index;
139962306a36Sopenharmony_ci}
140062306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_iter_delete);
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci/**
140362306a36Sopenharmony_ci * radix_tree_delete_item - delete an item from a radix tree
140462306a36Sopenharmony_ci * @root: radix tree root
140562306a36Sopenharmony_ci * @index: index key
140662306a36Sopenharmony_ci * @item: expected item
140762306a36Sopenharmony_ci *
140862306a36Sopenharmony_ci * Remove @item at @index from the radix tree rooted at @root.
140962306a36Sopenharmony_ci *
141062306a36Sopenharmony_ci * Return: the deleted entry, or %NULL if it was not present
141162306a36Sopenharmony_ci * or the entry at the given @index was not @item.
141262306a36Sopenharmony_ci */
141362306a36Sopenharmony_civoid *radix_tree_delete_item(struct radix_tree_root *root,
141462306a36Sopenharmony_ci			     unsigned long index, void *item)
141562306a36Sopenharmony_ci{
141662306a36Sopenharmony_ci	struct radix_tree_node *node = NULL;
141762306a36Sopenharmony_ci	void __rcu **slot = NULL;
141862306a36Sopenharmony_ci	void *entry;
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci	entry = __radix_tree_lookup(root, index, &node, &slot);
142162306a36Sopenharmony_ci	if (!slot)
142262306a36Sopenharmony_ci		return NULL;
142362306a36Sopenharmony_ci	if (!entry && (!is_idr(root) || node_tag_get(root, node, IDR_FREE,
142462306a36Sopenharmony_ci						get_slot_offset(node, slot))))
142562306a36Sopenharmony_ci		return NULL;
142662306a36Sopenharmony_ci
142762306a36Sopenharmony_ci	if (item && entry != item)
142862306a36Sopenharmony_ci		return NULL;
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	__radix_tree_delete(root, node, slot);
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_ci	return entry;
143362306a36Sopenharmony_ci}
143462306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_delete_item);
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci/**
143762306a36Sopenharmony_ci * radix_tree_delete - delete an entry from a radix tree
143862306a36Sopenharmony_ci * @root: radix tree root
143962306a36Sopenharmony_ci * @index: index key
144062306a36Sopenharmony_ci *
144162306a36Sopenharmony_ci * Remove the entry at @index from the radix tree rooted at @root.
144262306a36Sopenharmony_ci *
144362306a36Sopenharmony_ci * Return: The deleted entry, or %NULL if it was not present.
144462306a36Sopenharmony_ci */
144562306a36Sopenharmony_civoid *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
144662306a36Sopenharmony_ci{
144762306a36Sopenharmony_ci	return radix_tree_delete_item(root, index, NULL);
144862306a36Sopenharmony_ci}
144962306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_delete);
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_ci/**
145262306a36Sopenharmony_ci *	radix_tree_tagged - test whether any items in the tree are tagged
145362306a36Sopenharmony_ci *	@root:		radix tree root
145462306a36Sopenharmony_ci *	@tag:		tag to test
145562306a36Sopenharmony_ci */
145662306a36Sopenharmony_ciint radix_tree_tagged(const struct radix_tree_root *root, unsigned int tag)
145762306a36Sopenharmony_ci{
145862306a36Sopenharmony_ci	return root_tag_get(root, tag);
145962306a36Sopenharmony_ci}
146062306a36Sopenharmony_ciEXPORT_SYMBOL(radix_tree_tagged);
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci/**
146362306a36Sopenharmony_ci * idr_preload - preload for idr_alloc()
146462306a36Sopenharmony_ci * @gfp_mask: allocation mask to use for preloading
146562306a36Sopenharmony_ci *
146662306a36Sopenharmony_ci * Preallocate memory to use for the next call to idr_alloc().  This function
146762306a36Sopenharmony_ci * returns with preemption disabled.  It will be enabled by idr_preload_end().
146862306a36Sopenharmony_ci */
146962306a36Sopenharmony_civoid idr_preload(gfp_t gfp_mask)
147062306a36Sopenharmony_ci{
147162306a36Sopenharmony_ci	if (__radix_tree_preload(gfp_mask, IDR_PRELOAD_SIZE))
147262306a36Sopenharmony_ci		local_lock(&radix_tree_preloads.lock);
147362306a36Sopenharmony_ci}
147462306a36Sopenharmony_ciEXPORT_SYMBOL(idr_preload);
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_civoid __rcu **idr_get_free(struct radix_tree_root *root,
147762306a36Sopenharmony_ci			      struct radix_tree_iter *iter, gfp_t gfp,
147862306a36Sopenharmony_ci			      unsigned long max)
147962306a36Sopenharmony_ci{
148062306a36Sopenharmony_ci	struct radix_tree_node *node = NULL, *child;
148162306a36Sopenharmony_ci	void __rcu **slot = (void __rcu **)&root->xa_head;
148262306a36Sopenharmony_ci	unsigned long maxindex, start = iter->next_index;
148362306a36Sopenharmony_ci	unsigned int shift, offset = 0;
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ci grow:
148662306a36Sopenharmony_ci	shift = radix_tree_load_root(root, &child, &maxindex);
148762306a36Sopenharmony_ci	if (!radix_tree_tagged(root, IDR_FREE))
148862306a36Sopenharmony_ci		start = max(start, maxindex + 1);
148962306a36Sopenharmony_ci	if (start > max)
149062306a36Sopenharmony_ci		return ERR_PTR(-ENOSPC);
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci	if (start > maxindex) {
149362306a36Sopenharmony_ci		int error = radix_tree_extend(root, gfp, start, shift);
149462306a36Sopenharmony_ci		if (error < 0)
149562306a36Sopenharmony_ci			return ERR_PTR(error);
149662306a36Sopenharmony_ci		shift = error;
149762306a36Sopenharmony_ci		child = rcu_dereference_raw(root->xa_head);
149862306a36Sopenharmony_ci	}
149962306a36Sopenharmony_ci	if (start == 0 && shift == 0)
150062306a36Sopenharmony_ci		shift = RADIX_TREE_MAP_SHIFT;
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	while (shift) {
150362306a36Sopenharmony_ci		shift -= RADIX_TREE_MAP_SHIFT;
150462306a36Sopenharmony_ci		if (child == NULL) {
150562306a36Sopenharmony_ci			/* Have to add a child node.  */
150662306a36Sopenharmony_ci			child = radix_tree_node_alloc(gfp, node, root, shift,
150762306a36Sopenharmony_ci							offset, 0, 0);
150862306a36Sopenharmony_ci			if (!child)
150962306a36Sopenharmony_ci				return ERR_PTR(-ENOMEM);
151062306a36Sopenharmony_ci			all_tag_set(child, IDR_FREE);
151162306a36Sopenharmony_ci			rcu_assign_pointer(*slot, node_to_entry(child));
151262306a36Sopenharmony_ci			if (node)
151362306a36Sopenharmony_ci				node->count++;
151462306a36Sopenharmony_ci		} else if (!radix_tree_is_internal_node(child))
151562306a36Sopenharmony_ci			break;
151662306a36Sopenharmony_ci
151762306a36Sopenharmony_ci		node = entry_to_node(child);
151862306a36Sopenharmony_ci		offset = radix_tree_descend(node, &child, start);
151962306a36Sopenharmony_ci		if (!tag_get(node, IDR_FREE, offset)) {
152062306a36Sopenharmony_ci			offset = radix_tree_find_next_bit(node, IDR_FREE,
152162306a36Sopenharmony_ci							offset + 1);
152262306a36Sopenharmony_ci			start = next_index(start, node, offset);
152362306a36Sopenharmony_ci			if (start > max || start == 0)
152462306a36Sopenharmony_ci				return ERR_PTR(-ENOSPC);
152562306a36Sopenharmony_ci			while (offset == RADIX_TREE_MAP_SIZE) {
152662306a36Sopenharmony_ci				offset = node->offset + 1;
152762306a36Sopenharmony_ci				node = node->parent;
152862306a36Sopenharmony_ci				if (!node)
152962306a36Sopenharmony_ci					goto grow;
153062306a36Sopenharmony_ci				shift = node->shift;
153162306a36Sopenharmony_ci			}
153262306a36Sopenharmony_ci			child = rcu_dereference_raw(node->slots[offset]);
153362306a36Sopenharmony_ci		}
153462306a36Sopenharmony_ci		slot = &node->slots[offset];
153562306a36Sopenharmony_ci	}
153662306a36Sopenharmony_ci
153762306a36Sopenharmony_ci	iter->index = start;
153862306a36Sopenharmony_ci	if (node)
153962306a36Sopenharmony_ci		iter->next_index = 1 + min(max, (start | node_maxindex(node)));
154062306a36Sopenharmony_ci	else
154162306a36Sopenharmony_ci		iter->next_index = 1;
154262306a36Sopenharmony_ci	iter->node = node;
154362306a36Sopenharmony_ci	set_iter_tags(iter, node, offset, IDR_FREE);
154462306a36Sopenharmony_ci
154562306a36Sopenharmony_ci	return slot;
154662306a36Sopenharmony_ci}
154762306a36Sopenharmony_ci
154862306a36Sopenharmony_ci/**
154962306a36Sopenharmony_ci * idr_destroy - release all internal memory from an IDR
155062306a36Sopenharmony_ci * @idr: idr handle
155162306a36Sopenharmony_ci *
155262306a36Sopenharmony_ci * After this function is called, the IDR is empty, and may be reused or
155362306a36Sopenharmony_ci * the data structure containing it may be freed.
155462306a36Sopenharmony_ci *
155562306a36Sopenharmony_ci * A typical clean-up sequence for objects stored in an idr tree will use
155662306a36Sopenharmony_ci * idr_for_each() to free all objects, if necessary, then idr_destroy() to
155762306a36Sopenharmony_ci * free the memory used to keep track of those objects.
155862306a36Sopenharmony_ci */
155962306a36Sopenharmony_civoid idr_destroy(struct idr *idr)
156062306a36Sopenharmony_ci{
156162306a36Sopenharmony_ci	struct radix_tree_node *node = rcu_dereference_raw(idr->idr_rt.xa_head);
156262306a36Sopenharmony_ci	if (radix_tree_is_internal_node(node))
156362306a36Sopenharmony_ci		radix_tree_free_nodes(node);
156462306a36Sopenharmony_ci	idr->idr_rt.xa_head = NULL;
156562306a36Sopenharmony_ci	root_tag_set(&idr->idr_rt, IDR_FREE);
156662306a36Sopenharmony_ci}
156762306a36Sopenharmony_ciEXPORT_SYMBOL(idr_destroy);
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_cistatic void
157062306a36Sopenharmony_ciradix_tree_node_ctor(void *arg)
157162306a36Sopenharmony_ci{
157262306a36Sopenharmony_ci	struct radix_tree_node *node = arg;
157362306a36Sopenharmony_ci
157462306a36Sopenharmony_ci	memset(node, 0, sizeof(*node));
157562306a36Sopenharmony_ci	INIT_LIST_HEAD(&node->private_list);
157662306a36Sopenharmony_ci}
157762306a36Sopenharmony_ci
157862306a36Sopenharmony_cistatic int radix_tree_cpu_dead(unsigned int cpu)
157962306a36Sopenharmony_ci{
158062306a36Sopenharmony_ci	struct radix_tree_preload *rtp;
158162306a36Sopenharmony_ci	struct radix_tree_node *node;
158262306a36Sopenharmony_ci
158362306a36Sopenharmony_ci	/* Free per-cpu pool of preloaded nodes */
158462306a36Sopenharmony_ci	rtp = &per_cpu(radix_tree_preloads, cpu);
158562306a36Sopenharmony_ci	while (rtp->nr) {
158662306a36Sopenharmony_ci		node = rtp->nodes;
158762306a36Sopenharmony_ci		rtp->nodes = node->parent;
158862306a36Sopenharmony_ci		kmem_cache_free(radix_tree_node_cachep, node);
158962306a36Sopenharmony_ci		rtp->nr--;
159062306a36Sopenharmony_ci	}
159162306a36Sopenharmony_ci	return 0;
159262306a36Sopenharmony_ci}
159362306a36Sopenharmony_ci
159462306a36Sopenharmony_civoid __init radix_tree_init(void)
159562306a36Sopenharmony_ci{
159662306a36Sopenharmony_ci	int ret;
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	BUILD_BUG_ON(RADIX_TREE_MAX_TAGS + __GFP_BITS_SHIFT > 32);
159962306a36Sopenharmony_ci	BUILD_BUG_ON(ROOT_IS_IDR & ~GFP_ZONEMASK);
160062306a36Sopenharmony_ci	BUILD_BUG_ON(XA_CHUNK_SIZE > 255);
160162306a36Sopenharmony_ci	radix_tree_node_cachep = kmem_cache_create("radix_tree_node",
160262306a36Sopenharmony_ci			sizeof(struct radix_tree_node), 0,
160362306a36Sopenharmony_ci			SLAB_PANIC | SLAB_RECLAIM_ACCOUNT,
160462306a36Sopenharmony_ci			radix_tree_node_ctor);
160562306a36Sopenharmony_ci	ret = cpuhp_setup_state_nocalls(CPUHP_RADIX_DEAD, "lib/radix:dead",
160662306a36Sopenharmony_ci					NULL, radix_tree_cpu_dead);
160762306a36Sopenharmony_ci	WARN_ON(ret < 0);
160862306a36Sopenharmony_ci}
1609