Skip to contentSkip to conversation

MCS Lock: MCS lock code cleanup and optimizations

PATCH Superseded Tim Chen 6 participants 26 messages Jan 21, 2014 – Jan 22, 2014 1 message not in the archive

Subsystems (20)

v8 of 9 Superseded Latest is v9 →

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Tim Chen

author
#1 lore raw

v8 cover MCS Lock: MCS lock code cleanup and optimizations

This update to the patch series reorganize the order of the patches by fixing MCS lock barrier leakage first before making standalone MCS lock and unlock functions. We also changed the hooks to architecture specific mcs_spin_lock_contended and mcs_spin_lock_uncontended from needing Kconfig to generic-asm and putting arch specific asm headers as needed. Peter, please review the last patch and bless it with your signed-off if it looks right.

This patch series fixes barriers of MCS lock and perform some optimizations. Proper passing of the mcs lock is now done with smp_load_acquire() in mcs_spin_lock() and smp_store_release() in mcs_spin_unlock. Note that this is not sufficient to form a full memory barrier across cpus on many architectures (except x86) for the mcs_unlock and mcs_lock pair. For code that needs a full memory barrier with mcs_unlock and mcs_lock pair, smp_mb__after_unlock_lock() should be used after mcs_lock.

Will also added hooks to allow for architecture specific implementation and optimization of the of the contended paths of lock and unlock of mcs_spin_lock and mcs_spin_unlock functions.

The original mcs lock code has potential leaks between critical sections, which was not a problem when MCS was embedded within the mutex but needs to be corrected when allowing the MCS lock to be used by itself for other locking purposes. The MCS lock code was previously embedded in the mutex.c and is now sepearted. This allows for easier reuse of MCS lock in other places like rwsem and qrwlock.

Tim

v8:
1. Move order of patches by putting barrier corrections first.
2. Use generic-asm headers for hooking in arch specific mcs_spin_lock_contended and mcs_spin_lock_uncontended function.
3. Some minor cleanup and comments added.

v7:
1. Update architecture specific hooks with concise architecture specific arch_mcs_spin_lock_contended and arch_mcs_spin_lock_uncontended functions.

v6:
1. Fix a bug of improper xchg_acquire and extra space in barrier fixing patch.
2. Added extra hooks to allow for architecture specific version of mcs_spin_lock and mcs_spin_unlock to be used.

v5:
1. Rework barrier correction patch. We now use smp_load_acquire() in mcs_spin_lock() and smp_store_release() in mcs_spin_unlock() to allow for architecture dependent barriers to be automatically used. This is clean and will provide the right barriers for all architecture.

v4:
1. Move patch series to the latest tip after v3.12

v3:
1. modified memory barriers to support non x86 architectures that have weak memory ordering.

v2:
1. change export mcs_spin_lock as a GPL export symbol
2. corrected mcs_spin_lock to references

Jason Low (1):
MCS Lock: optimizations and extra comments

Peter Zijlstra (1):
MCS Lock: Allow architecture specific asm files to be used for
contended case

Tim Chen (2):
MCS Lock: Restructure the MCS lock defines and locking MCS Lock: allow architectures to hook in to contended

Waiman Long (2):
MCS Lock: Barrier corrections
MCS Lock: Move mcs_lock/unlock function into its own

 arch/alpha/include/asm/Kbuild      |   1 +
 arch/arc/include/asm/Kbuild        |   1 +
 arch/arm/include/asm/Kbuild        |   1 +
 arch/arm64/include/asm/Kbuild      |   1 +
 arch/avr32/include/asm/Kbuild      |   1 +
 arch/blackfin/include/asm/Kbuild   |   1 +
 arch/c6x/include/asm/Kbuild        |   1 +
 arch/cris/include/asm/Kbuild       |   1 +
 arch/frv/include/asm/Kbuild        |   1 +
 arch/hexagon/include/asm/Kbuild    |   1 +
 arch/ia64/include/asm/Kbuild       |   2 +-
 arch/m32r/include/asm/Kbuild       |   1 +
 arch/m68k/include/asm/Kbuild       |   1 +
 arch/metag/include/asm/Kbuild      |   1 +
 arch/microblaze/include/asm/Kbuild |   1 +
 arch/mips/include/asm/Kbuild       |   1 +
 arch/mn10300/include/asm/Kbuild    |   1 +
 arch/openrisc/include/asm/Kbuild   |   1 +
 arch/parisc/include/asm/Kbuild     |   1 +
 arch/powerpc/include/asm/Kbuild    |   2 +-
 arch/s390/include/asm/Kbuild       |   1 +
 arch/score/include/asm/Kbuild      |   1 +
 arch/sh/include/asm/Kbuild         |   1 +
 arch/sparc/include/asm/Kbuild      |   1 +
 arch/tile/include/asm/Kbuild       |   1 +
 arch/um/include/asm/Kbuild         |   1 +
 arch/unicore32/include/asm/Kbuild  |   1 +
 arch/x86/include/asm/Kbuild        |   1 +
 arch/xtensa/include/asm/Kbuild     |   1 +
 include/asm-generic/mcs_spinlock.h |  13 +++++
 include/linux/mcs_spinlock.h       |  27 ++++++++++
 include/linux/mutex.h              |   5 +-
 kernel/locking/Makefile            |   6 +--
 kernel/locking/mcs_spinlock.c      | 103 +++++++++++++++++++++++++++++++++++++
 kernel/locking/mutex.c             |  60 +++------------------
 35 files changed, 185 insertions(+), 60 deletions(-)
 create mode 100644 include/asm-generic/mcs_spinlock.h
 create mode 100644 include/linux/mcs_spinlock.h
 create mode 100644 kernel/locking/mcs_spinlock.c
Signature · 1 line
1.7.11.7
author
#2 lore raw

PATCH v8 1/6 MCS Lock: Barrier corrections

In reply to a message not in the archive

From: Waiman Long <[email protected]>

This patch corrects the way memory barriers are used in the MCS lock with smp_load_acquire and smp_store_release fucnction.
It removes ones that are not needed.

---
 kernel/locking/mutex.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
