1608 lines · 43.1 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * Copyright (C) 2001 Momchil Velikov * Portions Copyright (C) 2001 Christoph Hellwig * Copyright (C) 2005 SGI, Christoph Lameter * Copyright (C) 2006 Nick Piggin * Copyright (C) 2012 Konstantin Khlebnikov * Copyright (C) 2016 Intel, Matthew Wilcox * Copyright (C) 2016 Intel, Ross Zwisler */ #include <linux/bitmap.h>#include <linux/bitops.h>#include <linux/bug.h>#include <linux/cpu.h>#include <linux/errno.h>#include <linux/export.h>#include <linux/idr.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/kmemleak.h>#include <linux/percpu.h>#include <linux/preempt.h>		/* in_interrupt() */#include <linux/radix-tree.h>#include <linux/rcupdate.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/xarray.h> #include "radix-tree.h" /* * Radix tree node cache. */struct kmem_cache *radix_tree_node_cachep; /* * The radix tree is variable-height, so an insert operation not only has * to build the branch to its corresponding item, it also has to build the * branch to existing items if the size has to be increased (by * radix_tree_extend). * * The worst case is a zero height tree with just a single item at index 0, * and then inserting an item at index ULONG_MAX. This requires 2 new branches * of RADIX_TREE_MAX_PATH size to be created, with only the root node shared. * Hence: */#define RADIX_TREE_PRELOAD_SIZE (RADIX_TREE_MAX_PATH * 2 - 1) /* * The IDR does not have to be as high as the radix tree since it uses * signed integers, not unsigned longs. */#define IDR_INDEX_BITS		(8 /* CHAR_BIT */ * sizeof(int) - 1)#define IDR_MAX_PATH		(DIV_ROUND_UP(IDR_INDEX_BITS, \						RADIX_TREE_MAP_SHIFT))#define IDR_PRELOAD_SIZE	(IDR_MAX_PATH * 2 - 1) /* * Per-cpu pool of preloaded nodes */DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = {	.lock = INIT_LOCAL_LOCK(lock),};EXPORT_PER_CPU_SYMBOL_GPL(radix_tree_preloads); static inline struct radix_tree_node *entry_to_node(void *ptr){	return (void *)((unsigned long)ptr & ~RADIX_TREE_INTERNAL_NODE);} static inline void *node_to_entry(void *ptr){	return (void *)((unsigned long)ptr | RADIX_TREE_INTERNAL_NODE);} #define RADIX_TREE_RETRY	XA_RETRY_ENTRY static inline unsigned longget_slot_offset(const struct radix_tree_node *parent, void __rcu **slot){	return parent ? slot - parent->slots : 0;} static unsigned int radix_tree_descend(const struct radix_tree_node *parent,			struct radix_tree_node **nodep, unsigned long index){	unsigned int offset = (index >> parent->shift) & RADIX_TREE_MAP_MASK;	void __rcu **entry = rcu_dereference_raw(parent->slots[offset]); 	*nodep = (void *)entry;	return offset;} static inline gfp_t root_gfp_mask(const struct radix_tree_root *root){	return root->xa_flags & (__GFP_BITS_MASK & ~GFP_ZONEMASK);} static inline void tag_set(struct radix_tree_node *node, unsigned int tag,		int offset){	__set_bit(offset, node->tags[tag]);} static inline void tag_clear(struct radix_tree_node *node, unsigned int tag,		int offset){	__clear_bit(offset, node->tags[tag]);} static inline int tag_get(const struct radix_tree_node *node, unsigned int tag,		int offset){	return test_bit(offset, node->tags[tag]);} static inline void root_tag_set(struct radix_tree_root *root, unsigned tag){	root->xa_flags |= (__force gfp_t)(1 << (tag + ROOT_TAG_SHIFT));} static inline void root_tag_clear(struct radix_tree_root *root, unsigned tag){	root->xa_flags &= (__force gfp_t)~(1 << (tag + ROOT_TAG_SHIFT));} static inline void root_tag_clear_all(struct radix_tree_root *root){	root->xa_flags &= (__force gfp_t)((1 << ROOT_TAG_SHIFT) - 1);} static inline int root_tag_get(const struct radix_tree_root *root, unsigned tag){	return (__force int)root->xa_flags & (1 << (tag + ROOT_TAG_SHIFT));} static inline unsigned root_tags_get(const struct radix_tree_root *root){	return (__force unsigned)root->xa_flags >> ROOT_TAG_SHIFT;} static inline bool is_idr(const struct radix_tree_root *root){	return !!(root->xa_flags & ROOT_IS_IDR);} /* * Returns 1 if any slot in the node has this tag set. * Otherwise returns 0. */static inline int any_tag_set(const struct radix_tree_node *node,							unsigned int tag){	unsigned idx;	for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {		if (node->tags[tag][idx])			return 1;	}	return 0;} static inline void all_tag_set(struct radix_tree_node *node, unsigned int tag){	bitmap_fill(node->tags[tag], RADIX_TREE_MAP_SIZE);} /** * radix_tree_find_next_bit - find the next set bit in a memory region * * @node: where to begin the search * @tag: the tag index * @offset: the bitnumber to start searching at * * Unrollable variant of find_next_bit() for constant size arrays. * Tail bits starting from size to roundup(size, BITS_PER_LONG) must be zero. * Returns next bit offset, or size if nothing found. */static __always_inline unsigned longradix_tree_find_next_bit(struct radix_tree_node *node, unsigned int tag,			 unsigned long offset){	const unsigned long *addr = node->tags[tag]; 	if (offset < RADIX_TREE_MAP_SIZE) {		unsigned long tmp; 		addr += offset / BITS_PER_LONG;		tmp = *addr >> (offset % BITS_PER_LONG);		if (tmp)			return __ffs(tmp) + offset;		offset = (offset + BITS_PER_LONG) & ~(BITS_PER_LONG - 1);		while (offset < RADIX_TREE_MAP_SIZE) {			tmp = *++addr;			if (tmp)				return __ffs(tmp) + offset;			offset += BITS_PER_LONG;		}	}	return RADIX_TREE_MAP_SIZE;} static unsigned int iter_offset(const struct radix_tree_iter *iter){	return iter->index & RADIX_TREE_MAP_MASK;} /* * The maximum index which can be stored in a radix tree */static inline unsigned long shift_maxindex(unsigned int shift){	return (RADIX_TREE_MAP_SIZE << shift) - 1;} static inline unsigned long node_maxindex(const struct radix_tree_node *node){	return shift_maxindex(node->shift);} static unsigned long next_index(unsigned long index,				const struct radix_tree_node *node,				unsigned long offset){	return (index & ~node_maxindex(node)) + (offset << node->shift);} /* * This assumes that the caller has performed appropriate preallocation, and * that the caller has pinned this thread of control to the current CPU. */static struct radix_tree_node *radix_tree_node_alloc(gfp_t gfp_mask, struct radix_tree_node *parent,			struct radix_tree_root *root,			unsigned int shift, unsigned int offset,			unsigned int count, unsigned int nr_values){	struct radix_tree_node *ret = NULL; 	/*	 * Preload code isn't irq safe and it doesn't make sense to use	 * preloading during an interrupt anyway as all the allocations have	 * to be atomic. So just do normal allocation when in interrupt.	 */	if (!gfpflags_allow_blocking(gfp_mask) && !in_interrupt()) {		struct radix_tree_preload *rtp; 		/*		 * Even if the caller has preloaded, try to allocate from the		 * cache first for the new node to get accounted to the memory		 * cgroup.		 */		ret = kmem_cache_alloc(radix_tree_node_cachep,				       gfp_mask | __GFP_NOWARN);		if (ret)			goto out; 		/*		 * Provided the caller has preloaded here, we will always		 * succeed in getting a node here (and never reach		 * kmem_cache_alloc)		 */		rtp = this_cpu_ptr(&radix_tree_preloads);		if (rtp->nr) {			ret = rtp->nodes;			rtp->nodes = ret->parent;			rtp->nr--;		}		/*		 * Update the allocation stack trace as this is more useful		 * for debugging.		 */		kmemleak_update_trace(ret);		goto out;	}	ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);out:	BUG_ON(radix_tree_is_internal_node(ret));	if (ret) {		ret->shift = shift;		ret->offset = offset;		ret->count = count;		ret->nr_values = nr_values;		ret->parent = parent;		ret->array = root;	}	return ret;} void radix_tree_node_rcu_free(struct rcu_head *head){	struct radix_tree_node *node =			container_of(head, struct radix_tree_node, rcu_head); 	/*	 * Must only free zeroed nodes into the slab.  We can be left with	 * non-NULL entries by radix_tree_free_nodes, so clear the entries	 * and tags here.	 */	memset(node->slots, 0, sizeof(node->slots));	memset(node->tags, 0, sizeof(node->tags));	INIT_LIST_HEAD(&node->private_list); 	kmem_cache_free(radix_tree_node_cachep, node);} static inline voidradix_tree_node_free(struct radix_tree_node *node){	call_rcu(&node->rcu_head, radix_tree_node_rcu_free);} /* * Load up this CPU's radix_tree_node buffer with sufficient objects to * ensure that the addition of a single element in the tree cannot fail.  On * success, return zero, with preemption disabled.  On error, return -ENOMEM * with preemption not disabled. * * To make use of this facility, the radix tree must be initialised without * __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE(). */static __must_check int __radix_tree_preload(gfp_t gfp_mask, unsigned nr){	struct radix_tree_preload *rtp;	struct radix_tree_node *node;	int ret = -ENOMEM; 	/*	 * Nodes preloaded by one cgroup can be used by another cgroup, so	 * they should never be accounted to any particular memory cgroup.	 */	gfp_mask &= ~__GFP_ACCOUNT; 	local_lock(&radix_tree_preloads.lock);	rtp = this_cpu_ptr(&radix_tree_preloads);	while (rtp->nr < nr) {		local_unlock(&radix_tree_preloads.lock);		node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);		if (node == NULL)			goto out;		local_lock(&radix_tree_preloads.lock);		rtp = this_cpu_ptr(&radix_tree_preloads);		if (rtp->nr < nr) {			node->parent = rtp->nodes;			rtp->nodes = node;			rtp->nr++;		} else {			kmem_cache_free(radix_tree_node_cachep, node);		}	}	ret = 0;out:	return ret;} /* * Load up this CPU's radix_tree_node buffer with sufficient objects to * ensure that the addition of a single element in the tree cannot fail.  On * success, return zero, with preemption disabled.  On error, return -ENOMEM * with preemption not disabled. * * To make use of this facility, the radix tree must be initialised without * __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE(). */int radix_tree_preload(gfp_t gfp_mask){	/* Warn on non-sensical use... */	WARN_ON_ONCE(!gfpflags_allow_blocking(gfp_mask));	return __radix_tree_preload(gfp_mask, RADIX_TREE_PRELOAD_SIZE);}EXPORT_SYMBOL(radix_tree_preload); /* * The same as above function, except we don't guarantee preloading happens. * We do it, if we decide it helps. On success, return zero with preemption * disabled. On error, return -ENOMEM with preemption not disabled. */int radix_tree_maybe_preload(gfp_t gfp_mask){	if (gfpflags_allow_blocking(gfp_mask))		return __radix_tree_preload(gfp_mask, RADIX_TREE_PRELOAD_SIZE);	/* Preloading doesn't help anything with this gfp mask, skip it */	local_lock(&radix_tree_preloads.lock);	return 0;}EXPORT_SYMBOL(radix_tree_maybe_preload); static unsigned radix_tree_load_root(const struct radix_tree_root *root,		struct radix_tree_node **nodep, unsigned long *maxindex){	struct radix_tree_node *node = rcu_dereference_raw(root->xa_head); 	*nodep = node; 	if (likely(radix_tree_is_internal_node(node))) {		node = entry_to_node(node);		*maxindex = node_maxindex(node);		return node->shift + RADIX_TREE_MAP_SHIFT;	} 	*maxindex = 0;	return 0;} /* *	Extend a radix tree so it can store key @index. */static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp,				unsigned long index, unsigned int shift){	void *entry;	unsigned int maxshift;	int tag; 	/* Figure out what the shift should be.  */	maxshift = shift;	while (index > shift_maxindex(maxshift))		maxshift += RADIX_TREE_MAP_SHIFT; 	entry = rcu_dereference_raw(root->xa_head);	if (!entry && (!is_idr(root) || root_tag_get(root, IDR_FREE)))		goto out; 	do {		struct radix_tree_node *node = radix_tree_node_alloc(gfp, NULL,							root, shift, 0, 1, 0);		if (!node)			return -ENOMEM; 		if (is_idr(root)) {			all_tag_set(node, IDR_FREE);			if (!root_tag_get(root, IDR_FREE)) {				tag_clear(node, IDR_FREE, 0);				root_tag_set(root, IDR_FREE);			}		} else {			/* Propagate the aggregated tag info to the new child */			for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {				if (root_tag_get(root, tag))					tag_set(node, tag, 0);			}		} 		BUG_ON(shift > BITS_PER_LONG);		if (radix_tree_is_internal_node(entry)) {			entry_to_node(entry)->parent = node;		} else if (xa_is_value(entry)) {			/* Moving a value entry root->xa_head to a node */			node->nr_values = 1;		}		/*		 * entry was already in the radix tree, so we do not need		 * rcu_assign_pointer here		 */		node->slots[0] = (void __rcu *)entry;		entry = node_to_entry(node);		rcu_assign_pointer(root->xa_head, entry);		shift += RADIX_TREE_MAP_SHIFT;	} while (shift <= maxshift);out:	return maxshift + RADIX_TREE_MAP_SHIFT;} /** *	radix_tree_shrink    -    shrink radix tree to minimum height *	@root:		radix tree root */static inline bool radix_tree_shrink(struct radix_tree_root *root){	bool shrunk = false; 	for (;;) {		struct radix_tree_node *node = rcu_dereference_raw(root->xa_head);		struct radix_tree_node *child; 		if (!radix_tree_is_internal_node(node))			break;		node = entry_to_node(node); 		/*		 * The candidate node has more than one child, or its child		 * is not at the leftmost slot, we cannot shrink.		 */		if (node->count != 1)			break;		child = rcu_dereference_raw(node->slots[0]);		if (!child)			break; 		/*		 * For an IDR, we must not shrink entry 0 into the root in		 * case somebody calls idr_replace() with a pointer that		 * appears to be an internal entry		 */		if (!node->shift && is_idr(root))			break; 		if (radix_tree_is_internal_node(child))			entry_to_node(child)->parent = NULL; 

Lines 1–500 of 1608.