diff options
author | Jiri Pirko <jpirko@redhat.com> | 2009-04-14 11:33:57 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-14 12:41:15 -0400 |
commit | 72c6a9870f901045f2464c3dc6ee8914bfdc07aa (patch) | |
tree | 8bd683fea5f20b17dab613ed8864c016e7b5d369 | |
parent | 6fd9b3a40b82081d9e6490b0d7cd656e9a78a134 (diff) |
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>
-rw-r--r-- | include/linux/rculist.h | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/include/linux/rculist.h b/include/linux/rculist.h index e649bd3f2c97..5710f43bbc9e 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h | |||
@@ -198,6 +198,32 @@ static inline void list_splice_init_rcu(struct list_head *list, | |||
198 | at->prev = last; | 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 | #define __list_for_each_rcu(pos, head) \ | 227 | #define __list_for_each_rcu(pos, head) \ |
202 | for (pos = rcu_dereference((head)->next); \ | 228 | for (pos = rcu_dereference((head)->next); \ |
203 | pos != (head); \ | 229 | pos != (head); \ |
@@ -214,9 +240,9 @@ static inline void list_splice_init_rcu(struct list_head *list, | |||
214 | * as long as the traversal is guarded by rcu_read_lock(). | 240 | * as long as the traversal is guarded by rcu_read_lock(). |
215 | */ | 241 | */ |
216 | #define list_for_each_entry_rcu(pos, head, member) \ | 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 | prefetch(pos->member.next), &pos->member != (head); \ | 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 | /** |