kernel/locking/mutex.c +13 -5
index 4dd6e4c..fbbd2ed 100644
@@ -136,9 +136,12 @@ void mspin_lock(struct mspin_node **lock, struct mspin_node *node)
 		return;
 	}
 	ACCESS_ONCE(prev->next) = node;
-	smp_wmb();
-	/* Wait until the lock holder passes the lock down */
-	while (!ACCESS_ONCE(node->locked))
+	/*
+	 * Wait until the lock holder passes the lock down.
+	 * Using smp_load_acquire() provides a memory barrier that
+	 * ensures subsequent operations happen after the lock is acquired.
+	 */
+	while (!(smp_load_acquire(&node->locked)))
 		arch_mutex_cpu_relax();
 }
 
@@ -156,8 +159,13 @@ static void mspin_unlock(struct mspin_node **lock, struct mspin_node *node)
 		while (!(next = ACCESS_ONCE(node->next)))
 			arch_mutex_cpu_relax();
 	}
-	ACCESS_ONCE(next->locked) = 1;
-	smp_wmb();
+	/*
+	 * Pass lock to next waiter.
+	 * smp_store_release() provides a memory barrier to ensure
+	 * all operations in the critical section has been completed
+	 * before unlocking.
+	 */
+	smp_store_release(&next->locked, 1);
 }
 
 /*
Signature · 1 line
1.7.11.7
author
#3 lore raw

PATCH v8 2/6 MCS Lock: Restructure the MCS lock defines and locking

In reply to a message not in the archive

We will need the MCS lock code for doing optimistic spinning for rwsem and queue rwlock. Extracting the MCS code from mutex.c and put into its own file allow us to reuse this code easily.

Note that using the smp_load_acquire/smp_store_release pair used in mcs_lock and mcs_unlock is not sufficient to form a full memory barrier across cpus for many architectures (except x86). For applications that absolutely need a full barrier across multiple cpus with mcs_unlock and mcs_lock pair, smp_mb__after_unlock_lock() should be used after mcs_lock.

---
 include/linux/mcs_spinlock.h | 81 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mutex.h        |  5 +--
 kernel/locking/mutex.c       | 68 ++++---------------------------------
 3 files changed, 91 insertions(+), 63 deletions(-)
 create mode 100644 include/linux/mcs_spinlock.h
include/linux/mcs_spinlock.h new file +81 -0
new file mode 100644
index 0000000..23912cb
@@ -0,0 +1,81 @@
+/*
+ * MCS lock defines
+ *
+ * This file contains the main data structure and API definitions of MCS lock.
+ *
+ * The MCS lock (proposed by Mellor-Crummey and Scott) is a simple spin-lock
+ * with the desirable properties of being fair, and with each cpu trying
+ * to acquire the lock spinning on a local variable.
+ * It avoids expensive cache bouncings that common test-and-set spin-lock
+ * implementations incur.
+ */
+#ifndef __LINUX_MCS_SPINLOCK_H
+#define __LINUX_MCS_SPINLOCK_H
+
+struct mcs_spinlock {
+	struct mcs_spinlock *next;
+	int locked; /* 1 if lock acquired */
+};
+
+/*
+ * Note: the smp_load_acquire/smp_store_release pair is not
+ * sufficient to form a full memory barrier across
+ * cpus for many architectures (except x86) for mcs_unlock and mcs_lock.
+ * For applications that need a full barrier across multiple cpus
+ * with mcs_unlock and mcs_lock pair, smp_mb__after_unlock_lock() should be
+ * used after mcs_lock.
+ */
+
+/*
+ * We don't inline mcs_spin_lock() so that perf can correctly account for the
+ * time spent in this lock function.
+ */
+static noinline
+void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
+{
+	struct mcs_spinlock *prev;
+
+	/* Init node */
+	node->locked = 0;
+	node->next   = NULL;
+
+	prev = xchg(lock, node);
+	if (likely(prev == NULL)) {
+		/* Lock acquired */
+		node->locked = 1;
+		return;
+	}
+	ACCESS_ONCE(prev->next) = node;
+	/*
+	 * Wait until the lock holder passes the lock down.
+	 * Using smp_load_acquire() provides a memory barrier that
+	 * ensures subsequent operations happen after the lock is acquired.
+	 */
+	while (!(smp_load_acquire(&node->locked)))
+		arch_mutex_cpu_relax();
+}
+
+static void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
+{
+	struct mcs_spinlock *next = ACCESS_ONCE(node->next);
+
+	if (likely(!next)) {
+		/*
+		 * Release the lock by setting it to NULL
+		 */
+		if (cmpxchg(lock, node, NULL) == node)
+			return;
+		/* Wait until the next pointer is set */
+		while (!(next = ACCESS_ONCE(node->next)))
+			arch_mutex_cpu_relax();
+	}
+	/*
+	 * Pass lock to next waiter.
+	 * smp_store_release() provides a memory barrier to ensure
+	 * all operations in the critical section has been completed
+	 * before unlocking.
+	 */
+	smp_store_release(&next->locked, 1);
+}
+
+#endif /* __LINUX_MCS_SPINLOCK_H */
include/linux/mutex.h +3 -2
index d318193..c482e1d 100644
@@ -46,6 +46,7 @@
  * - detects multi-task circular deadlocks and prints out all affected
  *   locks and tasks (and only those tasks)
  */
