mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [GIT PULL] ticketlock + cmpxchg cleanups
@ 2011-08-29 17:28 Jeremy Fitzhardinge
  2011-08-30  5:22 ` [tip:x86/spinlocks] x86, cmpxchg: <linux/alternative.h> has LOCK_PREFIX tip-bot for Jeremy Fitzhardinge
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Jeremy Fitzhardinge @ 2011-08-29 17:28 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Linux Kernel Mailing List, xen-devel

Hi,

This is the final version of the ticketlock+cmpxchg series.  I dropped
the cmpxchg_flag() stuff, since it is not a clear win and not really
germane to the rest of the series.

Thanks,
    J

The following changes since commit 61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf:

  Linux 2.6.39 (2011-05-18 21:06:34 -0700)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git upstream/ticketlock-cleanup

Jeremy Fitzhardinge (10):
      x86/cmpxchg: linux/alternative.h has LOCK_PREFIX
      x86/cmpxchg: move 32-bit __cmpxchg_wrong_size to match 64 bit.
      x86/cmpxchg: move 64-bit set64_bit() to match 32-bit
      x86/cmpxchg: unify cmpxchg into cmpxchg.h
      x86: add xadd helper macro
      x86: use xadd helper more widely
      x86/ticketlock: clean up types and accessors
      x86/ticketlock: convert spin loop to C
      x86/ticketlock: convert __ticket_spin_lock to use xadd()
      x86/ticketlock: make __ticket_spin_trylock common

 arch/x86/include/asm/atomic.h         |    8 +-
 arch/x86/include/asm/atomic64_64.h    |    6 +-
 arch/x86/include/asm/cmpxchg.h        |  198 +++++++++++++++++++++++++++++++++
 arch/x86/include/asm/cmpxchg_32.h     |  114 -------------------
 arch/x86/include/asm/cmpxchg_64.h     |  131 ----------------------
 arch/x86/include/asm/rwsem.h          |    8 +-
 arch/x86/include/asm/spinlock.h       |  110 +++++--------------
 arch/x86/include/asm/spinlock_types.h |   22 ++++-
 arch/x86/include/asm/uv/uv_bau.h      |    6 +-
 9 files changed, 250 insertions(+), 353 deletions(-)



^ permalink raw reply	[flat|nested] 13+ messages in thread
* [PATCH 2/8] x86/ticketlock: convert spin loop to C
@ 2011-06-24  1:19 Jeremy Fitzhardinge
  2011-07-22 19:55 ` [tip:x86/spinlocks] x86, ticketlock: Convert " tip-bot for Jeremy Fitzhardinge
  0 siblings, 1 reply; 13+ messages in thread
From: Jeremy Fitzhardinge @ 2011-06-24  1:19 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Linus Torvalds, H. Peter Anvin, Ingo Molnar,
	the arch/x86 maintainers, Linux Kernel Mailing List, Nick Piggin,
	Jeremy Fitzhardinge

From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>

The inner loop of __ticket_spin_lock isn't doing anything very special,
so reimplement it in C.

For the 8 bit ticket lock variant, we use a register union to get direct
access to the lower and upper bytes in the tickets, but unfortunately gcc
won't generate a direct comparison between the two halves of the register,
so the generated asm isn't quite as pretty as the hand-coded version.
However benchmarking shows that this is actually a small improvement in
runtime performance on some benchmarks, and never a slowdown.

We also need to make sure there's a barrier at the end of the lock loop
to make sure that the compiler doesn't move any instructions from within
the locked region into the region where we don't yet own the lock.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
---
 arch/x86/include/asm/spinlock.h |   58 +++++++++++++++++++-------------------
 1 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
index d6d5784..f48a6e3 100644
--- a/arch/x86/include/asm/spinlock.h
+++ b/arch/x86/include/asm/spinlock.h
@@ -58,21 +58,21 @@
 #if (NR_CPUS < 256)
 static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
 {
-	unsigned short inc = 1 << TICKET_SHIFT;
-
-	asm volatile (
-		LOCK_PREFIX "xaddw %w0, %1\n"
-		"1:\t"
-		"cmpb %h0, %b0\n\t"
-		"je 2f\n\t"
-		"rep ; nop\n\t"
-		"movb %1, %b0\n\t"
-		/* don't need lfence here, because loads are in-order */
-		"jmp 1b\n"
-		"2:"
-		: "+Q" (inc), "+m" (lock->slock)
-		:
-		: "memory", "cc");
+	register union {
+		struct __raw_tickets tickets;
+		unsigned short slock;
+	} inc = { .slock = 1 << TICKET_SHIFT };
+
+	asm volatile (LOCK_PREFIX "xaddw %w0, %1\n"
+		      : "+Q" (inc), "+m" (lock->slock) : : "memory", "cc");
+
+	for (;;) {
+		if (inc.tickets.head == inc.tickets.tail)
+			goto out;
+		cpu_relax();
+		inc.tickets.head = ACCESS_ONCE(lock->tickets.head);
+	}
+out:	barrier();		/* make sure nothing creeps before the lock is taken */
 }
 
 static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
