Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

radix-tree: rewrite __radix_tree_lookup

Use the new multi-order support functions to rewrite __radix_tree_lookup()

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Reviewed-by: Ross 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Matthew Wilcox and committed by
Linus Torvalds
85829954 afe0e395

+16 -32
+16 -32
lib/radix-tree.c
··· 634 634 struct radix_tree_node **nodep, void ***slotp) 635 635 { 636 636 struct radix_tree_node *node, *parent; 637 - unsigned int height, shift; 637 + unsigned long maxindex; 638 + unsigned int shift; 638 639 void **slot; 639 640 640 - node = rcu_dereference_raw(root->rnode); 641 - if (node == NULL) 641 + restart: 642 + parent = NULL; 643 + slot = (void **)&root->rnode; 644 + shift = radix_tree_load_root(root, &node, &maxindex); 645 + if (index > maxindex) 642 646 return NULL; 643 647 644 - if (!radix_tree_is_indirect_ptr(node)) { 645 - if (index > 0) 646 - return NULL; 648 + while (radix_tree_is_indirect_ptr(node)) { 649 + unsigned offset; 647 650 648 - if (nodep) 649 - *nodep = NULL; 650 - if (slotp) 651 - *slotp = (void **)&root->rnode; 652 - return node; 653 - } 654 - node = indirect_to_ptr(node); 655 - 656 - height = node->path & RADIX_TREE_HEIGHT_MASK; 657 - if (index > radix_tree_maxindex(height)) 658 - return NULL; 659 - 660 - shift = (height-1) * RADIX_TREE_MAP_SHIFT; 661 - 662 - do { 663 - parent = node; 664 - slot = node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK); 665 - node = rcu_dereference_raw(*slot); 666 - if (node == NULL) 667 - return NULL; 668 - if (!radix_tree_is_indirect_ptr(node)) 669 - break; 670 - node = indirect_to_ptr(node); 671 - 651 + if (node == RADIX_TREE_RETRY) 652 + goto restart; 653 + parent = indirect_to_ptr(node); 672 654 shift -= RADIX_TREE_MAP_SHIFT; 673 - height--; 674 - } while (height > 0); 655 + offset = (index >> shift) & RADIX_TREE_MAP_MASK; 656 + offset = radix_tree_descend(parent, &node, offset); 657 + slot = parent->slots + offset; 658 + } 675 659 676 660 if (nodep) 677 661 *nodep = parent;