+struct mcs_spinlock;
 struct mutex {
 	/* 1: unlocked, 0: locked, negative: locked, possible waiters */
 	atomic_t		count;
@@ -55,7 +56,7 @@ struct mutex {
 	struct task_struct	*owner;
 #endif
 #ifdef CONFIG_MUTEX_SPIN_ON_OWNER
-	void			*spin_mlock;	/* Spinner MCS lock */
+	struct mcs_spinlock	*mcs_lock;	/* Spinner MCS lock */
 #endif
 #ifdef CONFIG_DEBUG_MUTEXES
 	const char 		*name;
@@ -179,4 +180,4 @@ extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
 # define arch_mutex_cpu_relax() cpu_relax()
 #endif
 
-#endif
+#endif /* __LINUX_MUTEX_H */
kernel/locking/mutex.c +7 -61

110 lines not on this page · raw message

Signature · 9 lines
1.7.11.7



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
author
#4 lore raw

PATCH v8 3/6 MCS Lock: optimizations and extra comments

In reply to a message not in the archive

From: Jason Low <[email protected]>

Remove unnecessary operation to assign locked status to 1 if lock is acquired without contention as this value will not be checked by lock holder again and other potential lock contenders will not be looking at their own lock status.

Make the cmpxchg(lock, node, NULL) == node check in mcs_spin_unlock() likely() as it is likely that a race did not occur most of the time.

Also add in more comments describing how the local node is used in MCS locks.

---
 include/linux/mcs_spinlock.h | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
include/linux/mcs_spinlock.h +16 -3
index 23912cb..bfe84c6 100644
@@ -27,6 +27,12 @@ struct mcs_spinlock {
  */
 
 /*
+ * In order to acquire the lock, the caller should declare a local node and
+ * pass a reference of the node to this function in addition to the lock.
+ * If the lock has already been acquired, then this will proceed to spin
+ * on this node->locked until the previous lock holder sets the node->locked
+ * in mcs_spin_unlock().
+ *
  * We don't inline mcs_spin_lock() so that perf can correctly account for the
  * time spent in this lock function.
  */
@@ -41,8 +47,11 @@ void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 
 	prev = xchg(lock, node);
 	if (likely(prev == NULL)) {
-		/* Lock acquired */
-		node->locked = 1;
+		/* Lock acquired, don't need to set node->locked to 1
+		 * as lock owner and other contenders won't check this value.
+		 * If a debug mode is needed to audit lock status, then
+		 * set node->locked value here.
+		 */
 		return;
 	}
 	ACCESS_ONCE(prev->next) = node;
@@ -55,6 +64,10 @@ void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 		arch_mutex_cpu_relax();
 }
 
+/*
+ * Releases the lock. The caller should pass in the corresponding node that
+ * was used to acquire the lock.
+ */
 static void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 {
 	struct mcs_spinlock *next = ACCESS_ONCE(node->next);
@@ -63,7 +76,7 @@ static void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *nod
 		/*
 		 * Release the lock by setting it to NULL
 		 */
-		if (cmpxchg(lock, node, NULL) == node)
+		if (likely(cmpxchg(lock, node, NULL) == node))
 			return;
 		/* Wait until the next pointer is set */
 		while (!(next = ACCESS_ONCE(node->next)))
Signature · 9 lines
1.7.11.7



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
maintainer
#5 lore raw

Re: [PATCH v8 3/6] MCS Lock: optimizations and extra comments

include/linux/mcs_spinlock.h void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node) · line 54

Quoted 11 lines · Tim Chen
include/linux/mcs_spinlock.h +5 -2
@@ -41,8 +47,11 @@ void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 
 	prev = xchg(lock, node);
 	if (likely(prev == NULL)) {
-		/* Lock acquired */
-		node->locked = 1;
+		/* Lock acquired, don't need to set node->locked to 1
+		 * as lock owner and other contenders won't check this value.
+		 * If a debug mode is needed to audit lock status, then
+		 * set node->locked value here.
+		 */

Fail in comment style.

include/linux/mcs_spinlock.h void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node) · line 57

Quoted 3 lines
include/linux/mcs_spinlock.h +0 -0
 		return;
 	}
 	ACCESS_ONCE(prev->next) = node;

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#6 lore raw

Re: [PATCH v8 3/6] MCS Lock: optimizations and extra comments

In reply to Tim Chen
Quoted 6 lines · Tim Chen

From: Jason Low <[email protected]>

Remove unnecessary operation to assign locked status to 1 if lock is acquired without contention as this value will not be checked by lock holder again and other potential lock contenders will not be looking at their own lock status.

Ha, read that again :-)

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#7 lore raw

Re: [PATCH v8 3/6] MCS Lock: optimizations and extra comments

Quoted 7 lines · Peter Zijlstra
Quoted 6 lines · Tim Chen

From: Jason Low <[email protected]>

Remove unnecessary operation to assign locked status to 1 if lock is acquired without contention as this value will not be checked by lock holder again and other potential lock contenders will not be looking at their own lock status.

should be "lock contenders will not be looking at lock holder's lock status"

Thanks for catching it.

Tim

Quoted 4 lines

Ha, read that again :-)

#8 lore raw

Re: [PATCH v8 3/6] MCS Lock: optimizations and extra comments

In reply to Tim Chen

include/linux/mcs_spinlock.h void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node) · line 54

Quoted 13 lines · Tim Chen

From: Jason Low <[email protected]>

include/linux/mcs_spinlock.h +5 -2
@@ -41,8 +47,11 @@ void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 
        prev = xchg(lock, node);
        if (likely(prev == NULL)) {
-               /* Lock acquired */
-               node->locked = 1;
+               /* Lock acquired, don't need to set node->locked to 1
+                * as lock owner and other contenders won't check this value.
+                * If a debug mode is needed to audit lock status, then
+                * set node->locked value here.
+                */

It would also be good to mention why the value is not checked in this comment. Perhaps something like the following:

/*
* Lock acquired, don't need to set node->locked to 1. Threads
* only spin on its own node->locked value for lock acquisition.
* However, since this thread can immediately acquire the lock
* and does not proceed to spin on its own node->locked, this
* value won't be used. If a debug mode is needed to
* audit lock status, then set node->locked value here. */

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#9 lore raw

Re: [PATCH v8 3/6] MCS Lock: optimizations and extra comments

Quoted 8 lines · Jason Low

/*
* Lock acquired, don't need to set node->locked to 1. Threads
* only spin on its own node->locked value for lock acquisition.
* However, since this thread can immediately acquire the lock
* and does not proceed to spin on its own node->locked, this
* value won't be used. If a debug mode is needed to
* audit lock status, then set node->locked value here. */

I'll update the comment accordingly.

Tim

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#10 lore raw

PATCH v8 4/6 MCS Lock: Move mcs_lock/unlock function into its own

In reply to a message not in the archive

From: Waiman Long <[email protected]>

Create a new mcs_spinlock.c file to contain the
mcs_spin_lock() and mcs_spin_unlock() function.

---
 include/linux/mcs_spinlock.h                       | 77 ++--------------------
 kernel/locking/Makefile                            |  6 +-
 .../locking/mcs_spinlock.c                         | 27 ++++----
 3 files changed, 18 insertions(+), 92 deletions(-)
 copy include/linux/mcs_spinlock.h => kernel/locking/mcs_spinlock.c (82%)
include/linux/mcs_spinlock.h +4 -73
index bfe84c6..d54bb23 100644
@@ -17,78 +17,9 @@ struct mcs_spinlock {
 	int locked; /* 1 if lock acquired */
 };
 
-/*
- * Note: the smp_load_acquire/smp_store_release pair is not
- * sufficient to form a full memory barrier across
- * cpus for many architectures (except x86) for mcs_unlock and mcs_lock.
- * For applications that need a full barrier across multiple cpus
- * with mcs_unlock and mcs_lock pair, smp_mb__after_unlock_lock() should be
- * used after mcs_lock.
- */
-
-/*
- * In order to acquire the lock, the caller should declare a local node and
- * pass a reference of the node to this function in addition to the lock.
- * If the lock has already been acquired, then this will proceed to spin
- * on this node->locked until the previous lock holder sets the node->locked
- * in mcs_spin_unlock().
- *
- * We don't inline mcs_spin_lock() so that perf can correctly account for the
- * time spent in this lock function.
- */
-static noinline
-void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
-{
-	struct mcs_spinlock *prev;
-
-	/* Init node */
-	node->locked = 0;
-	node->next   = NULL;
-
-	prev = xchg(lock, node);
-	if (likely(prev == NULL)) {
-		/* Lock acquired, don't need to set node->locked to 1
-		 * as lock owner and other contenders won't check this value.
-		 * If a debug mode is needed to audit lock status, then
-		 * set node->locked value here.
-		 */
-		return;
-	}
-	ACCESS_ONCE(prev->next) = node;
-	/*
-	 * Wait until the lock holder passes the lock down.
-	 * Using smp_load_acquire() provides a memory barrier that
-	 * ensures subsequent operations happen after the lock is acquired.
-	 */
-	while (!(smp_load_acquire(&node->locked)))
-		arch_mutex_cpu_relax();
-}
-
-/*
- * Releases the lock. The caller should pass in the corresponding node that
- * was used to acquire the lock.
- */
-static void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
-{
-	struct mcs_spinlock *next = ACCESS_ONCE(node->next);
-
-	if (likely(!next)) {
-		/*
-		 * Release the lock by setting it to NULL
-		 */
-		if (likely(cmpxchg(lock, node, NULL) == node))
-			return;
-		/* Wait until the next pointer is set */
-		while (!(next = ACCESS_ONCE(node->next)))
-			arch_mutex_cpu_relax();
-	}
-	/*
-	 * Pass lock to next waiter.
-	 * smp_store_release() provides a memory barrier to ensure
-	 * all operations in the critical section has been completed
-	 * before unlocking.
-	 */
-	smp_store_release(&next->locked, 1);
-}
+extern
+void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node);
+extern
+void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node);
 
 #endif /* __LINUX_MCS_SPINLOCK_H */
kernel/locking/Makefile +3 -3
index baab8e5..20d9d5c 100644
@@ -13,12 +13,12 @@ obj-$(CONFIG_LOCKDEP) += lockdep.o
 ifeq ($(CONFIG_PROC_FS),y)
 obj-$(CONFIG_LOCKDEP) += lockdep_proc.o
 endif
-obj-$(CONFIG_SMP) += spinlock.o
-obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
+obj-$(CONFIG_SMP) += spinlock.o mcs_spinlock.o
+obj-$(CONFIG_PROVE_LOCKING) += spinlock.o mcs_spinlock.o
 obj-$(CONFIG_RT_MUTEXES) += rtmutex.o
 obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o
 obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o
-obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
+obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o mcs_spinlock.o
 obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
 obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
 obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o
kernel/locking/mcs_spinlock.c renamed from include/linux/mcs_spinlock.h +11 -16
similarity index 82%
copy from include/linux/mcs_spinlock.h
copy to kernel/locking/mcs_spinlock.c
index bfe84c6..c3ee9cf 100644
@@ -1,7 +1,5 @@
 /*
- * MCS lock defines
- *
- * This file contains the main data structure and API definitions of MCS lock.
+ * MCS lock
  *
  * The MCS lock (proposed by Mellor-Crummey and Scott) is a simple spin-lock
  * with the desirable properties of being fair, and with each cpu trying
@@ -9,13 +7,14 @@
  * It avoids expensive cache bouncings that common test-and-set spin-lock
  * implementations incur.
  */
-#ifndef __LINUX_MCS_SPINLOCK_H
-#define __LINUX_MCS_SPINLOCK_H
 
-struct mcs_spinlock {
-	struct mcs_spinlock *next;
-	int locked; /* 1 if lock acquired */
-};
+#include <asm/barrier.h>
+#include <asm/cmpxchg.h>
+#include <asm/processor.h>
+#include <linux/compiler.h>
+#include <linux/mcs_spinlock.h>
+#include <linux/mutex.h>
+#include <linux/export.h>
 
 /*
  * Note: the smp_load_acquire/smp_store_release pair is not
@@ -32,11 +31,7 @@ struct mcs_spinlock {
  * If the lock has already been acquired, then this will proceed to spin
  * on this node->locked until the previous lock holder sets the node->locked
  * in mcs_spin_unlock().
- *
- * We don't inline mcs_spin_lock() so that perf can correctly account for the
- * time spent in this lock function.
  */
-static noinline
 void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 {
 	struct mcs_spinlock *prev;
@@ -63,12 +58,13 @@ void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 	while (!(smp_load_acquire(&node->locked)))
 		arch_mutex_cpu_relax();
 }
+EXPORT_SYMBOL_GPL(mcs_spin_lock);
 
 /*
  * Releases the lock. The caller should pass in the corresponding node that
  * was used to acquire the lock.
  */
-static void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
+void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 {
 	struct mcs_spinlock *next = ACCESS_ONCE(node->next);
 
@@ -90,5 +86,4 @@ static void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *nod
 	 */
 	smp_store_release(&next->locked, 1);
 }
