mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	locking/mutex: Set and clear owner using WRITE_ONCE()
The mutex owner can get read and written to locklessly. Use WRITE_ONCE when setting and clearing the owner field in order to avoid optimizations such as store tearing. This avoids situations where the owner field gets written to with multiple stores and another thread could concurrently read and use a partially written owner value. Signed-off-by: Jason Low <jason.low2@hpe.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Davidlohr Bueso <dave@stgolabs.net> Acked-by: Waiman Long <Waiman.Long@hpe.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Scott J Norton <scott.norton@hpe.com> Cc: Terry Rudd <terry.rudd@hpe.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1463782776.2479.9.camel@j-VirtualBox Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									c0fcb6c2d3
								
							
						
					
					
						commit
						6e2814745c
					
				
					 2 changed files with 10 additions and 4 deletions
				
			
		|  | @ -29,12 +29,12 @@ extern void debug_mutex_init(struct mutex *lock, const char *name, | ||||||
| 
 | 
 | ||||||
| static inline void mutex_set_owner(struct mutex *lock) | static inline void mutex_set_owner(struct mutex *lock) | ||||||
| { | { | ||||||
| 	lock->owner = current; | 	WRITE_ONCE(lock->owner, current); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void mutex_clear_owner(struct mutex *lock) | static inline void mutex_clear_owner(struct mutex *lock) | ||||||
| { | { | ||||||
| 	lock->owner = NULL; | 	WRITE_ONCE(lock->owner, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #define spin_lock_mutex(lock, flags)			\ | #define spin_lock_mutex(lock, flags)			\ | ||||||
|  |  | ||||||
|  | @ -17,14 +17,20 @@ | ||||||
| 		__list_del((waiter)->list.prev, (waiter)->list.next) | 		__list_del((waiter)->list.prev, (waiter)->list.next) | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_MUTEX_SPIN_ON_OWNER | #ifdef CONFIG_MUTEX_SPIN_ON_OWNER | ||||||
|  | /*
 | ||||||
|  |  * The mutex owner can get read and written to locklessly. | ||||||
|  |  * We should use WRITE_ONCE when writing the owner value to | ||||||
|  |  * avoid store tearing, otherwise, a thread could potentially | ||||||
|  |  * read a partially written and incomplete owner value. | ||||||
|  |  */ | ||||||
| static inline void mutex_set_owner(struct mutex *lock) | static inline void mutex_set_owner(struct mutex *lock) | ||||||
| { | { | ||||||
| 	lock->owner = current; | 	WRITE_ONCE(lock->owner, current); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void mutex_clear_owner(struct mutex *lock) | static inline void mutex_clear_owner(struct mutex *lock) | ||||||
| { | { | ||||||
| 	lock->owner = NULL; | 	WRITE_ONCE(lock->owner, NULL); | ||||||
| } | } | ||||||
| #else | #else | ||||||
| static inline void mutex_set_owner(struct mutex *lock) | static inline void mutex_set_owner(struct mutex *lock) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jason Low
						Jason Low