aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2015-01-02 17:00:16 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-03 14:32:56 -0500
commit88d6ed15acff1cb44b1d1f3c0a393b7f7744957a (patch)
treeee25a48f8ab11d06c062480c89ba1e96c8113e57 /include/linux
parenta4b18cda4c2676a4b4b59622b2e0394dc153e00b (diff)
rhashtable: Convert bucket iterators to take table and index
This patch is in preparation to introduce per bucket spinlocks. It extends all iterator macros to take the bucket table and bucket index. It also introduces a new rht_dereference_bucket() to handle protected accesses to buckets. It introduces a barrier() to the RCU iterators to the prevent the compiler from caching the first element. The lockdep verifier is introduced as stub which always succeeds and properly implement in the next patch when the locks are introduced. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/rhashtable.h173
1 files changed, 116 insertions, 57 deletions
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 1b51221c6bbd..b54e24a08806 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -87,11 +87,18 @@ struct rhashtable {
87 87
88#ifdef CONFIG_PROVE_LOCKING 88#ifdef CONFIG_PROVE_LOCKING
89int lockdep_rht_mutex_is_held(const struct rhashtable *ht); 89int lockdep_rht_mutex_is_held(const struct rhashtable *ht);
90int lockdep_rht_bucket_is_held(const struct bucket_table *tbl, u32 hash);
90#else 91#else
91static inline int lockdep_rht_mutex_is_held(const struct rhashtable *ht) 92static inline int lockdep_rht_mutex_is_held(const struct rhashtable *ht)
92{ 93{
93 return 1; 94 return 1;
94} 95}
96
97static inline int lockdep_rht_bucket_is_held(const struct bucket_table *tbl,
98 u32 hash)
99{
100 return 1;
101}
95#endif /* CONFIG_PROVE_LOCKING */ 102#endif /* CONFIG_PROVE_LOCKING */
96 103
97int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params); 104int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params);
@@ -119,92 +126,144 @@ void rhashtable_destroy(const struct rhashtable *ht);
119#define rht_dereference_rcu(p, ht) \ 126#define rht_dereference_rcu(p, ht) \
120 rcu_dereference_check(p, lockdep_rht_mutex_is_held(ht)) 127 rcu_dereference_check(p, lockdep_rht_mutex_is_held(ht))
121 128
122#define rht_entry(ptr, type, member) container_of(ptr, type, member) 129#define rht_dereference_bucket(p, tbl, hash) \
123#define rht_entry_safe(ptr, type, member) \ 130 rcu_dereference_protected(p, lockdep_rht_bucket_is_held(tbl, hash))
124({ \
125 typeof(ptr) __ptr = (ptr); \
126 __ptr ? rht_entry(__ptr, type, member) : NULL; \
127})
128 131
129#define rht_next_entry_safe(pos, ht, member) \ 132#define rht_dereference_bucket_rcu(p, tbl, hash) \
130({ \ 133 rcu_dereference_check(p, lockdep_rht_bucket_is_held(tbl, hash))
131 pos ? rht_entry_safe(rht_dereference((pos)->member.next, ht), \ 134
132 typeof(*(pos)), member) : NULL; \ 135#define rht_entry(tpos, pos, member) \
133}) 136 ({ tpos = container_of(pos, typeof(*tpos), member); 1; })
134 137
135/** 138/**
136 * rht_for_each - iterate over hash chain 139 * rht_for_each_continue - continue iterating over hash chain
137 * @pos: &struct rhash_head to use as a loop cursor. 140 * @pos: the &struct rhash_head to use as a loop cursor.
138 * @head: head of the hash chain (struct rhash_head *) 141 * @head: the previous &struct rhash_head to continue from
139 * @ht: pointer to your struct rhashtable 142 * @tbl: the &struct bucket_table
143 * @hash: the hash value / bucket index
140 */ 144 */
141#define rht_for_each(pos, head, ht) \ 145#define rht_for_each_continue(pos, head, tbl, hash) \
142 for (pos = rht_dereference(head, ht); \ 146 for (pos = rht_dereference_bucket(head, tbl, hash); \
143 pos; \ 147 pos; \
144 pos = rht_dereference((pos)->next, ht)) 148 pos = rht_dereference_bucket((pos)->next, tbl, hash))
149
150/**
151 * rht_for_each - iterate over hash chain
152 * @pos: the &struct rhash_head to use as a loop cursor.
153 * @tbl: the &struct bucket_table
154 * @hash: the hash value / bucket index
155 */
156#define rht_for_each(pos, tbl, hash) \
157 rht_for_each_continue(pos, (tbl)->buckets[hash], tbl, hash)
158
159/**
160 * rht_for_each_entry_continue - continue iterating over hash chain
161 * @tpos: the type * to use as a loop cursor.
162 * @pos: the &struct rhash_head to use as a loop cursor.
163 * @head: the previous &struct rhash_head to continue from
164 * @tbl: the &struct bucket_table
165 * @hash: the hash value / bucket index
166 * @member: name of the &struct rhash_head within the hashable struct.
167 */
168#define rht_for_each_entry_continue(tpos, pos, head, tbl, hash, member) \
169 for (pos = rht_dereference_bucket(head, tbl, hash); \
170 pos && rht_entry(tpos, pos, member); \
171 pos = rht_dereference_bucket((pos)->next, tbl, hash))
145 172
146/** 173/**
147 * rht_for_each_entry - iterate over hash chain of given type 174 * rht_for_each_entry - iterate over hash chain of given type
148 * @pos: type * to use as a loop cursor. 175 * @tpos: the type * to use as a loop cursor.
149 * @head: head of the hash chain (struct rhash_head *) 176 * @pos: the &struct rhash_head to use as a loop cursor.
150 * @ht: pointer to your struct rhashtable 177 * @tbl: the &struct bucket_table
151 * @member: name of the rhash_head within the hashable struct. 178 * @hash: the hash value / bucket index
179 * @member: name of the &struct rhash_head within the hashable struct.
152 */ 180 */
153#define rht_for_each_entry(pos, head, ht, member) \ 181#define rht_for_each_entry(tpos, pos, tbl, hash, member) \
154 for (pos = rht_entry_safe(rht_dereference(head, ht), \ 182 rht_for_each_entry_continue(tpos, pos, (tbl)->buckets[hash], \
155 typeof(*(pos)), member); \ 183 tbl, hash, member)
156 pos; \
157 pos = rht_next_entry_safe(pos, ht, member))
158 184
159/** 185/**
160 * rht_for_each_entry_safe - safely iterate over hash chain of given type 186 * rht_for_each_entry_safe - safely iterate over hash chain of given type
161 * @pos: type * to use as a loop cursor. 187 * @tpos: the type * to use as a loop cursor.
162 * @n: type * to use for temporary next object storage 188 * @pos: the &struct rhash_head to use as a loop cursor.
163 * @head: head of the hash chain (struct rhash_head *) 189 * @next: the &struct rhash_head to use as next in loop cursor.
164 * @ht: pointer to your struct rhashtable 190 * @tbl: the &struct bucket_table
165 * @member: name of the rhash_head within the hashable struct. 191 * @hash: the hash value / bucket index
192 * @member: name of the &struct rhash_head within the hashable struct.
166 * 193 *
167 * This hash chain list-traversal primitive allows for the looped code to 194 * This hash chain list-traversal primitive allows for the looped code to
168 * remove the loop cursor from the list. 195 * remove the loop cursor from the list.
169 */ 196 */
170#define rht_for_each_entry_safe(pos, n, head, ht, member) \ 197#define rht_for_each_entry_safe(tpos, pos, next, tbl, hash, member) \
171 for (pos = rht_entry_safe(rht_dereference(head, ht), \ 198 for (pos = rht_dereference_bucket((tbl)->buckets[hash], tbl, hash), \
172 typeof(*(pos)), member), \ 199 next = pos ? rht_dereference_bucket(pos->next, tbl, hash) \
173 n = rht_next_entry_safe(pos, ht, member); \ 200 : NULL; \
174 pos; \ 201 pos && rht_entry(tpos, pos, member); \
175 pos = n, \ 202 pos = next)
176 n = rht_next_entry_safe(pos, ht, member)) 203
204/**
205 * rht_for_each_rcu_continue - continue iterating over rcu hash chain
206 * @pos: the &struct rhash_head to use as a loop cursor.
207 * @head: the previous &struct rhash_head to continue from
208 * @tbl: the &struct bucket_table
209 * @hash: the hash value / bucket index
210 *
211 * This hash chain list-traversal primitive may safely run concurrently with
212 * the _rcu mutation primitives such as rhashtable_insert() as long as the
213 * traversal is guarded by rcu_read_lock().
214 */
215#define rht_for_each_rcu_continue(pos, head, tbl, hash) \
216 for (({barrier(); }), \
217 pos = rht_dereference_bucket_rcu(head, tbl, hash); \
218 pos; \
219 pos = rcu_dereference_raw(pos->next))
177 220
178/** 221/**
179 * rht_for_each_rcu - iterate over rcu hash chain 222 * rht_for_each_rcu - iterate over rcu hash chain
180 * @pos: &struct rhash_head to use as a loop cursor. 223 * @pos: the &struct rhash_head to use as a loop cursor.
181 * @head: head of the hash chain (struct rhash_head *) 224 * @tbl: the &struct bucket_table
182 * @ht: pointer to your struct rhashtable 225 * @hash: the hash value / bucket index
183 * 226 *
184 * This hash chain list-traversal primitive may safely run concurrently with 227 * This hash chain list-traversal primitive may safely run concurrently with
185 * the _rcu fkht mutation primitives such as rht_insert() as long as the 228 * the _rcu mutation primitives such as rhashtable_insert() as long as the
186 * traversal is guarded by rcu_read_lock(). 229 * traversal is guarded by rcu_read_lock().
187 */ 230 */
188#define rht_for_each_rcu(pos, head, ht) \ 231#define rht_for_each_rcu(pos, tbl, hash) \
189 for (pos = rht_dereference_rcu(head, ht); \ 232 rht_for_each_rcu_continue(pos, (tbl)->buckets[hash], tbl, hash)
190 pos; \ 233
191 pos = rht_dereference_rcu((pos)->next, ht)) 234/**
235 * rht_for_each_entry_rcu_continue - continue iterating over rcu hash chain
236 * @tpos: the type * to use as a loop cursor.
237 * @pos: the &struct rhash_head to use as a loop cursor.
238 * @head: the previous &struct rhash_head to continue from
239 * @tbl: the &struct bucket_table
240 * @hash: the hash value / bucket index
241 * @member: name of the &struct rhash_head within the hashable struct.
242 *
243 * This hash chain list-traversal primitive may safely run concurrently with
244 * the _rcu mutation primitives such as rhashtable_insert() as long as the
245 * traversal is guarded by rcu_read_lock().
246 */
247#define rht_for_each_entry_rcu_continue(tpos, pos, head, tbl, hash, member) \
248 for (({barrier(); }), \
249 pos = rht_dereference_bucket_rcu(head, tbl, hash); \
250 pos && rht_entry(tpos, pos, member); \
251 pos = rht_dereference_bucket_rcu(pos->next, tbl, hash))
192 252
193/** 253/**
194 * rht_for_each_entry_rcu - iterate over rcu hash chain of given type 254 * rht_for_each_entry_rcu - iterate over rcu hash chain of given type
195 * @pos: type * to use as a loop cursor. 255 * @tpos: the type * to use as a loop cursor.
196 * @head: head of the hash chain (struct rhash_head *) 256 * @pos: the &struct rhash_head to use as a loop cursor.
197 * @member: name of the rhash_head within the hashable struct. 257 * @tbl: the &struct bucket_table
258 * @hash: the hash value / bucket index
259 * @member: name of the &struct rhash_head within the hashable struct.
198 * 260 *
199 * This hash chain list-traversal primitive may safely run concurrently with 261 * This hash chain list-traversal primitive may safely run concurrently with
200 * the _rcu fkht mutation primitives such as rht_insert() as long as the 262 * the _rcu mutation primitives such as rhashtable_insert() as long as the
201 * traversal is guarded by rcu_read_lock(). 263 * traversal is guarded by rcu_read_lock().
202 */ 264 */
203#define rht_for_each_entry_rcu(pos, head, member) \ 265#define rht_for_each_entry_rcu(tpos, pos, tbl, hash, member) \
204 for (pos = rht_entry_safe(rcu_dereference_raw(head), \ 266 rht_for_each_entry_rcu_continue(tpos, pos, (tbl)->buckets[hash],\
205 typeof(*(pos)), member); \ 267 tbl, hash, member)
206 pos; \
207 pos = rht_entry_safe(rcu_dereference_raw((pos)->member.next), \
208 typeof(*(pos)), member))
209 268
210#endif /* _LINUX_RHASHTABLE_H */ 269#endif /* _LINUX_RHASHTABLE_H */