diff options
Diffstat (limited to 'lib/radix-tree.c')
| -rw-r--r-- | lib/radix-tree.c | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 92cdd9936e3d..05da38bcc298 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
| 30 | #include <linux/cpu.h> | 30 | #include <linux/cpu.h> |
| 31 | #include <linux/gfp.h> | ||
| 32 | #include <linux/string.h> | 31 | #include <linux/string.h> |
| 33 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
| 34 | #include <linux/rcupdate.h> | 33 | #include <linux/rcupdate.h> |
| @@ -364,7 +363,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, | |||
| 364 | unsigned int height, shift; | 363 | unsigned int height, shift; |
| 365 | struct radix_tree_node *node, **slot; | 364 | struct radix_tree_node *node, **slot; |
| 366 | 365 | ||
| 367 | node = rcu_dereference(root->rnode); | 366 | node = rcu_dereference_raw(root->rnode); |
| 368 | if (node == NULL) | 367 | if (node == NULL) |
| 369 | return NULL; | 368 | return NULL; |
| 370 | 369 | ||
| @@ -384,7 +383,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, | |||
| 384 | do { | 383 | do { |
| 385 | slot = (struct radix_tree_node **) | 384 | slot = (struct radix_tree_node **) |
| 386 | (node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); | 385 | (node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); |
| 387 | node = rcu_dereference(*slot); | 386 | node = rcu_dereference_raw(*slot); |
| 388 | if (node == NULL) | 387 | if (node == NULL) |
| 389 | return NULL; | 388 | return NULL; |
| 390 | 389 | ||
| @@ -556,6 +555,10 @@ EXPORT_SYMBOL(radix_tree_tag_clear); | |||
| 556 | * | 555 | * |
| 557 | * 0: tag not present or not set | 556 | * 0: tag not present or not set |
| 558 | * 1: tag set | 557 | * 1: tag set |
| 558 | * | ||
| 559 | * Note that the return value of this function may not be relied on, even if | ||
| 560 | * the RCU lock is held, unless tag modification and node deletion are excluded | ||
| 561 | * from concurrency. | ||
| 559 | */ | 562 | */ |
| 560 | int radix_tree_tag_get(struct radix_tree_root *root, | 563 | int radix_tree_tag_get(struct radix_tree_root *root, |
| 561 | unsigned long index, unsigned int tag) | 564 | unsigned long index, unsigned int tag) |
| @@ -568,7 +571,7 @@ int radix_tree_tag_get(struct radix_tree_root *root, | |||
| 568 | if (!root_tag_get(root, tag)) | 571 | if (!root_tag_get(root, tag)) |
| 569 | return 0; | 572 | return 0; |
| 570 | 573 | ||
| 571 | node = rcu_dereference(root->rnode); | 574 | node = rcu_dereference_raw(root->rnode); |
| 572 | if (node == NULL) | 575 | if (node == NULL) |
| 573 | return 0; | 576 | return 0; |
| 574 | 577 | ||
| @@ -596,13 +599,9 @@ int radix_tree_tag_get(struct radix_tree_root *root, | |||
| 596 | */ | 599 | */ |
| 597 | if (!tag_get(node, tag, offset)) | 600 | if (!tag_get(node, tag, offset)) |
| 598 | saw_unset_tag = 1; | 601 | saw_unset_tag = 1; |
| 599 | if (height == 1) { | 602 | if (height == 1) |
| 600 | int ret = tag_get(node, tag, offset); | 603 | return !!tag_get(node, tag, offset); |
| 601 | 604 | node = rcu_dereference_raw(node->slots[offset]); | |
| 602 | BUG_ON(ret && saw_unset_tag); | ||
| 603 | return !!ret; | ||
| 604 | } | ||
| 605 | node = rcu_dereference(node->slots[offset]); | ||
| 606 | shift -= RADIX_TREE_MAP_SHIFT; | 605 | shift -= RADIX_TREE_MAP_SHIFT; |
| 607 | height--; | 606 | height--; |
| 608 | } | 607 | } |
| @@ -657,7 +656,7 @@ EXPORT_SYMBOL(radix_tree_next_hole); | |||
| 657 | * | 656 | * |
| 658 | * Returns: the index of the hole if found, otherwise returns an index | 657 | * Returns: the index of the hole if found, otherwise returns an index |
| 659 | * outside of the set specified (in which case 'index - return >= max_scan' | 658 | * outside of the set specified (in which case 'index - return >= max_scan' |
| 660 | * will be true). In rare cases of wrap-around, LONG_MAX will be returned. | 659 | * will be true). In rare cases of wrap-around, ULONG_MAX will be returned. |
| 661 | * | 660 | * |
| 662 | * radix_tree_next_hole may be called under rcu_read_lock. However, like | 661 | * radix_tree_next_hole may be called under rcu_read_lock. However, like |
| 663 | * radix_tree_gang_lookup, this will not atomically search a snapshot of | 662 | * radix_tree_gang_lookup, this will not atomically search a snapshot of |
| @@ -675,7 +674,7 @@ unsigned long radix_tree_prev_hole(struct radix_tree_root *root, | |||
| 675 | if (!radix_tree_lookup(root, index)) | 674 | if (!radix_tree_lookup(root, index)) |
| 676 | break; | 675 | break; |
| 677 | index--; | 676 | index--; |
| 678 | if (index == LONG_MAX) | 677 | if (index == ULONG_MAX) |
| 679 | break; | 678 | break; |
| 680 | } | 679 | } |
| 681 | 680 | ||
| @@ -711,7 +710,7 @@ __lookup(struct radix_tree_node *slot, void ***results, unsigned long index, | |||
| 711 | } | 710 | } |
| 712 | 711 | ||
| 713 | shift -= RADIX_TREE_MAP_SHIFT; | 712 | shift -= RADIX_TREE_MAP_SHIFT; |
| 714 | slot = rcu_dereference(slot->slots[i]); | 713 | slot = rcu_dereference_raw(slot->slots[i]); |
| 715 | if (slot == NULL) | 714 | if (slot == NULL) |
| 716 | goto out; | 715 | goto out; |
| 717 | } | 716 | } |
| @@ -758,7 +757,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, | |||
| 758 | unsigned long cur_index = first_index; | 757 | unsigned long cur_index = first_index; |
| 759 | unsigned int ret; | 758 | unsigned int ret; |
| 760 | 759 | ||
| 761 | node = rcu_dereference(root->rnode); | 760 | node = rcu_dereference_raw(root->rnode); |
| 762 | if (!node) | 761 | if (!node) |
| 763 | return 0; | 762 | return 0; |
| 764 | 763 | ||
| @@ -787,7 +786,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, | |||
| 787 | slot = *(((void ***)results)[ret + i]); | 786 | slot = *(((void ***)results)[ret + i]); |
| 788 | if (!slot) | 787 | if (!slot) |
| 789 | continue; | 788 | continue; |
| 790 | results[ret + nr_found] = rcu_dereference(slot); | 789 | results[ret + nr_found] = rcu_dereference_raw(slot); |
| 791 | nr_found++; | 790 | nr_found++; |
| 792 | } | 791 | } |
| 793 | ret += nr_found; | 792 | ret += nr_found; |
| @@ -826,7 +825,7 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, | |||
| 826 | unsigned long cur_index = first_index; | 825 | unsigned long cur_index = first_index; |
| 827 | unsigned int ret; | 826 | unsigned int ret; |
| 828 | 827 | ||
| 829 | node = rcu_dereference(root->rnode); | 828 | node = rcu_dereference_raw(root->rnode); |
| 830 | if (!node) | 829 | if (!node) |
| 831 | return 0; | 830 | return 0; |
| 832 | 831 | ||
| @@ -915,7 +914,7 @@ __lookup_tag(struct radix_tree_node *slot, void ***results, unsigned long index, | |||
| 915 | } | 914 | } |
| 916 | } | 915 | } |
| 917 | shift -= RADIX_TREE_MAP_SHIFT; | 916 | shift -= RADIX_TREE_MAP_SHIFT; |
| 918 | slot = rcu_dereference(slot->slots[i]); | 917 | slot = rcu_dereference_raw(slot->slots[i]); |
| 919 | if (slot == NULL) | 918 | if (slot == NULL) |
| 920 | break; | 919 | break; |
| 921 | } | 920 | } |
| @@ -951,7 +950,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, | |||
| 951 | if (!root_tag_get(root, tag)) | 950 | if (!root_tag_get(root, tag)) |
| 952 | return 0; | 951 | return 0; |
| 953 | 952 | ||
| 954 | node = rcu_dereference(root->rnode); | 953 | node = rcu_dereference_raw(root->rnode); |
| 955 | if (!node) | 954 | if (!node) |
| 956 | return 0; | 955 | return 0; |
| 957 | 956 | ||
| @@ -980,7 +979,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, | |||
| 980 | slot = *(((void ***)results)[ret + i]); | 979 | slot = *(((void ***)results)[ret + i]); |
| 981 | if (!slot) | 980 | if (!slot) |
| 982 | continue; | 981 | continue; |
| 983 | results[ret + nr_found] = rcu_dereference(slot); | 982 | results[ret + nr_found] = rcu_dereference_raw(slot); |
| 984 | nr_found++; | 983 | nr_found++; |
| 985 | } | 984 | } |
| 986 | ret += nr_found; | 985 | ret += nr_found; |
| @@ -1020,7 +1019,7 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, | |||
| 1020 | if (!root_tag_get(root, tag)) | 1019 | if (!root_tag_get(root, tag)) |
| 1021 | return 0; | 1020 | return 0; |
| 1022 | 1021 | ||
| 1023 | node = rcu_dereference(root->rnode); | 1022 | node = rcu_dereference_raw(root->rnode); |
| 1024 | if (!node) | 1023 | if (!node) |
| 1025 | return 0; | 1024 | return 0; |
| 1026 | 1025 | ||
