diff options
author | Michel Lespinasse <walken@google.com> | 2012-10-08 19:31:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:22:38 -0400 |
commit | 9d9e6f9703bbd642f3f2f807e6aaa642a4cbcec9 (patch) | |
tree | 6d0061d6c1369bb006da753cc2cea55df60efe0f | |
parent | 14b94af0b251a2c80885b60538166fb7d04a642e (diff) |
rbtree: remove prior augmented rbtree implementation
convert arch/x86/mm/pat_rbtree.c to the proposed augmented rbtree api
and remove the old augmented rbtree implementation.
Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/x86/mm/pat_rbtree.c | 65 | ||||
-rw-r--r-- | include/linux/rbtree.h | 8 | ||||
-rw-r--r-- | lib/rbtree.c | 71 |
3 files changed, 46 insertions, 98 deletions
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index 8acaddd0fb21..7e1515bd4770 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c | |||
@@ -54,29 +54,57 @@ static u64 get_subtree_max_end(struct rb_node *node) | |||
54 | return ret; | 54 | return ret; |
55 | } | 55 | } |
56 | 56 | ||
57 | /* Update 'subtree_max_end' for a node, based on node and its children */ | 57 | static u64 compute_subtree_max_end(struct memtype *data) |
58 | static void memtype_rb_augment_cb(struct rb_node *node, void *__unused) | ||
59 | { | 58 | { |
60 | struct memtype *data; | 59 | u64 max_end = data->end, child_max_end; |
61 | u64 max_end, child_max_end; | ||
62 | |||
63 | if (!node) | ||
64 | return; | ||
65 | |||
66 | data = container_of(node, struct memtype, rb); | ||
67 | max_end = data->end; | ||
68 | 60 | ||
69 | child_max_end = get_subtree_max_end(node->rb_right); | 61 | child_max_end = get_subtree_max_end(data->rb.rb_right); |
70 | if (child_max_end > max_end) | 62 | if (child_max_end > max_end) |
71 | max_end = child_max_end; | 63 | max_end = child_max_end; |
72 | 64 | ||
73 | child_max_end = get_subtree_max_end(node->rb_left); | 65 | child_max_end = get_subtree_max_end(data->rb.rb_left); |
74 | if (child_max_end > max_end) | 66 | if (child_max_end > max_end) |
75 | max_end = child_max_end; | 67 | max_end = child_max_end; |
76 | 68 | ||
77 | data->subtree_max_end = max_end; | 69 | return max_end; |
70 | } | ||
71 | |||
72 | /* Update 'subtree_max_end' for node and its parents */ | ||
73 | static void memtype_rb_propagate_cb(struct rb_node *node, struct rb_node *stop) | ||
74 | { | ||
75 | while (node != stop) { | ||
76 | struct memtype *data = container_of(node, struct memtype, rb); | ||
77 | u64 subtree_max_end = compute_subtree_max_end(data); | ||
78 | if (data->subtree_max_end == subtree_max_end) | ||
79 | break; | ||
80 | data->subtree_max_end = subtree_max_end; | ||
81 | node = rb_parent(&data->rb); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | static void memtype_rb_copy_cb(struct rb_node *old, struct rb_node *new) | ||
86 | { | ||
87 | struct memtype *old_data = container_of(old, struct memtype, rb); | ||
88 | struct memtype *new_data = container_of(new, struct memtype, rb); | ||
89 | |||
90 | new_data->subtree_max_end = old_data->subtree_max_end; | ||
78 | } | 91 | } |
79 | 92 | ||
93 | /* Update 'subtree_max_end' after tree rotation. old and new are the | ||
94 | * former and current subtree roots */ | ||
95 | static void memtype_rb_rotate_cb(struct rb_node *old, struct rb_node *new) | ||
96 | { | ||
97 | struct memtype *old_data = container_of(old, struct memtype, rb); | ||
98 | struct memtype *new_data = container_of(new, struct memtype, rb); | ||
99 | |||
100 | new_data->subtree_max_end = old_data->subtree_max_end; | ||
101 | old_data->subtree_max_end = compute_subtree_max_end(old_data); | ||
102 | } | ||
103 | |||
104 | static const struct rb_augment_callbacks memtype_rb_augment_cb = { | ||
105 | memtype_rb_propagate_cb, memtype_rb_copy_cb, memtype_rb_rotate_cb | ||
106 | }; | ||
107 | |||
80 | /* Find the first (lowest start addr) overlapping range from rb tree */ | 108 | /* Find the first (lowest start addr) overlapping range from rb tree */ |
81 | static struct memtype *memtype_rb_lowest_match(struct rb_root *root, | 109 | static struct memtype *memtype_rb_lowest_match(struct rb_root *root, |
82 | u64 start, u64 end) | 110 | u64 start, u64 end) |
@@ -179,15 +207,17 @@ static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) | |||
179 | struct memtype *data = container_of(*node, struct memtype, rb); | 207 | struct memtype *data = container_of(*node, struct memtype, rb); |
180 | 208 | ||
181 | parent = *node; | 209 | parent = *node; |
210 | if (data->subtree_max_end < newdata->end) | ||
211 | data->subtree_max_end = newdata->end; | ||
182 | if (newdata->start <= data->start) | 212 | if (newdata->start <= data->start) |
183 | node = &((*node)->rb_left); | 213 | node = &((*node)->rb_left); |
184 | else if (newdata->start > data->start) | 214 | else if (newdata->start > data->start) |
185 | node = &((*node)->rb_right); | 215 | node = &((*node)->rb_right); |
186 | } | 216 | } |
187 | 217 | ||
218 | newdata->subtree_max_end = newdata->end; | ||
188 | rb_link_node(&newdata->rb, parent, node); | 219 | rb_link_node(&newdata->rb, parent, node); |
189 | rb_insert_color(&newdata->rb, root); | 220 | rb_insert_augmented(&newdata->rb, root, &memtype_rb_augment_cb); |
190 | rb_augment_insert(&newdata->rb, memtype_rb_augment_cb, NULL); | ||
191 | } | 221 | } |
192 | 222 | ||
193 | int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | 223 | int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) |
@@ -209,16 +239,13 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | |||
209 | 239 | ||
210 | struct memtype *rbt_memtype_erase(u64 start, u64 end) | 240 | struct memtype *rbt_memtype_erase(u64 start, u64 end) |
211 | { | 241 | { |
212 | struct rb_node *deepest; | ||
213 | struct memtype *data; | 242 | struct memtype *data; |
214 | 243 | ||
215 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); | 244 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); |
216 | if (!data) | 245 | if (!data) |
217 | goto out; | 246 | goto out; |
218 | 247 | ||
219 | deepest = rb_augment_erase_begin(&data->rb); | 248 | rb_erase_augmented(&data->rb, &memtype_rbroot, &memtype_rb_augment_cb); |
220 | rb_erase(&data->rb, &memtype_rbroot); | ||
221 | rb_augment_erase_end(deepest, memtype_rb_augment_cb, NULL); | ||
222 | out: | 249 | out: |
223 | return data; | 250 | return data; |
224 | } | 251 | } |
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index c902eb9d6506..4ace31b33380 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h | |||
@@ -80,14 +80,6 @@ rb_insert_augmented(struct rb_node *node, struct rb_root *root, | |||
80 | } | 80 | } |
81 | 81 | ||
82 | 82 | ||
83 | typedef void (*rb_augment_f)(struct rb_node *node, void *data); | ||
84 | |||
85 | extern void rb_augment_insert(struct rb_node *node, | ||
86 | rb_augment_f func, void *data); | ||
87 | extern struct rb_node *rb_augment_erase_begin(struct rb_node *node); | ||
88 | extern void rb_augment_erase_end(struct rb_node *node, | ||
89 | rb_augment_f func, void *data); | ||
90 | |||
91 | /* Find logical next and previous nodes in a tree */ | 83 | /* Find logical next and previous nodes in a tree */ |
92 | extern struct rb_node *rb_next(const struct rb_node *); | 84 | extern struct rb_node *rb_next(const struct rb_node *); |
93 | extern struct rb_node *rb_prev(const struct rb_node *); | 85 | extern struct rb_node *rb_prev(const struct rb_node *); |
diff --git a/lib/rbtree.c b/lib/rbtree.c index a37ee7954b8f..c0088ca345f9 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
@@ -538,77 +538,6 @@ void rb_erase_augmented(struct rb_node *node, struct rb_root *root, | |||
538 | } | 538 | } |
539 | EXPORT_SYMBOL(rb_erase_augmented); | 539 | EXPORT_SYMBOL(rb_erase_augmented); |
540 | 540 | ||
541 | static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data) | ||
542 | { | ||
543 | struct rb_node *parent; | ||
544 | |||
545 | up: | ||
546 | func(node, data); | ||
547 | parent = rb_parent(node); | ||
548 | if (!parent) | ||
549 | return; | ||
550 | |||
551 | if (node == parent->rb_left && parent->rb_right) | ||
552 | func(parent->rb_right, data); | ||
553 | else if (parent->rb_left) | ||
554 | func(parent->rb_left, data); | ||
555 | |||
556 | node = parent; | ||
557 | goto up; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * after inserting @node into the tree, update the tree to account for | ||
562 | * both the new entry and any damage done by rebalance | ||
563 | */ | ||
564 | void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data) | ||
565 | { | ||
566 | if (node->rb_left) | ||
567 | node = node->rb_left; | ||
568 | else if (node->rb_right) | ||
569 | node = node->rb_right; | ||
570 | |||
571 | rb_augment_path(node, func, data); | ||
572 | } | ||
573 | EXPORT_SYMBOL(rb_augment_insert); | ||
574 | |||
575 | /* | ||
576 | * before removing the node, find the deepest node on the rebalance path | ||
577 | * that will still be there after @node gets removed | ||
578 | */ | ||
579 | struct rb_node *rb_augment_erase_begin(struct rb_node *node) | ||
580 | { | ||
581 | struct rb_node *deepest; | ||
582 | |||
583 | if (!node->rb_right && !node->rb_left) | ||
584 | deepest = rb_parent(node); | ||
585 | else if (!node->rb_right) | ||
586 | deepest = node->rb_left; | ||
587 | else if (!node->rb_left) | ||
588 | deepest = node->rb_right; | ||
589 | else { | ||
590 | deepest = rb_next(node); | ||
591 | if (deepest->rb_right) | ||
592 | deepest = deepest->rb_right; | ||
593 | else if (rb_parent(deepest) != node) | ||
594 | deepest = rb_parent(deepest); | ||
595 | } | ||
596 | |||
597 | return deepest; | ||
598 | } | ||
599 | EXPORT_SYMBOL(rb_augment_erase_begin); | ||
600 | |||
601 | /* | ||
602 | * after removal, update the tree to account for the removed entry | ||
603 | * and any rebalance damage. | ||
604 | */ | ||
605 | void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data) | ||
606 | { | ||
607 | if (node) | ||
608 | rb_augment_path(node, func, data); | ||
609 | } | ||
610 | EXPORT_SYMBOL(rb_augment_erase_end); | ||
611 | |||
612 | /* | 541 | /* |
613 | * This function returns the first node (in sort order) of the tree. | 542 | * This function returns the first node (in sort order) of the tree. |
614 | */ | 543 | */ |