aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/radix-tree.h
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /include/linux/radix-tree.h
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'include/linux/radix-tree.h')
-rw-r--r--include/linux/radix-tree.h59
1 files changed, 42 insertions, 17 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 634b8e674ac5..23241c2fecce 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -34,19 +34,15 @@
34 * needed for RCU lookups (because root->height is unreliable). The only 34 * needed for RCU lookups (because root->height is unreliable). The only
35 * time callers need worry about this is when doing a lookup_slot under 35 * time callers need worry about this is when doing a lookup_slot under
36 * RCU. 36 * RCU.
37 *
38 * Indirect pointer in fact is also used to tag the last pointer of a node
39 * when it is shrunk, before we rcu free the node. See shrink code for
40 * details.
37 */ 41 */
38#define RADIX_TREE_INDIRECT_PTR 1 42#define RADIX_TREE_INDIRECT_PTR 1
39#define RADIX_TREE_RETRY ((void *)-1UL)
40
41static inline void *radix_tree_ptr_to_indirect(void *ptr)
42{
43 return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR);
44}
45 43
46static inline void *radix_tree_indirect_to_ptr(void *ptr) 44#define radix_tree_indirect_to_ptr(ptr) \
47{ 45 radix_tree_indirect_to_ptr((void __force *)(ptr))
48 return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
49}
50 46
51static inline int radix_tree_is_indirect_ptr(void *ptr) 47static inline int radix_tree_is_indirect_ptr(void *ptr)
52{ 48{
@@ -61,7 +57,7 @@ static inline int radix_tree_is_indirect_ptr(void *ptr)
61struct radix_tree_root { 57struct radix_tree_root {
62 unsigned int height; 58 unsigned int height;
63 gfp_t gfp_mask; 59 gfp_t gfp_mask;
64 struct radix_tree_node *rnode; 60 struct radix_tree_node __rcu *rnode;
65}; 61};
66 62
67#define RADIX_TREE_INIT(mask) { \ 63#define RADIX_TREE_INIT(mask) { \
@@ -138,16 +134,45 @@ do { \
138 * removed. 134 * removed.
139 * 135 *
140 * For use with radix_tree_lookup_slot(). Caller must hold tree at least read 136 * 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 137 * 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. 138 * held (ie. items cannot be concurrently inserted).
139 *
140 * radix_tree_deref_retry must be used to confirm validity of the pointer if
141 * only the read lock is held.
143 */ 142 */
144static inline void *radix_tree_deref_slot(void **pslot) 143static inline void *radix_tree_deref_slot(void **pslot)
145{ 144{
146 void *ret = rcu_dereference(*pslot); 145 return rcu_dereference(*pslot);
147 if (unlikely(radix_tree_is_indirect_ptr(ret)))
148 ret = RADIX_TREE_RETRY;
149 return ret;
150} 146}
147
148/**
149 * radix_tree_deref_slot_protected - dereference a slot without RCU lock but with tree lock held
150 * @pslot: pointer to slot, returned by radix_tree_lookup_slot
151 * Returns: item that was stored in that slot with any direct pointer flag
152 * removed.
153 *
154 * Similar to radix_tree_deref_slot but only used during migration when a pages
155 * mapping is being moved. The caller does not hold the RCU read lock but it
156 * must hold the tree lock to prevent parallel updates.
157 */
158static inline void *radix_tree_deref_slot_protected(void **pslot,
159 spinlock_t *treelock)
160{
161 return rcu_dereference_protected(*pslot, lockdep_is_held(treelock));
162}
163
164/**
165 * radix_tree_deref_retry - check radix_tree_deref_slot
166 * @arg: pointer returned by radix_tree_deref_slot
167 * Returns: 0 if retry is not required, otherwise retry is required
168 *
169 * radix_tree_deref_retry must be used with radix_tree_deref_slot.
170 */
171static inline int radix_tree_deref_retry(void *arg)
172{
173 return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR);
174}
175
151/** 176/**
152 * radix_tree_replace_slot - replace item in a slot 177 * radix_tree_replace_slot - replace item in a slot
153 * @pslot: pointer to slot, returned by radix_tree_lookup_slot 178 * @pslot: pointer to slot, returned by radix_tree_lookup_slot