[PATCH] Introduce rb_replace_node_rcu()

Peter Zijlstra peterz at infradead.org
Fri Jul 1 00:22:38 PDT 2016


On Fri, Jul 01, 2016 at 08:08:07AM +0100, David Howells wrote:

> Should I also reorder rb_replace_node() whilst
> I'm at it so that the new node is initialised first (it shouldn't make a
> difference, I know)?

Might as well, I can't imagine that making a performance difference and
keeping the general structure of things similar helps avoid confusion.

> commit 812667d2a82a6a8fe35a44e951e8b1515b04696a
> Author: David Howells <dhowells at redhat.com>
> Date:   Fri Jul 1 07:53:51 2016 +0100
> 
>     Introduce rb_replace_node_rcu()
>     
>     Implement an RCU-safe variant of rb_replace_node().
>     
>     Signed-off-by: David Howells <dhowells at redhat.com>
>     cc: Peter Zijlstra <peterz at infradead.org>

One little niggle below, but:

Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>


> diff --git a/lib/rbtree.c b/lib/rbtree.c
> index 1356454e36de..59eb906c6c3b 100644
> --- a/lib/rbtree.c
> +++ b/lib/rbtree.c
> @@ -551,6 +551,25 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new,
>  }
>  EXPORT_SYMBOL(rb_replace_node);
>  
> +void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new,
> +			 struct rb_root *root)
> +{
> +	struct rb_node *parent = rb_parent(victim);
> +
> +	/* Copy the pointers/colour from the victim to the replacement */
> +	*new = *victim;
> +
> +	/* Set the surrounding nodes to point to the replacement */
> +	if (victim->rb_left)
> +		rb_set_parent(victim->rb_left, new);
> +	if (victim->rb_right)
> +		rb_set_parent(victim->rb_right, new);
> +
> +	/* Set the onward pointer last with an RCU barrier */

Maybe also explain _why_ this needs to be last. Its obvious now and to
us, but it might safe some head scratching later.

> +	__rb_change_child_rcu(victim, new, parent, root);
> +}
> +EXPORT_SYMBOL(rb_replace_node_rcu);



More information about the linux-afs mailing list