]> git.baikalelectronics.ru Git - kernel.git/commit
rbtree: Make lockless searches non-fatal
authorPeter Zijlstra <peterz@infradead.org>
Wed, 27 May 2015 01:39:36 +0000 (11:09 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Thu, 28 May 2015 02:02:04 +0000 (11:32 +0930)
commitfaee406c2b3006556524f7f6d74002623451658d
treeb3fbbf22c0f1bbc175dce958cf99241aee665f4c
parentc2507e4c32809a06762cb478ee946c3c38f3b9c7
rbtree: Make lockless searches non-fatal

Change the insert and erase code such that lockless searches are
non-fatal.

In and of itself an rbtree cannot be correctly searched while
in-modification, we can however provide weaker guarantees that will
allow the rbtree to be used in conjunction with other techniques, such
as latches; see e62ffe65f7ae ("seqcount: Add raw_write_seqcount_latch()").

For this to work we need the following guarantees from the rbtree
code:

 1) a lockless reader must not see partial stores, this would allow it
    to observe nodes that are invalid memory.

 2) there must not be (temporary) loops in the tree structure in the
    modifier's program order, this would cause a lookup which
    interrupts the modifier to get stuck indefinitely.

For 1) we must use WRITE_ONCE() for all updates to the tree structure;
in particular this patch only does rb_{left,right} as those are the
only element required for simple searches.

It generates slightly worse code, probably because volatile. But in
pointer chasing heavy code a few instructions more should not matter.

For 2) I have carefully audited the code and drawn every intermediate
link state and not found a loop.

Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <David.Woodhouse@intel.com>
Cc: Rik van Riel <riel@redhat.com>
Reviewed-by: Michel Lespinasse <walken@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
include/linux/rbtree.h
include/linux/rbtree_augmented.h
lib/rbtree.c