forked from mirrors/linux
		
	list: Use WRITE_ONCE() when adding to lists and hlists
Code that does lockless emptiness testing of non-RCU lists is relying on the list-addition code to write the list head's ->next pointer atomically. This commit therefore adds WRITE_ONCE() to list-addition pointer stores that could affect the head's ->next pointer. Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
		
							parent
							
								
									6cf1008122
								
							
						
					
					
						commit
						1c97be677f
					
				
					 2 changed files with 5 additions and 5 deletions
				
			
		|  | @ -42,7 +42,7 @@ static inline void __list_add(struct list_head *new, | ||||||
| 	next->prev = new; | 	next->prev = new; | ||||||
| 	new->next = next; | 	new->next = next; | ||||||
| 	new->prev = prev; | 	new->prev = prev; | ||||||
| 	prev->next = new; | 	WRITE_ONCE(prev->next, new); | ||||||
| } | } | ||||||
| #else | #else | ||||||
| extern void __list_add(struct list_head *new, | extern void __list_add(struct list_head *new, | ||||||
|  | @ -642,7 +642,7 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) | ||||||
| 	n->next = first; | 	n->next = first; | ||||||
| 	if (first) | 	if (first) | ||||||
| 		first->pprev = &n->next; | 		first->pprev = &n->next; | ||||||
| 	h->first = n; | 	WRITE_ONCE(h->first, n); | ||||||
| 	n->pprev = &h->first; | 	n->pprev = &h->first; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -653,14 +653,14 @@ static inline void hlist_add_before(struct hlist_node *n, | ||||||
| 	n->pprev = next->pprev; | 	n->pprev = next->pprev; | ||||||
| 	n->next = next; | 	n->next = next; | ||||||
| 	next->pprev = &n->next; | 	next->pprev = &n->next; | ||||||
| 	*(n->pprev) = n; | 	WRITE_ONCE(*(n->pprev), n); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void hlist_add_behind(struct hlist_node *n, | static inline void hlist_add_behind(struct hlist_node *n, | ||||||
| 				    struct hlist_node *prev) | 				    struct hlist_node *prev) | ||||||
| { | { | ||||||
| 	n->next = prev->next; | 	n->next = prev->next; | ||||||
| 	prev->next = n; | 	WRITE_ONCE(prev->next, n); | ||||||
| 	n->pprev = &prev->next; | 	n->pprev = &prev->next; | ||||||
| 
 | 
 | ||||||
| 	if (n->next) | 	if (n->next) | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ void __list_add(struct list_head *new, | ||||||
| 	next->prev = new; | 	next->prev = new; | ||||||
| 	new->next = next; | 	new->next = next; | ||||||
| 	new->prev = prev; | 	new->prev = prev; | ||||||
| 	prev->next = new; | 	WRITE_ONCE(prev->next, new); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(__list_add); | EXPORT_SYMBOL(__list_add); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Paul E. McKenney
						Paul E. McKenney