diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-10-07 03:43:11 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-10-07 03:43:11 -0400 |
commit | d4f8f217b8a5d5bd02af979650418dca4caec472 (patch) | |
tree | af047bfa9729c975e24cb7624107574e884d3a57 /lib | |
parent | 2dfbf4dfbe47a484bae20456c12b40763b9b6af7 (diff) | |
parent | 773e3f93577ffb493fb7c39b1a6ecf39b5748e87 (diff) |
Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu into core/rcu
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kobject_uevent.c | 4 | ||||
-rw-r--r-- | lib/radix-tree.c | 63 | ||||
-rw-r--r-- | lib/raid6/.gitignore | 4 |
3 files changed, 54 insertions, 17 deletions
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index b93579504dfa..70af0a7f97c0 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -123,7 +123,7 @@ static int kobj_usermode_filter(struct kobject *kobj) | |||
123 | * @kobj: struct kobject that the action is happening to | 123 | * @kobj: struct kobject that the action is happening to |
124 | * @envp_ext: pointer to environmental data | 124 | * @envp_ext: pointer to environmental data |
125 | * | 125 | * |
126 | * Returns 0 if kobject_uevent() is completed with success or the | 126 | * Returns 0 if kobject_uevent_env() is completed with success or the |
127 | * corresponding error when it fails. | 127 | * corresponding error when it fails. |
128 | */ | 128 | */ |
129 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | 129 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, |
@@ -317,7 +317,7 @@ exit: | |||
317 | EXPORT_SYMBOL_GPL(kobject_uevent_env); | 317 | EXPORT_SYMBOL_GPL(kobject_uevent_env); |
318 | 318 | ||
319 | /** | 319 | /** |
320 | * kobject_uevent - notify userspace by ending an uevent | 320 | * kobject_uevent - notify userspace by sending an uevent |
321 | * | 321 | * |
322 | * @action: action that is happening | 322 | * @action: action that is happening |
323 | * @kobj: struct kobject that the action is happening to | 323 | * @kobj: struct kobject that the action is happening to |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 0ccbcdf75000..6f412ab4c24f 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -174,14 +174,16 @@ static void radix_tree_node_rcu_free(struct rcu_head *head) | |||
174 | { | 174 | { |
175 | struct radix_tree_node *node = | 175 | struct radix_tree_node *node = |
176 | container_of(head, struct radix_tree_node, rcu_head); | 176 | container_of(head, struct radix_tree_node, rcu_head); |
177 | int i; | ||
177 | 178 | ||
178 | /* | 179 | /* |
179 | * must only free zeroed nodes into the slab. radix_tree_shrink | 180 | * must only free zeroed nodes into the slab. radix_tree_shrink |
180 | * can leave us with a non-NULL entry in the first slot, so clear | 181 | * can leave us with a non-NULL entry in the first slot, so clear |
181 | * that here to make sure. | 182 | * that here to make sure. |
182 | */ | 183 | */ |
183 | tag_clear(node, 0, 0); | 184 | for (i = 0; i < RADIX_TREE_MAX_TAGS; i++) |
184 | tag_clear(node, 1, 0); | 185 | tag_clear(node, i, 0); |
186 | |||
185 | node->slots[0] = NULL; | 187 | node->slots[0] = NULL; |
186 | node->count = 0; | 188 | node->count = 0; |
187 | 189 | ||
@@ -623,6 +625,13 @@ EXPORT_SYMBOL(radix_tree_tag_get); | |||
623 | * also settag. The function stops either after tagging nr_to_tag items or | 625 | * also settag. The function stops either after tagging nr_to_tag items or |
624 | * after reaching last_index. | 626 | * after reaching last_index. |
625 | * | 627 | * |
628 | * The tags must be set from the leaf level only and propagated back up the | ||
629 | * path to the root. We must do this so that we resolve the full path before | ||
630 | * setting any tags on intermediate nodes. If we set tags as we descend, then | ||
631 | * we can get to the leaf node and find that the index that has the iftag | ||
632 | * set is outside the range we are scanning. This reults in dangling tags and | ||
633 | * can lead to problems with later tag operations (e.g. livelocks on lookups). | ||
634 | * | ||
626 | * The function returns number of leaves where the tag was set and sets | 635 | * The function returns number of leaves where the tag was set and sets |
627 | * *first_indexp to the first unscanned index. | 636 | * *first_indexp to the first unscanned index. |
628 | * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must | 637 | * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must |
@@ -633,9 +642,13 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
633 | unsigned long nr_to_tag, | 642 | unsigned long nr_to_tag, |
634 | unsigned int iftag, unsigned int settag) | 643 | unsigned int iftag, unsigned int settag) |
635 | { | 644 | { |
636 | unsigned int height = root->height, shift; | 645 | unsigned int height = root->height; |
637 | unsigned long tagged = 0, index = *first_indexp; | 646 | struct radix_tree_path path[height]; |
638 | struct radix_tree_node *open_slots[height], *slot; | 647 | struct radix_tree_path *pathp = path; |
648 | struct radix_tree_node *slot; | ||
649 | unsigned int shift; | ||
650 | unsigned long tagged = 0; | ||
651 | unsigned long index = *first_indexp; | ||
639 | 652 | ||
640 | last_index = min(last_index, radix_tree_maxindex(height)); | 653 | last_index = min(last_index, radix_tree_maxindex(height)); |
641 | if (index > last_index) | 654 | if (index > last_index) |
@@ -655,6 +668,13 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
655 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 668 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; |
656 | slot = radix_tree_indirect_to_ptr(root->rnode); | 669 | slot = radix_tree_indirect_to_ptr(root->rnode); |
657 | 670 | ||
671 | /* | ||
672 | * we fill the path from (root->height - 2) to 0, leaving the index at | ||
673 | * (root->height - 1) as a terminator. Zero the node in the terminator | ||
674 | * so that we can use this to end walk loops back up the path. | ||
675 | */ | ||
676 | path[height - 1].node = NULL; | ||
677 | |||
658 | for (;;) { | 678 | for (;;) { |
659 | int offset; | 679 | int offset; |
660 | 680 | ||
@@ -663,17 +683,30 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
663 | goto next; | 683 | goto next; |
664 | if (!tag_get(slot, iftag, offset)) | 684 | if (!tag_get(slot, iftag, offset)) |
665 | goto next; | 685 | goto next; |
686 | if (height > 1) { | ||
687 | /* Go down one level */ | ||
688 | height--; | ||
689 | shift -= RADIX_TREE_MAP_SHIFT; | ||
690 | path[height - 1].node = slot; | ||
691 | path[height - 1].offset = offset; | ||
692 | slot = slot->slots[offset]; | ||
693 | continue; | ||
694 | } | ||
695 | |||
696 | /* tag the leaf */ | ||
697 | tagged++; | ||
666 | tag_set(slot, settag, offset); | 698 | tag_set(slot, settag, offset); |
667 | if (height == 1) { | 699 | |
668 | tagged++; | 700 | /* walk back up the path tagging interior nodes */ |
669 | goto next; | 701 | pathp = &path[0]; |
702 | while (pathp->node) { | ||
703 | /* stop if we find a node with the tag already set */ | ||
704 | if (tag_get(pathp->node, settag, pathp->offset)) | ||
705 | break; | ||
706 | tag_set(pathp->node, settag, pathp->offset); | ||
707 | pathp++; | ||
670 | } | 708 | } |
671 | /* Go down one level */ | 709 | |
672 | height--; | ||
673 | shift -= RADIX_TREE_MAP_SHIFT; | ||
674 | open_slots[height] = slot; | ||
675 | slot = slot->slots[offset]; | ||
676 | continue; | ||
677 | next: | 710 | next: |
678 | /* Go to next item at level determined by 'shift' */ | 711 | /* Go to next item at level determined by 'shift' */ |
679 | index = ((index >> shift) + 1) << shift; | 712 | index = ((index >> shift) + 1) << shift; |
@@ -688,7 +721,7 @@ next: | |||
688 | * last_index is guaranteed to be in the tree, what | 721 | * last_index is guaranteed to be in the tree, what |
689 | * we do below cannot wander astray. | 722 | * we do below cannot wander astray. |
690 | */ | 723 | */ |
691 | slot = open_slots[height]; | 724 | slot = path[height - 1].node; |
692 | height++; | 725 | height++; |
693 | shift += RADIX_TREE_MAP_SHIFT; | 726 | shift += RADIX_TREE_MAP_SHIFT; |
694 | } | 727 | } |
diff --git a/lib/raid6/.gitignore b/lib/raid6/.gitignore new file mode 100644 index 000000000000..162becacf97c --- /dev/null +++ b/lib/raid6/.gitignore | |||
@@ -0,0 +1,4 @@ | |||
1 | mktables | ||
2 | altivec*.c | ||
3 | int*.c | ||
4 | tables.c | ||