diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /include/linux/radix-tree.h | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (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.h | 59 |
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 | |||
41 | static inline void *radix_tree_ptr_to_indirect(void *ptr) | ||
42 | { | ||
43 | return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); | ||
44 | } | ||
45 | 43 | ||
46 | static 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 | ||
51 | static inline int radix_tree_is_indirect_ptr(void *ptr) | 47 | static 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) | |||
61 | struct radix_tree_root { | 57 | struct 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 | */ |
144 | static inline void *radix_tree_deref_slot(void **pslot) | 143 | static 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 | */ | ||
158 | static 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 | */ | ||
171 | static 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 |