* [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h [not found] <cover.1733850317.git.beckerlee3@gmail.com> @ 2024-12-12 16:46 ` Roger L. Beckermeyer III 2024-12-13 7:21 ` Qu Wenruo 2024-12-13 9:06 ` Peter Zijlstra 0 siblings, 2 replies; 7+ messages in thread From: Roger L. Beckermeyer III @ 2024-12-12 16:46 UTC (permalink / raw) To: dsterba, peterz, oleg, mhiramat, linux-kernel Cc: beckerlee3, josef, linux-btrfs, lkp Adds rb_find_add_cached() as a helper function for use with red-black trees. Used in btrfs to reduce boilerplate code. Suggested-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com> --- include/linux/rbtree.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index 7c173aa64e1e..0d4444c0cfb3 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -210,6 +210,43 @@ rb_add(struct rb_node *node, struct rb_root *tree, rb_insert_color(node, tree); } +/** + * rb_find_add_cached() - find equivalent @node in @tree, or add @node + * @node: node to look-for / insert + * @tree: tree to search / modify + * @cmp: operator defining the node order + * + * Returns the rb_node matching @node, or NULL when no match is found and @node + * is inserted. + */ +static __always_inline struct rb_node * +rb_find_add_cached(struct rb_node *node, struct rb_root_cached *tree, + int (*cmp)(struct rb_node *, const struct rb_node *)) +{ + bool leftmost = true; + struct rb_node **link = &tree->rb_root.rb_node; + struct rb_node *parent = NULL; + int c; + + while (*link) { + parent = *link; + c = cmp(node, parent); + + if (c < 0) { + link = &parent->rb_left; + } else if (c > 0) { + link = &parent->rb_right; + leftmost = false; + } else { + return parent; + } + } + + rb_link_node(node, parent, link); + rb_insert_color_cached(node, tree, leftmost); + return NULL; +} + /** * rb_find_add() - find equivalent @node in @tree, or add @node * @node: node to look-for / insert -- 2.45.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h 2024-12-12 16:46 ` [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h Roger L. Beckermeyer III @ 2024-12-13 7:21 ` Qu Wenruo 2024-12-13 9:05 ` Peter Zijlstra 2024-12-13 9:06 ` Peter Zijlstra 1 sibling, 1 reply; 7+ messages in thread From: Qu Wenruo @ 2024-12-13 7:21 UTC (permalink / raw) To: Roger L. Beckermeyer III, dsterba, peterz, oleg, mhiramat, linux-kernel Cc: josef, linux-btrfs, lkp 在 2024/12/13 03:16, Roger L. Beckermeyer III 写道: > Adds rb_find_add_cached() as a helper function for use with > red-black trees. Used in btrfs to reduce boilerplate code. I won't call it boilerplate code though, it's just to utilize the cached rb tree feature as an optimization. And since rbtree is a tree-wide infrastructure, you need to be more persuasive to add a new interface. Yes, btrfs is utilizing this cached rb tree, but since you're adding a new tree-wide interface, it will be much better to find another driver/subsystem that can benefit from the new interface. > > Suggested-by: Josef Bacik <josef@toxicpanda.com> > Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com> > --- > include/linux/rbtree.h | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h > index 7c173aa64e1e..0d4444c0cfb3 100644 > --- a/include/linux/rbtree.h > +++ b/include/linux/rbtree.h > @@ -210,6 +210,43 @@ rb_add(struct rb_node *node, struct rb_root *tree, > rb_insert_color(node, tree); > } > > +/** > + * rb_find_add_cached() - find equivalent @node in @tree, or add @node > + * @node: node to look-for / insert > + * @tree: tree to search / modify > + * @cmp: operator defining the node order > + * > + * Returns the rb_node matching @node, or NULL when no match is found and @node > + * is inserted. > + */ > +static __always_inline struct rb_node * > +rb_find_add_cached(struct rb_node *node, struct rb_root_cached *tree, > + int (*cmp)(struct rb_node *, const struct rb_node *)) This function is almost the same as rb_add_cached(), the only difference is the extra handling for the cmp function returning 0. So I'm wondering if it's possible to enhance rb_add_cached(), or even refactor it so there can be a shared core function and rb_add_cached() and rb_find_add_cached() can reuse the same function. Thanks, Qu > +{ > + bool leftmost = true; > + struct rb_node **link = &tree->rb_root.rb_node; > + struct rb_node *parent = NULL; > + int c; > + > + while (*link) { > + parent = *link; > + c = cmp(node, parent); > + > + if (c < 0) { > + link = &parent->rb_left; > + } else if (c > 0) { > + link = &parent->rb_right; > + leftmost = false; > + } else { > + return parent; > + } > + } > + > + rb_link_node(node, parent, link); > + rb_insert_color_cached(node, tree, leftmost); > + return NULL; > +} > + > /** > * rb_find_add() - find equivalent @node in @tree, or add @node > * @node: node to look-for / insert ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h 2024-12-13 7:21 ` Qu Wenruo @ 2024-12-13 9:05 ` Peter Zijlstra 0 siblings, 0 replies; 7+ messages in thread From: Peter Zijlstra @ 2024-12-13 9:05 UTC (permalink / raw) To: Qu Wenruo Cc: Roger L. Beckermeyer III, dsterba, oleg, mhiramat, linux-kernel, josef, linux-btrfs, lkp On Fri, Dec 13, 2024 at 05:51:44PM +1030, Qu Wenruo wrote: > > > 在 2024/12/13 03:16, Roger L. Beckermeyer III 写道: > > Adds rb_find_add_cached() as a helper function for use with > > red-black trees. Used in btrfs to reduce boilerplate code. > > I won't call it boilerplate code though, it's just to utilize the cached > rb tree feature as an optimization. Nah, all this is boilerplate :-) > > > > Suggested-by: Josef Bacik <josef@toxicpanda.com> > > Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com> > > --- > > include/linux/rbtree.h | 37 +++++++++++++++++++++++++++++++++++++ > > 1 file changed, 37 insertions(+) > > > > diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h > > index 7c173aa64e1e..0d4444c0cfb3 100644 > > --- a/include/linux/rbtree.h > > +++ b/include/linux/rbtree.h > > @@ -210,6 +210,43 @@ rb_add(struct rb_node *node, struct rb_root *tree, > > rb_insert_color(node, tree); > > } > > > > +/** > > + * rb_find_add_cached() - find equivalent @node in @tree, or add @node > > + * @node: node to look-for / insert > > + * @tree: tree to search / modify > > + * @cmp: operator defining the node order > > + * > > + * Returns the rb_node matching @node, or NULL when no match is found and @node > > + * is inserted. > > + */ > > +static __always_inline struct rb_node * > > +rb_find_add_cached(struct rb_node *node, struct rb_root_cached *tree, > > + int (*cmp)(struct rb_node *, const struct rb_node *)) > > This function is almost the same as rb_add_cached(), the only difference > is the extra handling for the cmp function returning 0. > > So I'm wondering if it's possible to enhance rb_add_cached(), or even > refactor it so there can be a shared core function and rb_add_cached() > and rb_find_add_cached() can reuse the same function. Nope, rb_add_cached() can add multiple entries with the same key, rb_find_add() cannot. Also, note that all these things are effectively 'templates', they generate code at the call site. The cmp() function as required for find_add() is a tri-state return and generates more logic than the binary less() required for add(). ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h 2024-12-12 16:46 ` [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h Roger L. Beckermeyer III 2024-12-13 7:21 ` Qu Wenruo @ 2024-12-13 9:06 ` Peter Zijlstra 2024-12-16 22:13 ` Qu Wenruo 1 sibling, 1 reply; 7+ messages in thread From: Peter Zijlstra @ 2024-12-13 9:06 UTC (permalink / raw) To: Roger L. Beckermeyer III Cc: dsterba, oleg, mhiramat, linux-kernel, josef, linux-btrfs, lkp On Thu, Dec 12, 2024 at 10:46:18AM -0600, Roger L. Beckermeyer III wrote: > Adds rb_find_add_cached() as a helper function for use with > red-black trees. Used in btrfs to reduce boilerplate code. > > Suggested-by: Josef Bacik <josef@toxicpanda.com> > Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> > --- > include/linux/rbtree.h | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h > index 7c173aa64e1e..0d4444c0cfb3 100644 > --- a/include/linux/rbtree.h > +++ b/include/linux/rbtree.h > @@ -210,6 +210,43 @@ rb_add(struct rb_node *node, struct rb_root *tree, > rb_insert_color(node, tree); > } > > +/** > + * rb_find_add_cached() - find equivalent @node in @tree, or add @node > + * @node: node to look-for / insert > + * @tree: tree to search / modify > + * @cmp: operator defining the node order > + * > + * Returns the rb_node matching @node, or NULL when no match is found and @node > + * is inserted. > + */ > +static __always_inline struct rb_node * > +rb_find_add_cached(struct rb_node *node, struct rb_root_cached *tree, > + int (*cmp)(struct rb_node *, const struct rb_node *)) > +{ > + bool leftmost = true; > + struct rb_node **link = &tree->rb_root.rb_node; > + struct rb_node *parent = NULL; > + int c; > + > + while (*link) { > + parent = *link; > + c = cmp(node, parent); > + > + if (c < 0) { > + link = &parent->rb_left; > + } else if (c > 0) { > + link = &parent->rb_right; > + leftmost = false; > + } else { > + return parent; > + } > + } > + > + rb_link_node(node, parent, link); > + rb_insert_color_cached(node, tree, leftmost); > + return NULL; > +} > + > /** > * rb_find_add() - find equivalent @node in @tree, or add @node > * @node: node to look-for / insert > -- > 2.45.2 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h 2024-12-13 9:06 ` Peter Zijlstra @ 2024-12-16 22:13 ` Qu Wenruo 2024-12-16 22:22 ` Peter Zijlstra 0 siblings, 1 reply; 7+ messages in thread From: Qu Wenruo @ 2024-12-16 22:13 UTC (permalink / raw) To: Peter Zijlstra, Roger L. Beckermeyer III Cc: dsterba, oleg, mhiramat, linux-kernel, josef, linux-btrfs, lkp 在 2024/12/13 19:36, Peter Zijlstra 写道: > On Thu, Dec 12, 2024 at 10:46:18AM -0600, Roger L. Beckermeyer III wrote: >> Adds rb_find_add_cached() as a helper function for use with >> red-black trees. Used in btrfs to reduce boilerplate code. >> >> Suggested-by: Josef Bacik <josef@toxicpanda.com> >> Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com> > > Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> I guess it's fine to merge this change through btrfs tree? Just curious about the existing cmp() and less() functions, as they only accept the exist node as const. I'm wondering if this is intentional to allow the less/cmp() functions to modify the new node if needed. As I normally assume such cmp()/less() should never touch any node nor its entries. Thanks, Qu > >> --- >> include/linux/rbtree.h | 37 +++++++++++++++++++++++++++++++++++++ >> 1 file changed, 37 insertions(+) >> >> diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h >> index 7c173aa64e1e..0d4444c0cfb3 100644 >> --- a/include/linux/rbtree.h >> +++ b/include/linux/rbtree.h >> @@ -210,6 +210,43 @@ rb_add(struct rb_node *node, struct rb_root *tree, >> rb_insert_color(node, tree); >> } >> >> +/** >> + * rb_find_add_cached() - find equivalent @node in @tree, or add @node >> + * @node: node to look-for / insert >> + * @tree: tree to search / modify >> + * @cmp: operator defining the node order >> + * >> + * Returns the rb_node matching @node, or NULL when no match is found and @node >> + * is inserted. >> + */ >> +static __always_inline struct rb_node * >> +rb_find_add_cached(struct rb_node *node, struct rb_root_cached *tree, >> + int (*cmp)(struct rb_node *, const struct rb_node *)) >> +{ >> + bool leftmost = true; >> + struct rb_node **link = &tree->rb_root.rb_node; >> + struct rb_node *parent = NULL; >> + int c; >> + >> + while (*link) { >> + parent = *link; >> + c = cmp(node, parent); >> + >> + if (c < 0) { >> + link = &parent->rb_left; >> + } else if (c > 0) { >> + link = &parent->rb_right; >> + leftmost = false; >> + } else { >> + return parent; >> + } >> + } >> + >> + rb_link_node(node, parent, link); >> + rb_insert_color_cached(node, tree, leftmost); >> + return NULL; >> +} >> + >> /** >> * rb_find_add() - find equivalent @node in @tree, or add @node >> * @node: node to look-for / insert >> -- >> 2.45.2 >> > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h 2024-12-16 22:13 ` Qu Wenruo @ 2024-12-16 22:22 ` Peter Zijlstra 2024-12-16 22:40 ` Qu Wenruo 0 siblings, 1 reply; 7+ messages in thread From: Peter Zijlstra @ 2024-12-16 22:22 UTC (permalink / raw) To: Qu Wenruo Cc: Roger L. Beckermeyer III, dsterba, oleg, mhiramat, linux-kernel, josef, linux-btrfs, lkp On Tue, Dec 17, 2024 at 08:43:26AM +1030, Qu Wenruo wrote: > > > 在 2024/12/13 19:36, Peter Zijlstra 写道: > > On Thu, Dec 12, 2024 at 10:46:18AM -0600, Roger L. Beckermeyer III wrote: > > > Adds rb_find_add_cached() as a helper function for use with > > > red-black trees. Used in btrfs to reduce boilerplate code. > > > > > > Suggested-by: Josef Bacik <josef@toxicpanda.com> > > > Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com> > > > > Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> > > I guess it's fine to merge this change through btrfs tree? Yeah, I think so. I don't think there's anything else pending for this file -- its not touched much. > > Just curious about the existing cmp() and less() functions, as they only > accept the exist node as const. > > I'm wondering if this is intentional to allow the less/cmp() functions > to modify the new node if needed. > As I normally assume such cmp()/less() should never touch any node nor > its entries. Oh yeah, they probably should not. I think it's just because the callchain as a whole does not have const on the new node (for obvious raisins), and I failed to put it on for the comparators. You could add it (and fix up the whole tree) and see if anything comes apart. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h 2024-12-16 22:22 ` Peter Zijlstra @ 2024-12-16 22:40 ` Qu Wenruo 0 siblings, 0 replies; 7+ messages in thread From: Qu Wenruo @ 2024-12-16 22:40 UTC (permalink / raw) To: Peter Zijlstra, Qu Wenruo Cc: Roger L. Beckermeyer III, dsterba, oleg, mhiramat, linux-kernel, josef, linux-btrfs, lkp 在 2024/12/17 08:52, Peter Zijlstra 写道: > On Tue, Dec 17, 2024 at 08:43:26AM +1030, Qu Wenruo wrote: >> >> >> 在 2024/12/13 19:36, Peter Zijlstra 写道: >>> On Thu, Dec 12, 2024 at 10:46:18AM -0600, Roger L. Beckermeyer III wrote: >>>> Adds rb_find_add_cached() as a helper function for use with >>>> red-black trees. Used in btrfs to reduce boilerplate code. >>>> >>>> Suggested-by: Josef Bacik <josef@toxicpanda.com> >>>> Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com> >>> >>> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> >> >> I guess it's fine to merge this change through btrfs tree? > > Yeah, I think so. I don't think there's anything else pending for this > file -- its not touched much. > >> >> Just curious about the existing cmp() and less() functions, as they only >> accept the exist node as const. >> >> I'm wondering if this is intentional to allow the less/cmp() functions >> to modify the new node if needed. >> As I normally assume such cmp()/less() should never touch any node nor >> its entries. > > Oh yeah, they probably should not. I think it's just because the > callchain as a whole does not have const on the new node (for obvious > raisins), and I failed to put it on for the comparators. > > You could add it (and fix up the whole tree) and see if anything comes > apart. > Thanks for confirming this. I'll make the cmp() for the new helper to accept all const parameter, and give a try to do a tree-wide cleanup to make existing cmp/less() to accept all const parameters. (pretty sure a lot of things will fall apart though). Thanks, Qu ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-12-16 22:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <cover.1733850317.git.beckerlee3@gmail.com>
2024-12-12 16:46 ` [PATCH 1/6] rbtree: add rb_find_add_cached() to rbtree.h Roger L. Beckermeyer III
2024-12-13 7:21 ` Qu Wenruo
2024-12-13 9:05 ` Peter Zijlstra
2024-12-13 9:06 ` Peter Zijlstra
2024-12-16 22:13 ` Qu Wenruo
2024-12-16 22:22 ` Peter Zijlstra
2024-12-16 22:40 ` Qu Wenruo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox