Skip to content

Commit 3cb7a56

Browse files
walken-googletorvalds
authored andcommitted
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 <[email protected]> Reported-by: Wu Fengguang <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent a8906b0 commit 3cb7a56

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

include/linux/rbtree_augmented.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ __rb_change_child(struct rb_node *old, struct rb_node *new,
123123
extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
124124
void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
125125

126-
static __always_inline void
127-
rb_erase_augmented(struct rb_node *node, struct rb_root *root,
128-
const struct rb_augment_callbacks *augment)
126+
static __always_inline struct rb_node *
127+
__rb_erase_augmented(struct rb_node *node, struct rb_root *root,
128+
const struct rb_augment_callbacks *augment)
129129
{
130130
struct rb_node *child = node->rb_right, *tmp = node->rb_left;
131131
struct rb_node *parent, *rebalance;
@@ -217,6 +217,14 @@ rb_erase_augmented(struct rb_node *node, struct rb_root *root,
217217
}
218218

219219
augment->propagate(tmp, NULL);
220+
return rebalance;
221+
}
222+
223+
static __always_inline void
224+
rb_erase_augmented(struct rb_node *node, struct rb_root *root,
225+
const struct rb_augment_callbacks *augment)
226+
{
227+
struct rb_node *rebalance = __rb_erase_augmented(node, root, augment);
220228
if (rebalance)
221229
__rb_erase_color(rebalance, root, augment->rotate);
222230
}

lib/rbtree.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,12 @@ __rb_insert(struct rb_node *node, struct rb_root *root,
194194
}
195195
}
196196

197-
__always_inline void
198-
__rb_erase_color(struct rb_node *parent, struct rb_root *root,
197+
/*
198+
* Inline version for rb_erase() use - we want to be able to inline
199+
* and eliminate the dummy_rotate callback there
200+
*/
201+
static __always_inline void
202+
____rb_erase_color(struct rb_node *parent, struct rb_root *root,
199203
void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
200204
{
201205
struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
@@ -355,6 +359,13 @@ __rb_erase_color(struct rb_node *parent, struct rb_root *root,
355359
}
356360
}
357361
}
362+
363+
/* Non-inline version for rb_erase_augmented() use */
364+
void __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+
}
358369
EXPORT_SYMBOL(__rb_erase_color);
359370

360371
/*
@@ -380,7 +391,10 @@ EXPORT_SYMBOL(rb_insert_color);
380391

381392
void rb_erase(struct rb_node *node, struct rb_root *root)
382393
{
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);
384398
}
385399
EXPORT_SYMBOL(rb_erase);
386400

0 commit comments

Comments
 (0)