diff options
Diffstat (limited to 'include/linux/radix-tree.h')
-rw-r--r-- | include/linux/radix-tree.h | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 634b8e674ac5..9f38fe50217e 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -36,17 +36,6 @@ | |||
36 | * RCU. | 36 | * RCU. |
37 | */ | 37 | */ |
38 | #define RADIX_TREE_INDIRECT_PTR 1 | 38 | #define RADIX_TREE_INDIRECT_PTR 1 |
39 | #define RADIX_TREE_RETRY ((void *)-1UL) | ||
40 | |||
41 | static inline void *radix_tree_ptr_to_indirect(void *ptr) | ||
42 | { | ||
43 | return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); | ||
44 | } | ||
45 | |||
46 | static inline void *radix_tree_indirect_to_ptr(void *ptr) | ||
47 | { | ||
48 | return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR); | ||
49 | } | ||
50 | 39 | ||
51 | static inline int radix_tree_is_indirect_ptr(void *ptr) | 40 | static inline int radix_tree_is_indirect_ptr(void *ptr) |
52 | { | 41 | { |
@@ -138,16 +127,29 @@ do { \ | |||
138 | * removed. | 127 | * removed. |
139 | * | 128 | * |
140 | * For use with radix_tree_lookup_slot(). Caller must hold tree at least read | 129 | * For use with radix_tree_lookup_slot(). Caller must hold tree at least read |
141 | * locked across slot lookup and dereference. More likely, will be used with | 130 | * locked across slot lookup and dereference. Not required if write lock is |
142 | * radix_tree_replace_slot(), as well, so caller will hold tree write locked. | 131 | * held (ie. items cannot be concurrently inserted). |
132 | * | ||
133 | * radix_tree_deref_retry must be used to confirm validity of the pointer if | ||
134 | * only the read lock is held. | ||
143 | */ | 135 | */ |
144 | static inline void *radix_tree_deref_slot(void **pslot) | 136 | static inline void *radix_tree_deref_slot(void **pslot) |
145 | { | 137 | { |
146 | void *ret = rcu_dereference(*pslot); | 138 | return rcu_dereference(*pslot); |
147 | if (unlikely(radix_tree_is_indirect_ptr(ret))) | ||
148 | ret = RADIX_TREE_RETRY; | ||
149 | return ret; | ||
150 | } | 139 | } |
140 | |||
141 | /** | ||
142 | * radix_tree_deref_retry - check radix_tree_deref_slot | ||
143 | * @arg: pointer returned by radix_tree_deref_slot | ||
144 | * Returns: 0 if retry is not required, otherwise retry is required | ||
145 | * | ||
146 | * radix_tree_deref_retry must be used with radix_tree_deref_slot. | ||
147 | */ | ||
148 | static inline int radix_tree_deref_retry(void *arg) | ||
149 | { | ||
150 | return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR); | ||
151 | } | ||
152 | |||
151 | /** | 153 | /** |
152 | * radix_tree_replace_slot - replace item in a slot | 154 | * radix_tree_replace_slot - replace item in a slot |
153 | * @pslot: pointer to slot, returned by radix_tree_lookup_slot | 155 | * @pslot: pointer to slot, returned by radix_tree_lookup_slot |