diff options
| -rw-r--r-- | arch/x86/kernel/pci-calgary_64.c | 4 | ||||
| -rw-r--r-- | arch/x86/mm/pat_rbtree.c | 34 | ||||
| -rw-r--r-- | include/linux/rbtree.h | 13 | ||||
| -rw-r--r-- | lib/rbtree.c | 116 |
4 files changed, 88 insertions, 79 deletions
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 0b96b5589f08..078d4ec1a9d9 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
| @@ -110,7 +110,7 @@ int use_calgary __read_mostly = 0; | |||
| 110 | * x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 | 110 | * x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 |
| 111 | * x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 | 111 | * x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 |
| 112 | */ | 112 | */ |
| 113 | #define MAX_PHB_BUS_NUM 384 | 113 | #define MAX_PHB_BUS_NUM 256 |
| 114 | 114 | ||
| 115 | #define PHBS_PER_CALGARY 4 | 115 | #define PHBS_PER_CALGARY 4 |
| 116 | 116 | ||
| @@ -1056,8 +1056,6 @@ static int __init calgary_init_one(struct pci_dev *dev) | |||
| 1056 | struct iommu_table *tbl; | 1056 | struct iommu_table *tbl; |
| 1057 | int ret; | 1057 | int ret; |
| 1058 | 1058 | ||
| 1059 | BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); | ||
| 1060 | |||
| 1061 | bbar = busno_to_bbar(dev->bus->number); | 1059 | bbar = busno_to_bbar(dev->bus->number); |
| 1062 | ret = calgary_setup_tar(dev, bbar); | 1060 | ret = calgary_setup_tar(dev, bbar); |
| 1063 | if (ret) | 1061 | if (ret) |
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index f20eeec85a86..8acaddd0fb21 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c | |||
| @@ -34,8 +34,7 @@ | |||
| 34 | * memtype_lock protects the rbtree. | 34 | * memtype_lock protects the rbtree. |
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | static void memtype_rb_augment_cb(struct rb_node *node); | 37 | static struct rb_root memtype_rbroot = RB_ROOT; |
| 38 | static struct rb_root memtype_rbroot = RB_AUGMENT_ROOT(&memtype_rb_augment_cb); | ||
| 39 | 38 | ||
| 40 | static int is_node_overlap(struct memtype *node, u64 start, u64 end) | 39 | static int is_node_overlap(struct memtype *node, u64 start, u64 end) |
| 41 | { | 40 | { |
| @@ -56,7 +55,7 @@ static u64 get_subtree_max_end(struct rb_node *node) | |||
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | /* Update 'subtree_max_end' for a node, based on node and its children */ | 57 | /* Update 'subtree_max_end' for a node, based on node and its children */ |
| 59 | static void update_node_max_end(struct rb_node *node) | 58 | static void memtype_rb_augment_cb(struct rb_node *node, void *__unused) |
| 60 | { | 59 | { |
| 61 | struct memtype *data; | 60 | struct memtype *data; |
| 62 | u64 max_end, child_max_end; | 61 | u64 max_end, child_max_end; |
| @@ -78,25 +77,6 @@ static void update_node_max_end(struct rb_node *node) | |||
| 78 | data->subtree_max_end = max_end; | 77 | data->subtree_max_end = max_end; |
| 79 | } | 78 | } |
| 80 | 79 | ||
| 81 | /* Update 'subtree_max_end' for a node and all its ancestors */ | ||
| 82 | static void update_path_max_end(struct rb_node *node) | ||
| 83 | { | ||
| 84 | u64 old_max_end, new_max_end; | ||
| 85 | |||
| 86 | while (node) { | ||
| 87 | struct memtype *data = container_of(node, struct memtype, rb); | ||
| 88 | |||
| 89 | old_max_end = data->subtree_max_end; | ||
| 90 | update_node_max_end(node); | ||
| 91 | new_max_end = data->subtree_max_end; | ||
| 92 | |||
| 93 | if (new_max_end == old_max_end) | ||
| 94 | break; | ||
| 95 | |||
| 96 | node = rb_parent(node); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | /* Find the first (lowest start addr) overlapping range from rb tree */ | 80 | /* Find the first (lowest start addr) overlapping range from rb tree */ |
| 101 | static struct memtype *memtype_rb_lowest_match(struct rb_root *root, | 81 | static struct memtype *memtype_rb_lowest_match(struct rb_root *root, |
| 102 | u64 start, u64 end) | 82 | u64 start, u64 end) |
| @@ -190,12 +170,6 @@ failure: | |||
| 190 | return -EBUSY; | 170 | return -EBUSY; |
| 191 | } | 171 | } |
| 192 | 172 | ||
| 193 | static void memtype_rb_augment_cb(struct rb_node *node) | ||
| 194 | { | ||
| 195 | if (node) | ||
| 196 | update_path_max_end(node); | ||
| 197 | } | ||
| 198 | |||
| 199 | static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) | 173 | static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) |
| 200 | { | 174 | { |
| 201 | struct rb_node **node = &(root->rb_node); | 175 | struct rb_node **node = &(root->rb_node); |
| @@ -213,6 +187,7 @@ static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) | |||
| 213 | 187 | ||
| 214 | rb_link_node(&newdata->rb, parent, node); | 188 | rb_link_node(&newdata->rb, parent, node); |
| 215 | rb_insert_color(&newdata->rb, root); | 189 | rb_insert_color(&newdata->rb, root); |
| 190 | rb_augment_insert(&newdata->rb, memtype_rb_augment_cb, NULL); | ||
| 216 | } | 191 | } |
| 217 | 192 | ||
| 218 | int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | 193 | int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) |
| @@ -234,13 +209,16 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | |||
| 234 | 209 | ||
| 235 | struct memtype *rbt_memtype_erase(u64 start, u64 end) | 210 | struct memtype *rbt_memtype_erase(u64 start, u64 end) |
| 236 | { | 211 | { |
| 212 | struct rb_node *deepest; | ||
| 237 | struct memtype *data; | 213 | struct memtype *data; |
| 238 | 214 | ||
| 239 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); | 215 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); |
| 240 | if (!data) | 216 | if (!data) |
| 241 | goto out; | 217 | goto out; |
| 242 | 218 | ||
| 219 | deepest = rb_augment_erase_begin(&data->rb); | ||
| 243 | rb_erase(&data->rb, &memtype_rbroot); | 220 | rb_erase(&data->rb, &memtype_rbroot); |
| 221 | rb_augment_erase_end(deepest, memtype_rb_augment_cb, NULL); | ||
| 244 | out: | 222 | out: |
| 245 | return data; | 223 | return data; |
| 246 | } | 224 | } |
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index fe1872e5b37e..7066acb2c530 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h | |||
| @@ -110,7 +110,6 @@ struct rb_node | |||
| 110 | struct rb_root | 110 | struct rb_root |
| 111 | { | 111 | { |
| 112 | struct rb_node *rb_node; | 112 | struct rb_node *rb_node; |
| 113 | void (*augment_cb)(struct rb_node *node); | ||
| 114 | }; | 113 | }; |
| 115 | 114 | ||
| 116 | 115 | ||
| @@ -130,9 +129,7 @@ static inline void rb_set_color(struct rb_node *rb, int color) | |||
| 130 | rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; | 129 | rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; |
| 131 | } | 130 | } |
| 132 | 131 | ||
| 133 | #define RB_ROOT (struct rb_root) { NULL, NULL, } | 132 | #define RB_ROOT (struct rb_root) { NULL, } |
| 134 | #define RB_AUGMENT_ROOT(x) (struct rb_root) { NULL, x} | ||
| 135 | |||
| 136 | #define rb_entry(ptr, type, member) container_of(ptr, type, member) | 133 | #define rb_entry(ptr, type, member) container_of(ptr, type, member) |
| 137 | 134 | ||
| 138 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) | 135 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) |
| @@ -142,6 +139,14 @@ static inline void rb_set_color(struct rb_node *rb, int color) | |||
| 142 | extern void rb_insert_color(struct rb_node *, struct rb_root *); | 139 | extern void rb_insert_color(struct rb_node *, struct rb_root *); |
| 143 | extern void rb_erase(struct rb_node *, struct rb_root *); | 140 | extern void rb_erase(struct rb_node *, struct rb_root *); |
| 144 | 141 | ||
| 142 | typedef void (*rb_augment_f)(struct rb_node *node, void *data); | ||
| 143 | |||
| 144 | extern void rb_augment_insert(struct rb_node *node, | ||
| 145 | rb_augment_f func, void *data); | ||
| 146 | extern struct rb_node *rb_augment_erase_begin(struct rb_node *node); | ||
| 147 | extern void rb_augment_erase_end(struct rb_node *node, | ||
| 148 | rb_augment_f func, void *data); | ||
| 149 | |||
| 145 | /* Find logical next and previous nodes in a tree */ | 150 | /* Find logical next and previous nodes in a tree */ |
| 146 | extern struct rb_node *rb_next(const struct rb_node *); | 151 | extern struct rb_node *rb_next(const struct rb_node *); |
| 147 | extern struct rb_node *rb_prev(const struct rb_node *); | 152 | extern struct rb_node *rb_prev(const struct rb_node *); |
diff --git a/lib/rbtree.c b/lib/rbtree.c index 15e10b1afdd2..4693f79195d3 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
| @@ -44,11 +44,6 @@ static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) | |||
| 44 | else | 44 | else |
| 45 | root->rb_node = right; | 45 | root->rb_node = right; |
| 46 | rb_set_parent(node, right); | 46 | rb_set_parent(node, right); |
| 47 | |||
| 48 | if (root->augment_cb) { | ||
| 49 | root->augment_cb(node); | ||
| 50 | root->augment_cb(right); | ||
| 51 | } | ||
| 52 | } | 47 | } |
| 53 | 48 | ||
| 54 | static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) | 49 | static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) |
| @@ -72,20 +67,12 @@ static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) | |||
| 72 | else | 67 | else |
| 73 | root->rb_node = left; | 68 | root->rb_node = left; |
| 74 | rb_set_parent(node, left); | 69 | rb_set_parent(node, left); |
| 75 | |||
| 76 | if (root->augment_cb) { | ||
| 77 | root->augment_cb(node); | ||
| 78 | root->augment_cb(left); | ||
| 79 | } | ||
| 80 | } | 70 | } |
| 81 | 71 | ||
| 82 | void rb_insert_color(struct rb_node *node, struct rb_root *root) | 72 | void rb_insert_color(struct rb_node *node, struct rb_root *root) |
| 83 | { | 73 | { |
| 84 | struct rb_node *parent, *gparent; | 74 | struct rb_node *parent, *gparent; |
| 85 | 75 | ||
| 86 | if (root->augment_cb) | ||
| 87 | root->augment_cb(node); | ||
| 88 | |||
| 89 | while ((parent = rb_parent(node)) && rb_is_red(parent)) | 76 | while ((parent = rb_parent(node)) && rb_is_red(parent)) |
| 90 | { | 77 | { |
| 91 | gparent = rb_parent(parent); | 78 | gparent = rb_parent(parent); |
| @@ -240,15 +227,12 @@ void rb_erase(struct rb_node *node, struct rb_root *root) | |||
| 240 | else | 227 | else |
| 241 | { | 228 | { |
| 242 | struct rb_node *old = node, *left; | 229 | struct rb_node *old = node, *left; |
| 243 | int old_parent_cb = 0; | ||
| 244 | int successor_parent_cb = 0; | ||
| 245 | 230 | ||
| 246 | node = node->rb_right; | 231 | node = node->rb_right; |
| 247 | while ((left = node->rb_left) != NULL) | 232 | while ((left = node->rb_left) != NULL) |
| 248 | node = left; | 233 | node = left; |
| 249 | 234 | ||
| 250 | if (rb_parent(old)) { | 235 | if (rb_parent(old)) { |
| 251 | old_parent_cb = 1; | ||
| 252 | if (rb_parent(old)->rb_left == old) | 236 | if (rb_parent(old)->rb_left == old) |
| 253 | rb_parent(old)->rb_left = node; | 237 | rb_parent(old)->rb_left = node; |
| 254 | else | 238 | else |
| @@ -263,10 +247,8 @@ void rb_erase(struct rb_node *node, struct rb_root *root) | |||
| 263 | if (parent == old) { | 247 | if (parent == old) { |
| 264 | parent = node; | 248 | parent = node; |
| 265 | } else { | 249 | } else { |
| 266 | successor_parent_cb = 1; | ||
| 267 | if (child) | 250 | if (child) |
| 268 | rb_set_parent(child, parent); | 251 | rb_set_parent(child, parent); |
| 269 | |||
| 270 | parent->rb_left = child; | 252 | parent->rb_left = child; |
| 271 | 253 | ||
| 272 | node->rb_right = old->rb_right; | 254 | node->rb_right = old->rb_right; |
| @@ -277,24 +259,6 @@ void rb_erase(struct rb_node *node, struct rb_root *root) | |||
| 277 | node->rb_left = old->rb_left; | 259 | node->rb_left = old->rb_left; |
| 278 | rb_set_parent(old->rb_left, node); | 260 | rb_set_parent(old->rb_left, node); |
| 279 | 261 | ||
| 280 | if (root->augment_cb) { | ||
| 281 | /* | ||
| 282 | * Here, three different nodes can have new children. | ||
| 283 | * The parent of the successor node that was selected | ||
| 284 | * to replace the node to be erased. | ||
| 285 | * The node that is getting erased and is now replaced | ||
| 286 | * by its successor. | ||
| 287 | * The parent of the node getting erased-replaced. | ||
| 288 | */ | ||
| 289 | if (successor_parent_cb) | ||
| 290 | root->augment_cb(parent); | ||
| 291 | |||
| 292 | root->augment_cb(node); | ||
| 293 | |||
| 294 | if (old_parent_cb) | ||
| 295 | root->augment_cb(rb_parent(old)); | ||
| 296 | } | ||
| 297 | |||
| 298 | goto color; | 262 | goto color; |
| 299 | } | 263 | } |
| 300 | 264 | ||
| @@ -303,19 +267,15 @@ void rb_erase(struct rb_node *node, struct rb_root *root) | |||
| 303 | 267 | ||
| 304 | if (child) | 268 | if (child) |
| 305 | rb_set_parent(child, parent); | 269 | rb_set_parent(child, parent); |
| 306 | 270 | if (parent) | |
| 307 | if (parent) { | 271 | { |
| 308 | if (parent->rb_left == node) | 272 | if (parent->rb_left == node) |
| 309 | parent->rb_left = child; | 273 | parent->rb_left = child; |
| 310 | else | 274 | else |
| 311 | parent->rb_right = child; | 275 | parent->rb_right = child; |
| 312 | |||
| 313 | if (root->augment_cb) | ||
| 314 | root->augment_cb(parent); | ||
| 315 | |||
| 316 | } else { | ||
| 317 | root->rb_node = child; | ||
| 318 | } | 276 | } |
| 277 | else | ||
| 278 | root->rb_node = child; | ||
| 319 | 279 | ||
| 320 | color: | 280 | color: |
| 321 | if (color == RB_BLACK) | 281 | if (color == RB_BLACK) |
| @@ -323,6 +283,74 @@ void rb_erase(struct rb_node *node, struct rb_root *root) | |||
| 323 | } | 283 | } |
| 324 | EXPORT_SYMBOL(rb_erase); | 284 | EXPORT_SYMBOL(rb_erase); |
| 325 | 285 | ||
| 286 | static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data) | ||
| 287 | { | ||
| 288 | struct rb_node *parent; | ||
| 289 | |||
| 290 | up: | ||
| 291 | func(node, data); | ||
| 292 | parent = rb_parent(node); | ||
| 293 | if (!parent) | ||
| 294 | return; | ||
| 295 | |||
| 296 | if (node == parent->rb_left && parent->rb_right) | ||
| 297 | func(parent->rb_right, data); | ||
| 298 | else if (parent->rb_left) | ||
| 299 | func(parent->rb_left, data); | ||
| 300 | |||
| 301 | node = parent; | ||
| 302 | goto up; | ||
| 303 | } | ||
| 304 | |||
| 305 | /* | ||
| 306 | * after inserting @node into the tree, update the tree to account for | ||
| 307 | * both the new entry and any damage done by rebalance | ||
| 308 | */ | ||
| 309 | void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data) | ||
| 310 | { | ||
| 311 | if (node->rb_left) | ||
| 312 | node = node->rb_left; | ||
| 313 | else if (node->rb_right) | ||
| 314 | node = node->rb_right; | ||
| 315 | |||
| 316 | rb_augment_path(node, func, data); | ||
| 317 | } | ||
| 318 | |||
| 319 | /* | ||
| 320 | * before removing the node, find the deepest node on the rebalance path | ||
| 321 | * that will still be there after @node gets removed | ||
| 322 | */ | ||
| 323 | struct rb_node *rb_augment_erase_begin(struct rb_node *node) | ||
| 324 | { | ||
| 325 | struct rb_node *deepest; | ||
| 326 | |||
| 327 | if (!node->rb_right && !node->rb_left) | ||
| 328 | deepest = rb_parent(node); | ||
| 329 | else if (!node->rb_right) | ||
| 330 | deepest = node->rb_left; | ||
| 331 | else if (!node->rb_left) | ||
| 332 | deepest = node->rb_right; | ||
| 333 | else { | ||
| 334 | deepest = rb_next(node); | ||
| 335 | if (deepest->rb_right) | ||
| 336 | deepest = deepest->rb_right; | ||
| 337 | else if (rb_parent(deepest) != node) | ||
| 338 | deepest = rb_parent(deepest); | ||
| 339 | } | ||
| 340 | |||
| 341 | return deepest; | ||
| 342 | } | ||
| 343 | |||
| 344 | /* | ||
| 345 | * after removal, update the tree to account for the removed entry | ||
| 346 | * and any rebalance damage. | ||
| 347 | */ | ||
| 348 | void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data) | ||
| 349 | { | ||
| 350 | if (node) | ||
| 351 | rb_augment_path(node, func, data); | ||
| 352 | } | ||
| 353 | |||
| 326 | /* | 354 | /* |
| 327 | * This function returns the first node (in sort order) of the tree. | 355 | * This function returns the first node (in sort order) of the tree. |
| 328 | */ | 356 | */ |
