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>
This commit is contained in:
		
					parent
					
						
							
								6fd9b3a40b
							
						
					
				
			
			
				commit
				
					
						72c6a9870f
					
				
			
		
					 1 changed files with 28 additions and 2 deletions
				
			
		| 
						 | 
					@ -198,6 +198,32 @@ static inline void list_splice_init_rcu(struct list_head *list,
 | 
				
			||||||
	at->prev = last;
 | 
						at->prev = last;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * list_entry_rcu - get the struct for this entry
 | 
				
			||||||
 | 
					 * @ptr:        the &struct list_head pointer.
 | 
				
			||||||
 | 
					 * @type:       the type of the struct this is embedded in.
 | 
				
			||||||
 | 
					 * @member:     the name of the list_struct within the struct.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This primitive may safely run concurrently with the _rcu list-mutation
 | 
				
			||||||
 | 
					 * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define list_entry_rcu(ptr, type, member) \
 | 
				
			||||||
 | 
						container_of(rcu_dereference(ptr), type, member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * list_first_entry_rcu - get the first element from a list
 | 
				
			||||||
 | 
					 * @ptr:        the list head to take the element from.
 | 
				
			||||||
 | 
					 * @type:       the type of the struct this is embedded in.
 | 
				
			||||||
 | 
					 * @member:     the name of the list_struct within the struct.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note, that list is expected to be not empty.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This primitive may safely run concurrently with the _rcu list-mutation
 | 
				
			||||||
 | 
					 * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define list_first_entry_rcu(ptr, type, member) \
 | 
				
			||||||
 | 
						list_entry_rcu((ptr)->next, type, member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define __list_for_each_rcu(pos, head) \
 | 
					#define __list_for_each_rcu(pos, head) \
 | 
				
			||||||
	for (pos = rcu_dereference((head)->next); \
 | 
						for (pos = rcu_dereference((head)->next); \
 | 
				
			||||||
		pos != (head); \
 | 
							pos != (head); \
 | 
				
			||||||
| 
						 | 
					@ -214,9 +240,9 @@ static inline void list_splice_init_rcu(struct list_head *list,
 | 
				
			||||||
 * as long as the traversal is guarded by rcu_read_lock().
 | 
					 * as long as the traversal is guarded by rcu_read_lock().
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define list_for_each_entry_rcu(pos, head, member) \
 | 
					#define list_for_each_entry_rcu(pos, head, member) \
 | 
				
			||||||
	for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \
 | 
						for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
 | 
				
			||||||
		prefetch(pos->member.next), &pos->member != (head); \
 | 
							prefetch(pos->member.next), &pos->member != (head); \
 | 
				
			||||||
		pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member))
 | 
							pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue