aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2013-01-11 17:32:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-01-11 17:54:56 -0500
commit3cb7a56344ca45ee56d71c5f8fe9f922306bff1f (patch)
treeda6fd5aa462e9e7c117063740c15fd95241c72d3 /lib
parenta8906b0b673a8a64ae1446a7847def62388f6e46 (diff)
lib/rbtree.c: avoid the use of non-static __always_inline
lib/rbtree.c declared __rb_erase_color() as __always_inline void, and then exported it with EXPORT_SYMBOL. This was because __rb_erase_color() must be exported for augmented rbtree users, but it must also be inlined into rb_erase() so that the dummy callback can get optimized out of that call site. (Actually with a modern compiler, none of the dummy callback functions should even be generated as separate text functions). The above usage is legal C, but it was unusual enough for some compilers to warn about it. This change makes things more explicit, with a static __always_inline ____rb_erase_color function for use in rb_erase(), and a separate non-inline __rb_erase_color function for use in rb_erase_augmented call sites. Signed-off-by: Michel Lespinasse <walken@google.com> Reported-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/rbtree.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/rbtree.c b/lib/rbtree.c
index 4f56a11d67fa..c0e31fe2fabf 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -194,8 +194,12 @@ __rb_insert(struct rb_node *node, struct rb_root *root,
194 } 194 }
195} 195}
196 196
197__always_inline void 197/*
198__rb_erase_color(struct rb_node *parent, struct rb_root *root, 198 * Inline version for rb_erase() use - we want to be able to inline
199 * and eliminate the dummy_rotate callback there
200 */
201static __always_inline void
202____rb_erase_color(struct rb_node *parent, struct rb_root *root,
199 void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 203 void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
200{ 204{
201 struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; 205 struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
@@ -355,6 +359,13 @@ __rb_erase_color(struct rb_node *parent, struct rb_root *root,
355 } 359 }
356 } 360 }
357} 361}
362
363/* Non-inline version for rb_erase_augmented() use */
364void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
365 void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
366{
367 ____rb_erase_color(parent, root, augment_rotate);
368}
358EXPORT_SYMBOL(__rb_erase_color); 369EXPORT_SYMBOL(__rb_erase_color);
359 370
360/* 371/*
@@ -380,7 +391,10 @@ EXPORT_SYMBOL(rb_insert_color);
380 391
381void rb_erase(struct rb_node *node, struct rb_root *root) 392void rb_erase(struct rb_node *node, struct rb_root *root)
382{ 393{
383 rb_erase_augmented(node, root, &dummy_callbacks); 394 struct rb_node *rebalance;
395 rebalance = __rb_erase_augmented(node, root, &dummy_callbacks);
396 if (rebalance)
397 ____rb_erase_color(rebalance, root, dummy_rotate);
384} 398}
385EXPORT_SYMBOL(rb_erase); 399EXPORT_SYMBOL(rb_erase);
386 400