Skip to contentSkip to conversation

locking/mutex: Set and clear owner using WRITE_ONCE()

PATCH Superseded Jason Low 3 participants 3 messages May 20, 2016 – Jun 3, 2016 Locking primitives

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Jason Low

author
#0 lore raw

PATCH v2 1/1 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.

---
 kernel/locking/mutex-debug.h |  4 ++--
 kernel/locking/mutex.h       | 10 ++++++++--
 2 files changed, 10 insertions(+), 4 deletions(-)
kernel/locking/mutex-debug.h +2 -2
index 0799fd3..372e653 100644
@@ -29,12 +29,12 @@ extern void debug_mutex_init(struct mutex *lock, const char *name,
 
 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)
 {
-	lock->owner = NULL;
+	WRITE_ONCE(lock->owner, NULL);
 }
 
 #define spin_lock_mutex(lock, flags)			\
kernel/locking/mutex.h +8 -2
index 5cda397..12f9619 100644
@@ -17,14 +17,20 @@
 		__list_del((waiter)->list.prev, (waiter)->list.next)
 
 #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)
 {
-	lock->owner = current;
+	WRITE_ONCE(lock->owner, current);
 }
 
 static inline void mutex_clear_owner(struct mutex *lock)
 {
-	lock->owner = NULL;
+	WRITE_ONCE(lock->owner, NULL);
 }
 #else
 static inline void mutex_set_owner(struct mutex *lock)
Signature · 1 line
2.1.4
Acked-by on v2 1/1
#1 lore raw
Quoted 50 lines · Jason Low

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.

---
  kernel/locking/mutex-debug.h |  4 ++--
  kernel/locking/mutex.h       | 10 ++++++++--
  2 files changed, 10 insertions(+), 4 deletions(-)
kernel/locking/mutex-debug.h +2 -2
index 0799fd3..372e653 100644
@@ -29,12 +29,12 @@ extern void debug_mutex_init(struct mutex *lock, const char *name,
 
  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)
  {
-	lock->owner = NULL;
+	WRITE_ONCE(lock->owner, NULL);
  }
 
  #define spin_lock_mutex(lock, flags)			\
kernel/locking/mutex.h +6 -1
index 5cda397..12f9619 100644
@@ -17,14 +17,20 @@
  		__list_del((waiter)->list.prev, (waiter)->list.next)
 
  #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)
  {
-	lock->owner = current;

kernel/locking/mutex.h line 36

Quoted 10 lines
kernel/locking/mutex.h +2 -1
+	WRITE_ONCE(lock->owner, current);
  }
 
  static inline void mutex_clear_owner(struct mutex *lock)
  {
-	lock->owner = NULL;
+	WRITE_ONCE(lock->owner, NULL);
  }
  #else
  static inline void mutex_set_owner(struct mutex *lock)
#2 lore raw
In reply to Jason Low
locking/mutex: Set and clear owner using WRITE_ONCE()
Commit-ID:  6e2814745c67ab422b86262b05e6f23a56f28aa3
Gitweb:     http://git.kernel.org/tip/6e2814745c67ab422b86262b05e6f23a56f28aa3
Author:     Jason Low <[email protected]>
AuthorDate: Fri, 20 May 2016 15:19:36 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Fri, 3 Jun 2016 12:06:10 +0200

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.

---
 kernel/locking/mutex-debug.h |  4 ++--
 kernel/locking/mutex.h       | 10 ++++++++--
 2 files changed, 10 insertions(+), 4 deletions(-)
kernel/locking/mutex-debug.h +2 -2
index 0799fd3..372e653 100644
@@ -29,12 +29,12 @@ extern void debug_mutex_init(struct mutex *lock, const char *name,
 
 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)
 {
-	lock->owner = NULL;
+	WRITE_ONCE(lock->owner, NULL);
 }
 
 #define spin_lock_mutex(lock, flags)			\
kernel/locking/mutex.h +8 -2
index 5cda397..12f9619 100644
@@ -17,14 +17,20 @@
 		__list_del((waiter)->list.prev, (waiter)->list.next)
 
 #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)
 {
-	lock->owner = current;
+	WRITE_ONCE(lock->owner, current);
 }
 
 static inline void mutex_clear_owner(struct mutex *lock)
 {
-	lock->owner = NULL;
+	WRITE_ONCE(lock->owner, NULL);
 }
 #else
 static inline void mutex_set_owner(struct mutex *lock)