-
-#endif /* __LINUX_MCS_SPINLOCK_H */
+EXPORT_SYMBOL_GPL(mcs_spin_unlock);
Signature · 9 lines
1.7.11.7



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
maintainer
#11 lore raw

Re: [PATCH v8 4/6] MCS Lock: Move mcs_lock/unlock function into its own

Review

Quoted 2 lines · Tim Chen
(quoted diff) +2 -0
+EXPORT_SYMBOL_GPL(mcs_spin_lock);
+EXPORT_SYMBOL_GPL(mcs_spin_unlock);

Do we really need the EXPORTs? The only user so far is mutex and that's core code. The other planned users are rwsems and rwlocks, for both it would be in the slow path, which is also core code.

We should generally only add EXPORTs once theres a need.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#12 lore raw

Re: [PATCH v8 4/6] MCS Lock: Move mcs_lock/unlock function into its own

Quoted 9 lines · Peter Zijlstra

Review

Quoted 2 lines · Tim Chen
(quoted diff) +2 -0
+EXPORT_SYMBOL_GPL(mcs_spin_lock);
+EXPORT_SYMBOL_GPL(mcs_spin_unlock);

Do we really need the EXPORTs? The only user so far is mutex and that's core code. The other planned users are rwsems and rwlocks, for both it would be in the slow path, which is also core code.

We should generally only add EXPORTs once theres a need.

In fact I'd argue the hot path needs to be inlined.

We only don't inline regular locking primitives because it would blow up the kernel's size in too many critical places.

But inlining an _internal_ locking implementation used in just a handful of places is a no-brainer...

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#13 lore raw

Re: [PATCH v8 4/6] MCS Lock: Move mcs_lock/unlock function into its own

Quoted 12 lines · Ingo Molnar
Quoted 9 lines · Peter Zijlstra

Review

Quoted 2 lines · Tim Chen
(quoted diff) +2 -0
+EXPORT_SYMBOL_GPL(mcs_spin_lock);
+EXPORT_SYMBOL_GPL(mcs_spin_unlock);

Do we really need the EXPORTs? The only user so far is mutex and that's core code. The other planned users are rwsems and rwlocks, for both it would be in the slow path, which is also core code.

We should generally only add EXPORTs once theres a need.

Quoted 8 lines

In fact I'd argue the hot path needs to be inlined.

We only don't inline regular locking primitives because it would blow up the kernel's size in too many critical places.

But inlining an _internal_ locking implementation used in just a handful of places is a no-brainer...

The original mspin_lock primitive from which mcs_spin_lock was derived has an explicit noinline annotation. The comment says that it is so that perf can properly account for time spent in the lock function. So it wasn't inlined in previous kernels when we started.

For the time being, I'll just remove the EXPORT. If people feel that inline is the right way to go, then we'll leave the function in mcs_spin_lock.h and not create mcs_spin_lock.c.

Tim

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#14 lore raw

Re: [PATCH v8 4/6] MCS Lock: Move mcs_lock/unlock function into its own

Quoted 18 lines · Tim Chen
Quoted 17 lines · Ingo Molnar
Quoted 9 lines · Peter Zijlstra

Review

Quoted 2 lines · Tim Chen
(quoted diff) +2 -0
+EXPORT_SYMBOL_GPL(mcs_spin_lock);
+EXPORT_SYMBOL_GPL(mcs_spin_unlock);

Do we really need the EXPORTs? The only user so far is mutex and that's core code. The other planned users are rwsems and rwlocks, for both it would be in the slow path, which is also core code.

We should generally only add EXPORTs once theres a need.

In fact I'd argue the hot path needs to be inlined.

We only don't inline regular locking primitives because it would blow up the kernel's size in too many critical places.

Quoted 7 lines
Quoted 2 lines

But inlining an _internal_ locking implementation used in just a handful of places is a no-brainer...

The original mspin_lock primitive from which mcs_spin_lock was derived has an explicit noinline annotation. The comment says that it is so that perf can properly account for time spent in the lock function. So it wasn't inlined in previous kernels when we started.

Not sure what comment that was, but it's not a valid argument:
profiling and measurement is in almost all cases secondary to any performance considerations!

If we keep it out of line then we want to do it only if it's faster that way.

Quoted 3 lines

For the time being, I'll just remove the EXPORT. If people feel that inline is the right way to go, then we'll leave the function in mcs_spin_lock.h and not create mcs_spin_lock.c.

Well, 'people' could be you, the person touching the code? This is really something that is discoverable: look at the critical path in the inlined and the out of line case, and compare the number of instructions. This can be done based on disassembly of the affected code.

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#15 lore raw

Re: [PATCH v8 4/6] MCS Lock: Move mcs_lock/unlock function into its own

Quoted 39 lines · Ingo Molnar
Quoted 18 lines · Tim Chen
Quoted 17 lines · Ingo Molnar
Quoted 9 lines · Peter Zijlstra

Review

Quoted 2 lines · Tim Chen
(quoted diff) +2 -0
+EXPORT_SYMBOL_GPL(mcs_spin_lock);
+EXPORT_SYMBOL_GPL(mcs_spin_unlock);

Do we really need the EXPORTs? The only user so far is mutex and that's core code. The other planned users are rwsems and rwlocks, for both it would be in the slow path, which is also core code.

We should generally only add EXPORTs once theres a need.

In fact I'd argue the hot path needs to be inlined.

We only don't inline regular locking primitives because it would blow up the kernel's size in too many critical places.

Quoted 7 lines
Quoted 2 lines

But inlining an _internal_ locking implementation used in just a handful of places is a no-brainer...

The original mspin_lock primitive from which mcs_spin_lock was derived has an explicit noinline annotation. The comment says that it is so that perf can properly account for time spent in the lock function. So it wasn't inlined in previous kernels when we started.

Not sure what comment that was, but it's not a valid argument:
profiling and measurement is in almost all cases secondary to any performance considerations!

If we keep it out of line then we want to do it only if it's faster that way.

Quoted 3 lines

For the time being, I'll just remove the EXPORT. If people feel that inline is the right way to go, then we'll leave the function in mcs_spin_lock.h and not create mcs_spin_lock.c.

Quoted 5 lines

Well, 'people' could be you, the person touching the code? This is really something that is discoverable: look at the critical path in the inlined and the out of line case, and compare the number of instructions. This can be done based on disassembly of the affected code.

Okay, will make it inline function and drop the move of to mcs_spin_lock.c

Tim

Quoted 4 lines

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#16 lore raw

Re: [PATCH v8 4/6] MCS Lock: Move mcs_lock/unlock function into its own

Quoted 4 lines · Tim Chen
Quoted 4 lines
Quoted 3 lines

For the time being, I'll just remove the EXPORT. If people feel that inline is the right way to go, then we'll leave the function in mcs_spin_lock.h and not create mcs_spin_lock.c.

Quoted 8 lines
Quoted 5 lines

Well, 'people' could be you, the person touching the code? This is really something that is discoverable: look at the critical path in the inlined and the out of line case, and compare the number of instructions. This can be done based on disassembly of the affected code.

Okay, will make it inline function and drop the move of to mcs_spin_lock.c

Only if I'm right! I was speculating.

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#17 lore raw

PATCH v8 5/6 MCS Lock: allow architectures to hook in to contended

In reply to a message not in the archive

From: Will Deacon <[email protected]>

When contended, architectures may be able to reduce the polling overhead in ways which aren't expressible using a simple relax() primitive.

This patch allows architectures to hook into the mcs_{lock,unlock} functions for the contended cases only.

---
 kernel/locking/mcs_spinlock.c | 42 ++++++++++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 14 deletions(-)
kernel/locking/mcs_spinlock.c +28 -14
index c3ee9cf..e12ed32 100644
@@ -16,6 +16,28 @@
 #include <linux/mutex.h>
 #include <linux/export.h>
 
+#ifndef arch_mcs_spin_lock_contended
+/*
+ * Using smp_load_acquire() provides a memory barrier that ensures
+ * subsequent operations happen after the lock is acquired.
+ */
+#define arch_mcs_spin_lock_contended(l)					\
+do {									\
+	while (!(smp_load_acquire(l)))					\
+		arch_mutex_cpu_relax();					\
+} while (0)
+#endif
+
+#ifndef arch_mcs_spin_unlock_contended
+/*
+ * smp_store_release() provides a memory barrier to ensure all
+ * operations in the critical section has been completed before
+ * unlocking.
+ */
+#define arch_mcs_spin_unlock_contended(l)				\
+	smp_store_release((l), 1)
+#endif
+
 /*
  * Note: the smp_load_acquire/smp_store_release pair is not
  * sufficient to form a full memory barrier across
@@ -50,13 +72,9 @@ void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 		return;
 	}
 	ACCESS_ONCE(prev->next) = node;
-	/*
-	 * Wait until the lock holder passes the lock down.
-	 * Using smp_load_acquire() provides a memory barrier that
-	 * ensures subsequent operations happen after the lock is acquired.
-	 */
-	while (!(smp_load_acquire(&node->locked)))
-		arch_mutex_cpu_relax();
+
+	/* Wait until the lock holder passes the lock down. */
+	arch_mcs_spin_lock_contended(&node->locked);
 }
 EXPORT_SYMBOL_GPL(mcs_spin_lock);
 
@@ -78,12 +96,8 @@ void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node)
 		while (!(next = ACCESS_ONCE(node->next)))
 			arch_mutex_cpu_relax();
 	}
-	/*
-	 * Pass lock to next waiter.
-	 * smp_store_release() provides a memory barrier to ensure
-	 * all operations in the critical section has been completed
-	 * before unlocking.
-	 */
-	smp_store_release(&next->locked, 1);
+
+	/* Pass lock to next waiter. */
+	arch_mcs_spin_unlock_contended(&next->locked);
 }
 EXPORT_SYMBOL_GPL(mcs_spin_unlock);
Signature · 9 lines
1.7.11.7



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#18 lore raw

Re: [PATCH v8 5/6] MCS Lock: allow architectures to hook in to contended

Hi Tim,

Quoted 10 lines · Tim Chen

From: Will Deacon <[email protected]>

When contended, architectures may be able to reduce the polling overhead in ways which aren't expressible using a simple relax() primitive.

This patch allows architectures to hook into the mcs_{lock,unlock} functions for the contended cases only.

Not a huge problem, but the subject for this patch seem to have been truncated (should be "... contended paths").

Will

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#19 lore raw

PATCH v8 6/6 MCS Lock: Allow architecture specific asm files to be used for contended case

In reply to a message not in the archive

From: Peter Zijlstra <[email protected]>

This patch allows each architecture to add its specific assembly optimized arch_mcs_spin_lock_contended and arch_mcs_spinlock_uncontended for MCS lock and unlock functions.

---
 arch/alpha/include/asm/Kbuild      |  1 +
 arch/arc/include/asm/Kbuild        |  1 +
 arch/arm/include/asm/Kbuild        |  1 +
 arch/arm64/include/asm/Kbuild      |  1 +
 arch/avr32/include/asm/Kbuild      |  1 +
 arch/blackfin/include/asm/Kbuild   |  1 +
 arch/c6x/include/asm/Kbuild        |  1 +
 arch/cris/include/asm/Kbuild       |  1 +
 arch/frv/include/asm/Kbuild        |  1 +
 arch/hexagon/include/asm/Kbuild    |  1 +
 arch/ia64/include/asm/Kbuild       |  2 +-
 arch/m32r/include/asm/Kbuild       |  1 +
 arch/m68k/include/asm/Kbuild       |  1 +
 arch/metag/include/asm/Kbuild      |  1 +
 arch/microblaze/include/asm/Kbuild |  1 +
 arch/mips/include/asm/Kbuild       |  1 +
 arch/mn10300/include/asm/Kbuild    |  1 +
 arch/openrisc/include/asm/Kbuild   |  1 +
 arch/parisc/include/asm/Kbuild     |  1 +
 arch/powerpc/include/asm/Kbuild    |  2 +-
 arch/s390/include/asm/Kbuild       |  1 +
 arch/score/include/asm/Kbuild      |  1 +
 arch/sh/include/asm/Kbuild         |  1 +
 arch/sparc/include/asm/Kbuild      |  1 +
 arch/tile/include/asm/Kbuild       |  1 +
 arch/um/include/asm/Kbuild         |  1 +
 arch/unicore32/include/asm/Kbuild  |  1 +
 arch/x86/include/asm/Kbuild        |  1 +
 arch/xtensa/include/asm/Kbuild     |  1 +
 include/asm-generic/mcs_spinlock.h | 13 +++++++++++++
 include/linux/mcs_spinlock.h       |  2 ++
 31 files changed, 44 insertions(+), 2 deletions(-)
 create mode 100644 include/asm-generic/mcs_spinlock.h