@@ -105,22 +105,22 @@ static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
 static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
 {
 	unsigned inc = 1 << TICKET_SHIFT;
-	unsigned tmp;
+	__ticket_t tmp;
 
-	asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
-		     "movzwl %w0, %2\n\t"
-		     "shrl $16, %0\n\t"
-		     "1:\t"
-		     "cmpl %0, %2\n\t"
-		     "je 2f\n\t"
-		     "rep ; nop\n\t"
-		     "movzwl %1, %2\n\t"
-		     /* don't need lfence here, because loads are in-order */
-		     "jmp 1b\n"
-		     "2:"
-		     : "+r" (inc), "+m" (lock->slock), "=&r" (tmp)
-		     :
-		     : "memory", "cc");
+	asm volatile(LOCK_PREFIX "xaddl %0, %1\n\t"
+		     : "+r" (inc), "+m" (lock->slock)
+		     : : "memory", "cc");
+
+	tmp = inc;
+	inc >>= TICKET_SHIFT;
+
+	for (;;) {
+		if ((__ticket_t)inc == tmp)
+			goto out;
+		cpu_relax();
+		tmp = ACCESS_ONCE(lock->tickets.head);
+	}
+out:	barrier();		/* make sure nothing creeps before the lock is taken */
 }
 
 static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-08-30  5:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-29 17:28 [GIT PULL] ticketlock + cmpxchg cleanups Jeremy Fitzhardinge
2011-08-30  5:22 ` [tip:x86/spinlocks] x86, cmpxchg: <linux/alternative.h> has LOCK_PREFIX tip-bot for Jeremy Fitzhardinge
2011-08-30  5:22 ` [tip:x86/spinlocks] x86, cmpxchg: Move 32-bit __cmpxchg_wrong_size to match 64 bit tip-bot for Jeremy Fitzhardinge
2011-08-30  5:23 ` [tip:x86/spinlocks] x86, cmpxchg: Move 64-bit set64_bit() to match 32-bit tip-bot for Jeremy Fitzhardinge
2011-08-30  5:23 ` [tip:x86/spinlocks] x86, cmpxchg: Unify cmpxchg into cmpxchg.h tip-bot for Jeremy Fitzhardinge
2011-08-30  5:24 ` [tip:x86/spinlocks] x86: Add xadd helper macro tip-bot for Jeremy Fitzhardinge
2011-08-30  5:24 ` [tip:x86/spinlocks] x86: Use xadd helper more widely tip-bot for Jeremy Fitzhardinge
2011-08-30  5:25 ` [tip:x86/spinlocks] x86, ticketlock: Clean up types and accessors tip-bot for Jeremy Fitzhardinge
2011-08-30  5:25 ` [tip:x86/spinlocks] x86, ticketlock: Convert spin loop to C tip-bot for Jeremy Fitzhardinge
2011-08-30  5:26 ` [tip:x86/spinlocks] x86, ticketlock: Convert __ticket_spin_lock to use xadd() tip-bot for Jeremy Fitzhardinge
2011-08-30  5:26 ` [tip:x86/spinlocks] x86, ticketlock: Make __ticket_spin_trylock common tip-bot for Jeremy Fitzhardinge
2011-08-30  5:27 ` [tip:x86/spinlocks] x86, cmpxchg: Use __compiletime_error() to make usage messages a bit nicer tip-bot for Jeremy Fitzhardinge
  -- strict thread matches above, loose matches on Subject: below --
2011-06-24  1:19 [PATCH 2/8] x86/ticketlock: convert spin loop to C Jeremy Fitzhardinge
2011-07-22 19:55 ` [tip:x86/spinlocks] x86, ticketlock: Convert " tip-bot for Jeremy Fitzhardinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome