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

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
...@@ -110,13 +110,11 @@ struct radix_tree_node { ...@@ -110,13 +110,11 @@ struct radix_tree_node {
/* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */ /* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */
struct radix_tree_root { struct radix_tree_root {
unsigned int height;
gfp_t gfp_mask; gfp_t gfp_mask;
struct radix_tree_node __rcu *rnode; struct radix_tree_node __rcu *rnode;
}; };
#define RADIX_TREE_INIT(mask) { \ #define RADIX_TREE_INIT(mask) { \
.height = 0, \
.gfp_mask = (mask), \ .gfp_mask = (mask), \
.rnode = NULL, \ .rnode = NULL, \
} }
...@@ -126,7 +124,6 @@ struct radix_tree_root { ...@@ -126,7 +124,6 @@ struct radix_tree_root {
#define INIT_RADIX_TREE(root, mask) \ #define INIT_RADIX_TREE(root, mask) \
do { \ do { \
(root)->height = 0; \
(root)->gfp_mask = (mask); \ (root)->gfp_mask = (mask); \
(root)->rnode = NULL; \ (root)->rnode = NULL; \
} while (0) } while (0)
......
...@@ -38,12 +38,6 @@ ...@@ -38,12 +38,6 @@
#include <linux/preempt.h> /* in_interrupt() */ #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. * Radix tree node cache.
*/ */
...@@ -218,8 +212,7 @@ radix_tree_find_next_bit(const unsigned long *addr, ...@@ -218,8 +212,7 @@ radix_tree_find_next_bit(const unsigned long *addr,
} }
#ifndef __KERNEL__ #ifndef __KERNEL__
static void dump_node(struct radix_tree_node *node, static void dump_node(struct radix_tree_node *node, unsigned long index)
unsigned shift, unsigned long index)
{ {
unsigned long i; unsigned long i;
...@@ -229,8 +222,8 @@ static void dump_node(struct radix_tree_node *node, ...@@ -229,8 +222,8 @@ static void dump_node(struct radix_tree_node *node,
node->shift, node->count, node->parent); node->shift, node->count, node->parent);
for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) { for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) {
unsigned long first = index | (i << shift); unsigned long first = index | (i << node->shift);
unsigned long last = first | ((1UL << shift) - 1); unsigned long last = first | ((1UL << node->shift) - 1);
void *entry = node->slots[i]; void *entry = node->slots[i];
if (!entry) if (!entry)
continue; continue;
...@@ -243,8 +236,7 @@ static void dump_node(struct radix_tree_node *node, ...@@ -243,8 +236,7 @@ static void dump_node(struct radix_tree_node *node,
pr_debug("radix entry %p offset %ld indices %ld-%ld\n", pr_debug("radix entry %p offset %ld indices %ld-%ld\n",
entry, i, first, last); entry, i, first, last);
} else { } else {
dump_node(indirect_to_ptr(entry), dump_node(indirect_to_ptr(entry), first);
shift - RADIX_TREE_MAP_SHIFT, first);
} }
} }
} }
...@@ -252,13 +244,12 @@ static void dump_node(struct radix_tree_node *node, ...@@ -252,13 +244,12 @@ static void dump_node(struct radix_tree_node *node,
/* For debug */ /* For debug */
static void radix_tree_dump(struct radix_tree_root *root) static void radix_tree_dump(struct radix_tree_root *root)
{ {
pr_debug("radix root: %p height %d rnode %p tags %x\n", pr_debug("radix root: %p rnode %p tags %x\n",
root, root->height, root->rnode, root, root->rnode,
root->gfp_mask >> __GFP_BITS_SHIFT); root->gfp_mask >> __GFP_BITS_SHIFT);
if (!radix_tree_is_indirect_ptr(root->rnode)) if (!radix_tree_is_indirect_ptr(root->rnode))
return; return;
dump_node(indirect_to_ptr(root->rnode), dump_node(indirect_to_ptr(root->rnode), 0);
(root->height - 1) * RADIX_TREE_MAP_SHIFT, 0);
} }
#endif #endif
...@@ -411,14 +402,8 @@ int radix_tree_maybe_preload(gfp_t gfp_mask) ...@@ -411,14 +402,8 @@ int radix_tree_maybe_preload(gfp_t gfp_mask)
EXPORT_SYMBOL(radix_tree_maybe_preload); EXPORT_SYMBOL(radix_tree_maybe_preload);
/* /*
* Return the maximum key which can be store into a * The maximum index which can be stored in a radix tree
* radix tree with height HEIGHT.
*/ */
static inline unsigned long radix_tree_maxindex(unsigned int height)
{
return height_to_maxindex[height];
}
static inline unsigned long shift_maxindex(unsigned int shift) static inline unsigned long shift_maxindex(unsigned int shift)
{ {
return (RADIX_TREE_MAP_SIZE << shift) - 1; return (RADIX_TREE_MAP_SIZE << shift) - 1;
...@@ -450,24 +435,22 @@ static unsigned radix_tree_load_root(struct radix_tree_root *root, ...@@ -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. * Extend a radix tree so it can store key @index.
*/ */
static int radix_tree_extend(struct radix_tree_root *root, static int radix_tree_extend(struct radix_tree_root *root,
unsigned long index) unsigned long index, unsigned int shift)
{ {
struct radix_tree_node *slot; struct radix_tree_node *slot;
unsigned int height; unsigned int maxshift;
int tag; int tag;
/* Figure out what the height should be. */ /* Figure out what the shift should be. */
height = root->height + 1; maxshift = shift;
while (index > radix_tree_maxindex(height)) while (index > shift_maxindex(maxshift))
height++; maxshift += RADIX_TREE_MAP_SHIFT;
if (root->rnode == NULL) { slot = root->rnode;
root->height = height; if (!slot)
goto out; goto out;
}
do { do {
unsigned int newheight;
struct radix_tree_node *node = radix_tree_node_alloc(root); struct radix_tree_node *node = radix_tree_node_alloc(root);
if (!node) if (!node)
...@@ -479,14 +462,11 @@ static int radix_tree_extend(struct radix_tree_root *root, ...@@ -479,14 +462,11 @@ static int radix_tree_extend(struct radix_tree_root *root,
tag_set(node, tag, 0); tag_set(node, tag, 0);
} }
/* Increase the height. */ BUG_ON(shift > BITS_PER_LONG);
newheight = root->height; node->shift = shift;
BUG_ON(newheight > BITS_PER_LONG);
node->shift = newheight * RADIX_TREE_MAP_SHIFT;
node->offset = 0; node->offset = 0;
node->count = 1; node->count = 1;
node->parent = NULL; node->parent = NULL;
slot = root->rnode;
if (radix_tree_is_indirect_ptr(slot)) { if (radix_tree_is_indirect_ptr(slot)) {
slot = indirect_to_ptr(slot); slot = indirect_to_ptr(slot);
slot->parent = node; slot->parent = node;
...@@ -495,10 +475,11 @@ static int radix_tree_extend(struct radix_tree_root *root, ...@@ -495,10 +475,11 @@ static int radix_tree_extend(struct radix_tree_root *root,
node->slots[0] = slot; node->slots[0] = slot;
node = ptr_to_indirect(node); node = ptr_to_indirect(node);
rcu_assign_pointer(root->rnode, node); rcu_assign_pointer(root->rnode, node);
root->height = ++newheight; shift += RADIX_TREE_MAP_SHIFT;
} while (height > root->height); slot = node;
} while (shift <= maxshift);
out: 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, ...@@ -531,15 +512,13 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
/* Make sure the tree is high enough. */ /* Make sure the tree is high enough. */
if (max > maxindex) { if (max > maxindex) {
int error = radix_tree_extend(root, max); int error = radix_tree_extend(root, max, shift);
if (error < 0) if (error < 0)
return error; return error;
shift = error; shift = error;
slot = root->rnode; slot = root->rnode;
if (order == shift) { if (order == shift)
shift += RADIX_TREE_MAP_SHIFT; shift += RADIX_TREE_MAP_SHIFT;
root->height++;
}
} }
offset = 0; /* uninitialised var warning */ offset = 0; /* uninitialised var warning */
...@@ -1412,32 +1391,32 @@ unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item) ...@@ -1412,32 +1391,32 @@ unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item)
#endif /* CONFIG_SHMEM && CONFIG_SWAP */ #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 * @root radix tree root
*/ */
static inline bool radix_tree_shrink(struct radix_tree_root *root) static inline bool radix_tree_shrink(struct radix_tree_root *root)
{ {
bool shrunk = false; bool shrunk = false;
/* try to shrink tree height */ for (;;) {
while (root->height > 0) {
struct radix_tree_node *to_free = root->rnode; struct radix_tree_node *to_free = root->rnode;
struct radix_tree_node *slot; 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); to_free = indirect_to_ptr(to_free);
/* /*
* The candidate node has more than one child, or its child * The candidate node has more than one child, or its child
* is not at the leftmost slot, or it is a multiorder entry, * is not at the leftmost slot, or the child is a multiorder
* we cannot shrink. * entry, we cannot shrink.
*/ */
if (to_free->count != 1) if (to_free->count != 1)
break; break;
slot = to_free->slots[0]; slot = to_free->slots[0];
if (!slot) if (!slot)
break; break;
if (!radix_tree_is_indirect_ptr(slot) && (root->height > 1)) if (!radix_tree_is_indirect_ptr(slot) && to_free->shift)
break; break;
if (radix_tree_is_indirect_ptr(slot)) { if (radix_tree_is_indirect_ptr(slot)) {
...@@ -1454,7 +1433,6 @@ static inline bool radix_tree_shrink(struct radix_tree_root *root) ...@@ -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. * one (root->rnode) as far as dependent read barriers go.
*/ */
root->rnode = slot; root->rnode = slot;
root->height--;
/* /*
* We have a dilemma here. The node's slot[0] must not be * 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, ...@@ -1515,7 +1493,6 @@ bool __radix_tree_delete_node(struct radix_tree_root *root,
parent->count--; parent->count--;
} else { } else {
root_tag_clear_all(root); root_tag_clear_all(root);
root->height = 0;
root->rnode = NULL; root->rnode = NULL;
} }
...@@ -1631,26 +1608,6 @@ radix_tree_node_ctor(void *arg) ...@@ -1631,26 +1608,6 @@ radix_tree_node_ctor(void *arg)
INIT_LIST_HEAD(&node->private_list); 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, static int radix_tree_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu) unsigned long action, void *hcpu)
{ {
...@@ -1677,6 +1634,5 @@ void __init radix_tree_init(void) ...@@ -1677,6 +1634,5 @@ void __init radix_tree_init(void)
sizeof(struct radix_tree_node), 0, sizeof(struct radix_tree_node), 0,
SLAB_PANIC | SLAB_RECLAIM_ACCOUNT, SLAB_PANIC | SLAB_RECLAIM_ACCOUNT,
radix_tree_node_ctor); radix_tree_node_ctor);
radix_tree_init_maxindex();
hotcpu_notifier(radix_tree_callback, 0); hotcpu_notifier(radix_tree_callback, 0);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment