Commit 72c6a9870f901045f2464c3dc6ee8914bfdc07aa
Committed by
Ingo Molnar
1 parent
6fd9b3a40b
rculist.h: introduce list_entry_rcu() and list_first_entry_rcu()
I've run into the situation where I need to use list_first_entry with rcu-guarded list. This patch introduces this. Also simplify list_for_each_entry_rcu() to use new list_entry_rcu() instead of list_entry(). Signed-off-by: Jiri Pirko <jpirko@redhat.com> Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: dipankar@in.ibm.com LKML-Reference: <20090414153356.GC3999@psychotron.englab.brq.redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Showing 1 changed file with 28 additions and 2 deletions Side-by-side Diff
include/linux/rculist.h
... | ... | @@ -198,6 +198,32 @@ |
198 | 198 | at->prev = last; |
199 | 199 | } |
200 | 200 | |
201 | +/** | |
202 | + * list_entry_rcu - get the struct for this entry | |
203 | + * @ptr: the &struct list_head pointer. | |
204 | + * @type: the type of the struct this is embedded in. | |
205 | + * @member: the name of the list_struct within the struct. | |
206 | + * | |
207 | + * This primitive may safely run concurrently with the _rcu list-mutation | |
208 | + * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). | |
209 | + */ | |
210 | +#define list_entry_rcu(ptr, type, member) \ | |
211 | + container_of(rcu_dereference(ptr), type, member) | |
212 | + | |
213 | +/** | |
214 | + * list_first_entry_rcu - get the first element from a list | |
215 | + * @ptr: the list head to take the element from. | |
216 | + * @type: the type of the struct this is embedded in. | |
217 | + * @member: the name of the list_struct within the struct. | |
218 | + * | |
219 | + * Note, that list is expected to be not empty. | |
220 | + * | |
221 | + * This primitive may safely run concurrently with the _rcu list-mutation | |
222 | + * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). | |
223 | + */ | |
224 | +#define list_first_entry_rcu(ptr, type, member) \ | |
225 | + list_entry_rcu((ptr)->next, type, member) | |
226 | + | |
201 | 227 | #define __list_for_each_rcu(pos, head) \ |
202 | 228 | for (pos = rcu_dereference((head)->next); \ |
203 | 229 | pos != (head); \ |
204 | 230 | |
... | ... | @@ -214,9 +240,9 @@ |
214 | 240 | * as long as the traversal is guarded by rcu_read_lock(). |
215 | 241 | */ |
216 | 242 | #define list_for_each_entry_rcu(pos, head, member) \ |
217 | - for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \ | |
243 | + for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \ | |
218 | 244 | prefetch(pos->member.next), &pos->member != (head); \ |
219 | - pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member)) | |
245 | + pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) | |
220 | 246 | |
221 | 247 | |
222 | 248 | /** |