From: Lee Schermerhorn radix_tree_deref_slot() was actually dereferencing the pointer in the assignment to the local variable 'slot' and then rcu_dereference()ing the results of an expression [return value of an inline function]. Because we must hold the tree locked across lookup_slot() and _deref_slot(), we don't need the rcu_dereference() at all. Added comments specifying required locking for _lookup_slot() and _deref_slot(). Signed-off-by: Lee Schermerhorn Cc: Nick Piggin Signed-off-by: Andrew Morton --- include/linux/radix-tree.h | 9 +++++++-- lib/radix-tree.c | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff -puN include/linux/radix-tree.h~radix-tree-cleanup-radix_tree_deref_slot-and include/linux/radix-tree.h --- a/include/linux/radix-tree.h~radix-tree-cleanup-radix_tree_deref_slot-and +++ a/include/linux/radix-tree.h @@ -122,12 +122,17 @@ do { \ /** * radix_tree_deref_slot - dereference a slot * @pslot: pointer to slot, returned by radix_tree_lookup_slot - * @returns: item that was stored in that slot. + * @returns: item that was stored in that slot with any direct pointer flag + * removed. + * + * For use with radix_tree_lookup_slot(). Caller must hold tree at least read + * locked across slot lookup and dereference. More likely, will be used with + * radix_tree_replace_slot(), as well, so caller will hold tree write locked. */ static inline void *radix_tree_deref_slot(void *pslot) { void *slot = *(void **)pslot; - return rcu_dereference(radix_tree_direct_to_ptr(slot)); + return radix_tree_direct_to_ptr(slot); } /** * radix_tree_replace_slot - replace item in a slot diff -puN lib/radix-tree.c~radix-tree-cleanup-radix_tree_deref_slot-and lib/radix-tree.c --- a/lib/radix-tree.c~radix-tree-cleanup-radix_tree_deref_slot-and +++ a/lib/radix-tree.c @@ -335,7 +335,10 @@ EXPORT_SYMBOL(radix_tree_insert); * @root. This is useful for update-if-exists operations. * * This function cannot be called under rcu_read_lock, it must be - * excluded from writers, as must the returned slot. + * excluded from writers, as must the returned slot for subsequent + * use by radix_tree_deref_slot() and radix_tree_replace slot. + * Caller must hold tree write locked across slot lookup and + * replace. */ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) { _