Commit d0891265 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds
Browse files

radix-tree: remove root->height



The only remaining references to root->height were in extend and shrink,
where it was updated.  Now we can remove it entirely.

Signed-off-by: default avatarMatthew Wilcox <willy@linux.intel.com>
Reviewed-by: default avatarRoss Zwisler <ross.zwisler@linux.intel.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Kirill Shutemov <kirill.shutemov@linux.intel.com>
Cc: Jan Kara <jack@suse.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 0694f0c9
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -110,13 +110,11 @@ struct radix_tree_node {

/* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */
struct radix_tree_root {
	unsigned int		height;
	gfp_t			gfp_mask;
	struct radix_tree_node	__rcu *rnode;
};

#define RADIX_TREE_INIT(mask)	{					\
	.height = 0,							\
	.gfp_mask = (mask),						\
	.rnode = NULL,							\
}
@@ -126,7 +124,6 @@ struct radix_tree_root {

#define INIT_RADIX_TREE(root, mask)					\
do {									\
	(root)->height = 0;						\
	(root)->gfp_mask = (mask);					\
	(root)->rnode = NULL;						\
} while (0)
+31 −75
Original line number Diff line number Diff line
@@ -38,12 +38,6 @@
#include <linux/preempt.h>		/* in_interrupt() */


/*
 * The height_to_maxindex array needs to be one deeper than the maximum
 * path as height 0 holds only 1 entry.
 */
static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH + 1] __read_mostly;

/*
 * Radix tree node cache.
 */
@@ -218,8 +212,7 @@ radix_tree_find_next_bit(const unsigned long *addr,
}

#ifndef __KERNEL__
static void dump_node(struct radix_tree_node *node,
				unsigned shift, unsigned long index)
static void dump_node(struct radix_tree_node *node, unsigned long index)
{
	unsigned long i;

@@ -229,8 +222,8 @@ static void dump_node(struct radix_tree_node *node,
		node->shift, node->count, node->parent);

	for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) {
		unsigned long first = index | (i << shift);
		unsigned long last = first | ((1UL << shift) - 1);
		unsigned long first = index | (i << node->shift);
		unsigned long last = first | ((1UL << node->shift) - 1);
		void *entry = node->slots[i];
		if (!entry)
			continue;
@@ -243,8 +236,7 @@ static void dump_node(struct radix_tree_node *node,
			pr_debug("radix entry %p offset %ld indices %ld-%ld\n",
					entry, i, first, last);
		} else {
			dump_node(indirect_to_ptr(entry),
					shift - RADIX_TREE_MAP_SHIFT, first);
			dump_node(indirect_to_ptr(entry), first);
		}
	}
}
@@ -252,13 +244,12 @@ static void dump_node(struct radix_tree_node *node,
/* For debug */
static void radix_tree_dump(struct radix_tree_root *root)
{
	pr_debug("radix root: %p height %d rnode %p tags %x\n",
			root, root->height, root->rnode,
	pr_debug("radix root: %p rnode %p tags %x\n",
			root, root->rnode,
			root->gfp_mask >> __GFP_BITS_SHIFT);
	if (!radix_tree_is_indirect_ptr(root->rnode))
		return;
	dump_node(indirect_to_ptr(root->rnode),
				(root->height - 1) * RADIX_TREE_MAP_SHIFT, 0);
	dump_node(indirect_to_ptr(root->rnode), 0);
}
#endif

@@ -411,14 +402,8 @@ int radix_tree_maybe_preload(gfp_t gfp_mask)
EXPORT_SYMBOL(radix_tree_maybe_preload);

/*
 *	Return the maximum key which can be store into a
 *	radix tree with height HEIGHT.
 * The maximum index which can be stored in a radix tree
 */
static inline unsigned long radix_tree_maxindex(unsigned int height)
{
	return height_to_maxindex[height];
}

static inline unsigned long shift_maxindex(unsigned int shift)
{
	return (RADIX_TREE_MAP_SIZE << shift) - 1;
@@ -450,24 +435,22 @@ static unsigned radix_tree_load_root(struct radix_tree_root *root,
 *	Extend a radix tree so it can store key @index.
 */
static int radix_tree_extend(struct radix_tree_root *root,
				unsigned long index)
				unsigned long index, unsigned int shift)
{
	struct radix_tree_node *slot;
	unsigned int height;
	unsigned int maxshift;
	int tag;

	/* Figure out what the height should be.  */
	height = root->height + 1;
	while (index > radix_tree_maxindex(height))
		height++;
	/* Figure out what the shift should be.  */
	maxshift = shift;
	while (index > shift_maxindex(maxshift))
		maxshift += RADIX_TREE_MAP_SHIFT;

	if (root->rnode == NULL) {
		root->height = height;
	slot = root->rnode;
	if (!slot)
		goto out;
	}

	do {
		unsigned int newheight;
		struct radix_tree_node *node = radix_tree_node_alloc(root);

		if (!node)
@@ -479,14 +462,11 @@ static int radix_tree_extend(struct radix_tree_root *root,
				tag_set(node, tag, 0);
		}

		/* Increase the height.  */
		newheight = root->height;
		BUG_ON(newheight > BITS_PER_LONG);
		node->shift = newheight * RADIX_TREE_MAP_SHIFT;
		BUG_ON(shift > BITS_PER_LONG);
		node->shift = shift;
		node->offset = 0;
		node->count = 1;
		node->parent = NULL;
		slot = root->rnode;
		if (radix_tree_is_indirect_ptr(slot)) {
			slot = indirect_to_ptr(slot);
			slot->parent = node;
@@ -495,10 +475,11 @@ static int radix_tree_extend(struct radix_tree_root *root,
		node->slots[0] = slot;
		node = ptr_to_indirect(node);
		rcu_assign_pointer(root->rnode, node);
		root->height = ++newheight;
	} while (height > root->height);
		shift += RADIX_TREE_MAP_SHIFT;
		slot = node;
	} while (shift <= maxshift);
out:
	return height * RADIX_TREE_MAP_SHIFT;
	return maxshift + RADIX_TREE_MAP_SHIFT;
}

/**
@@ -531,15 +512,13 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,

	/* Make sure the tree is high enough.  */
	if (max > maxindex) {
		int error = radix_tree_extend(root, max);
		int error = radix_tree_extend(root, max, shift);
		if (error < 0)
			return error;
		shift = error;
		slot = root->rnode;
		if (order == shift) {
		if (order == shift)
			shift += RADIX_TREE_MAP_SHIFT;
			root->height++;
		}
	}

	offset = 0;			/* uninitialised var warning */
@@ -1412,32 +1391,32 @@ unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item)
#endif /* CONFIG_SHMEM && CONFIG_SWAP */

/**
 *	radix_tree_shrink    -    shrink height of a radix tree to minimal
 *	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;

	/* try to shrink tree height */
	while (root->height > 0) {
	for (;;) {
		struct radix_tree_node *to_free = root->rnode;
		struct radix_tree_node *slot;

		BUG_ON(!radix_tree_is_indirect_ptr(to_free));
		if (!radix_tree_is_indirect_ptr(to_free))
			break;
		to_free = indirect_to_ptr(to_free);

		/*
		 * The candidate node has more than one child, or its child
		 * is not at the leftmost slot, or it is a multiorder entry,
		 * we cannot shrink.
		 * is not at the leftmost slot, or the child is a multiorder
		 * entry, we cannot shrink.
		 */
		if (to_free->count != 1)
			break;
		slot = to_free->slots[0];
		if (!slot)
			break;
		if (!radix_tree_is_indirect_ptr(slot) && (root->height > 1))
		if (!radix_tree_is_indirect_ptr(slot) && to_free->shift)
			break;

		if (radix_tree_is_indirect_ptr(slot)) {
@@ -1454,7 +1433,6 @@ static inline bool radix_tree_shrink(struct radix_tree_root *root)
		 * one (root->rnode) as far as dependent read barriers go.
		 */
		root->rnode = slot;
		root->height--;

		/*
		 * We have a dilemma here. The node's slot[0] must not be
@@ -1515,7 +1493,6 @@ bool __radix_tree_delete_node(struct radix_tree_root *root,
			parent->count--;
		} else {
			root_tag_clear_all(root);
			root->height = 0;
			root->rnode = NULL;
		}

@@ -1631,26 +1608,6 @@ radix_tree_node_ctor(void *arg)
	INIT_LIST_HEAD(&node->private_list);
}

static __init unsigned long __maxindex(unsigned int height)
{
	unsigned int width = height * RADIX_TREE_MAP_SHIFT;
	int shift = RADIX_TREE_INDEX_BITS - width;

	if (shift < 0)
		return ~0UL;
	if (shift >= BITS_PER_LONG)
		return 0UL;
	return ~0UL >> shift;
}

static __init void radix_tree_init_maxindex(void)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(height_to_maxindex); i++)
		height_to_maxindex[i] = __maxindex(i);
}

static int radix_tree_callback(struct notifier_block *nfb,
				unsigned long action, void *hcpu)
{
@@ -1677,6 +1634,5 @@ void __init radix_tree_init(void)
			sizeof(struct radix_tree_node), 0,
			SLAB_PANIC | SLAB_RECLAIM_ACCOUNT,
			radix_tree_node_ctor);
	radix_tree_init_maxindex();
	hotcpu_notifier(radix_tree_callback, 0);
}