arch/alpha/include/asm/Kbuild +1 -0
index f01fb50..14cbbbc 100644
@@ -4,3 +4,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/arc/include/asm/Kbuild +1 -0
index 9ae21c1..c0773a5 100644
@@ -48,3 +48,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/arm/include/asm/Kbuild +1 -0
index c38b58c..c68cfdd 100644
@@ -34,3 +34,4 @@ generic-y += timex.h
 generic-y += trace_clock.h
 generic-y += unaligned.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/arm64/include/asm/Kbuild +1 -0
index 519f89f..24a3c10 100644
@@ -51,3 +51,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/avr32/include/asm/Kbuild +1 -0
index 658001b..466e13d 100644
@@ -18,3 +18,4 @@ generic-y       += sections.h
 generic-y       += topology.h
 generic-y	+= trace_clock.h
 generic-y       += xor.h
+generic-y += mcs_spinlock.h
arch/blackfin/include/asm/Kbuild +1 -0
index f2b4347..0bd1c5c 100644
@@ -45,3 +45,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/c6x/include/asm/Kbuild +1 -0
index fc0b3c3..21d7100 100644
@@ -57,3 +57,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/cris/include/asm/Kbuild +1 -0
index 199b1a9..c571cc1 100644
@@ -13,3 +13,4 @@ generic-y += trace_clock.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/frv/include/asm/Kbuild +1 -0
index 74742dc..ccca92e 100644
@@ -3,3 +3,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/hexagon/include/asm/Kbuild +1 -0
index ada843c..553077d 100644
@@ -55,3 +55,4 @@ generic-y += ucontext.h
 generic-y += unaligned.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/ia64/include/asm/Kbuild +1 -1
index f93ee08..25aed55 100644
@@ -4,4 +4,4 @@ generic-y += exec.h
 generic-y += kvm_para.h
 generic-y += trace_clock.h
 generic-y += preempt.h
-generic-y += vtime.h
\ No newline at end of file
+generic-y += vtime.hgeneric-y += mcs_spinlock.h
arch/m32r/include/asm/Kbuild +1 -0
index 2b58c5f..d64fdd1 100644
@@ -4,3 +4,4 @@ generic-y += exec.h
 generic-y += module.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/m68k/include/asm/Kbuild +1 -0
index a5d27f2..1f4d44c 100644
@@ -32,3 +32,4 @@ generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/metag/include/asm/Kbuild +1 -0
index 84d0c1d..ae0ae6e 100644
@@ -53,3 +53,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/microblaze/include/asm/Kbuild +1 -0
index a824265..6eb70bd 100644
@@ -5,3 +5,4 @@ generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += syscalls.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/mips/include/asm/Kbuild +1 -0
index 1acbb8b..c718d63 100644
@@ -14,3 +14,4 @@ generic-y += trace_clock.h
 generic-y += preempt.h
 generic-y += ucontext.h
 generic-y += xor.h
+generic-y += mcs_spinlock.h
arch/mn10300/include/asm/Kbuild +1 -0
index 032143e..1393ae5 100644
@@ -4,3 +4,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/openrisc/include/asm/Kbuild +1 -0
index da1951a..7e049d3 100644
@@ -69,3 +69,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/parisc/include/asm/Kbuild +1 -0
index 34b0be4..ebe1649 100644
@@ -6,3 +6,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \
 	  poll.h xor.h clkdev.h exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/powerpc/include/asm/Kbuild +1 -1
index d8f9d2f..426001b 100644
@@ -3,4 +3,4 @@ generic-y += clkdev.h
 generic-y += rwsem.h
 generic-y += trace_clock.h
 generic-y += preempt.h
-generic-y += vtime.h
\ No newline at end of file
+generic-y += vtime.hgeneric-y += mcs_spinlock.h
arch/s390/include/asm/Kbuild +1 -0
index 7a5288f..8508913 100644
@@ -3,3 +3,4 @@
 generic-y += clkdev.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/score/include/asm/Kbuild +1 -0
index fe7471e..8e39afc 100644
@@ -6,3 +6,4 @@ generic-y += clkdev.h
 generic-y += trace_clock.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/sh/include/asm/Kbuild +1 -0
index 231efbb..1aed131 100644
@@ -35,3 +35,4 @@ generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/sparc/include/asm/Kbuild +1 -0
index bf39066..8843299 100644
@@ -17,3 +17,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/tile/include/asm/Kbuild +1 -0
index 22f3bd1..152fc48 100644
@@ -39,3 +39,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/um/include/asm/Kbuild +1 -0
index fdde187..620d729 100644
@@ -4,3 +4,4 @@ generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
 generic-y += switch_to.h clkdev.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/unicore32/include/asm/Kbuild +1 -0
index 00045cb..cd7822c 100644
@@ -61,3 +61,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
arch/x86/include/asm/Kbuild +1 -0
index 7f66985..a8fee07 100644
@@ -5,3 +5,4 @@ genhdr-y += unistd_64.h
 genhdr-y += unistd_x32.h
 
 generic-y += clkdev.h
+generic-y += mcs_spinlock.h
arch/xtensa/include/asm/Kbuild +1 -0
index 228d6ae..9653e5c 100644
@@ -29,3 +29,4 @@ generic-y += topology.h
 generic-y += trace_clock.h
 generic-y += xor.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h
include/asm-generic/mcs_spinlock.h new file +13 -0
new file mode 100644
index 0000000..10cd4ff
@@ -0,0 +1,13 @@
+#ifndef __ASM_MCS_SPINLOCK_H
+#define __ASM_MCS_SPINLOCK_H
+
+/*
+ * Architectures can define their own:
+ *
+ *   arch_mcs_spin_lock_contended(l)
+ *   arch_mcs_spin_unlock_contended(l)
+ *
+ * See kernel/locking/mcs_spinlock.c.
+ */
+
+#endif /* __ASM_MCS_SPINLOCK_H */
include/linux/mcs_spinlock.h +2 -0
index d54bb23..164298a 100644
@@ -12,6 +12,8 @@
 #ifndef __LINUX_MCS_SPINLOCK_H
 #define __LINUX_MCS_SPINLOCK_H
 
+#include <asm/mcs_spinlock.h>
+
 struct mcs_spinlock {
 	struct mcs_spinlock *next;
 	int locked; /* 1 if lock acquired */
Signature · 8 lines
1.7.11.7


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
maintainer
#20 lore raw

Re: [PATCH v8 6/6] MCS Lock: Allow architecture specific asm files to be used for contended case

arch/alpha/include/asm/Kbuild generic-y += clkdev.h · line 7

Quoted 9 lines · Tim Chen
arch/alpha/include/asm/Kbuild +1 -0
index f01fb50..14cbbbc 100644
@@ -4,3 +4,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h

m < p

arch/ia64/include/asm/Kbuild generic-y += exec.h · line 7

Quoted 9 lines
arch/ia64/include/asm/Kbuild +1 -1
@@ -4,4 +4,4 @@ generic-y += exec.h
 generic-y += kvm_para.h
 generic-y += trace_clock.h
 generic-y += preempt.h
-generic-y += vtime.h
\ No newline at end of file
+generic-y += vtime.hgeneric-y += mcs_spinlock.h

EOL fail

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#21 lore raw

Re: [PATCH v8 6/6] MCS Lock: Allow architecture specific asm files to be used for contended case

Quoted 12 lines · Peter Zijlstra

arch/alpha/include/asm/Kbuild generic-y += clkdev.h · line 7

Quoted 9 lines · Tim Chen
arch/alpha/include/asm/Kbuild +1 -0
index f01fb50..14cbbbc 100644
@@ -4,3 +4,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h

m < p

Hm, did your script not work?

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#22 lore raw

Re: [PATCH v8 6/6] MCS Lock: Allow architecture specific asm files to be used for contended case

Quoted 16 lines · Ingo Molnar
Quoted 12 lines · Peter Zijlstra

arch/alpha/include/asm/Kbuild generic-y += clkdev.h · line 7

Quoted 9 lines · Tim Chen
arch/alpha/include/asm/Kbuild +1 -0
index f01fb50..14cbbbc 100644
@@ -4,3 +4,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h

m < p

Quoted 1 line

Hm, did your script not work?

It wasn't used, afaict.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#23 lore raw

Re: [PATCH v8 6/6] MCS Lock: Allow architecture specific asm files to be used for contended case

Quoted 17 lines · Peter Zijlstra
Quoted 16 lines · Ingo Molnar
Quoted 12 lines · Peter Zijlstra

arch/alpha/include/asm/Kbuild generic-y += clkdev.h · line 7

Quoted 9 lines · Tim Chen
arch/alpha/include/asm/Kbuild +1 -0
index f01fb50..14cbbbc 100644
@@ -4,3 +4,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h

m < p

Quoted 3 lines
Quoted 1 line

Hm, did your script not work?

It wasn't used, afaict.

Something to keep in mind for the next version of this series I suspect ;-)

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#24 lore raw

Re: [PATCH v8 6/6] MCS Lock: Allow architecture specific asm files to be used for contended case

In reply to Peter Zijlstra
Quoted 13 lines · Peter Zijlstra

arch/alpha/include/asm/Kbuild generic-y += clkdev.h · line 7

Quoted 9 lines · Tim Chen
arch/alpha/include/asm/Kbuild +1 -0
index f01fb50..14cbbbc 100644
@@ -4,3 +4,4 @@ generic-y += clkdev.h
 generic-y += exec.h
 generic-y += trace_clock.h
 generic-y += preempt.h
+generic-y += mcs_spinlock.h

m < p

Quoted 8 lines

arch/ia64/include/asm/Kbuild generic-y += exec.h · line 7

Quoted 8 lines
arch/ia64/include/asm/Kbuild +0 -1
@@ -4,4 +4,4 @@ generic-y += exec.h
 generic-y += kvm_para.h
 generic-y += trace_clock.h
 generic-y += preempt.h
-generic-y += vtime.h
\ No newline at end of file

The no newline compliant apparently caused by
existing Kbuild file.

Tim

Quoted 8 lines

arch/ia64/include/asm/Kbuild generic-y += exec.h · line 7

Quoted 1 line
arch/ia64/include/asm/Kbuild +1 -0
+generic-y += vtime.hgeneric-y += mcs_spinlock.h

EOL fail
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

#25 lore raw

Re: [PATCH v8 6/6] MCS Lock: Allow architecture specific asm files to be used for contended case

In reply to Tim Chen

Hi,

Quoted 7 lines · On Monday 20 January 2014 17:24:39 Tim Chen wrote:

From: Peter Zijlstra <[email protected]>

This patch allows each architecture to add its specific assembly optimized arch_mcs_spin_lock_contended and arch_mcs_spinlock_uncontended for MCS lock and unlock functions.

Where possible can you try and maintain the sort order in the Kbuild files?

Cheers
James

#26 lore raw

Re: [PATCH v8 6/6] MCS Lock: Allow architecture specific asm files to be used for contended case

Quoted 5 lines · James Hogan

Hi,

Quoted 2 lines · On Monday 20 January 2014 17:24:39 Tim Chen wrote:

From: Peter Zijlstra <[email protected]>

Quoted 7 lines
Quoted 5 lines

This patch allows each architecture to add its specific assembly optimized arch_mcs_spin_lock_contended and arch_mcs_spinlock_uncontended for MCS lock and unlock functions.

Where possible can you try and maintain the sort order in the Kbuild files?

Sorry for the noise, I see this is already taken care of. These emails got filtered funny without any of the replies so I didn't see straight away.

Cheers
James

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>