Commit 72c6a9870f901045f2464c3dc6ee8914bfdc07aa

Authored by Jiri Pirko
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 /**