mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Michel Lespinasse <walken@google.com>
To: Linus Torvalds <torvalds@linux-foundation.org>,
	David Howells <dhowells@redhat.com>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Ingo Molnar <mingo@kernel.org>, Rik van Riel <riel@redhat.com>,
	Davidlohr Bueso <davidlohr.bueso@hp.com>,
	Peter Hurley <peter@hurleysoftware.com>
Cc: Alex Shi <alex.shi@intel.com>,
	Yuanhan Liu <yuanhan.liu@linux.intel.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	linux-kernel@vger.kernel.org
Subject: [PATCH v3 13/14] x86 rwsem: avoid taking slow path when stealing write lock
Date: Tue,  7 May 2013 06:46:01 -0700	[thread overview]
Message-ID: <1367934362-10433-14-git-send-email-walken@google.com> (raw)
In-Reply-To: <1367934362-10433-1-git-send-email-walken@google.com>

modify __down_write[_nested] and __down_write_trylock to grab the write
lock whenever the active count is 0, even if there are queued waiters
(they must be writers pending wakeup, since the active count is 0).

Note that this is an optimization only; architectures without this
optimization will still work fine:

- __down_write() would take the slow path which would take the wait_lock
  and then try stealing the lock (as in the spinlocked rwsem implementation)

- __down_write_trylock() would fail, but callers must be ready to deal
  with that - since there are some writers pending wakeup, they could
  have raced with us and obtained the lock before we steal it.

Signed-off-by: Michel Lespinasse <walken@google.com>
Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
Acked-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
 arch/x86/include/asm/rwsem.h | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h
index 2dbe4a721ce5..cad82c9c2fde 100644
--- a/arch/x86/include/asm/rwsem.h
+++ b/arch/x86/include/asm/rwsem.h
@@ -105,8 +105,8 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
 	asm volatile("# beginning down_write\n\t"
 		     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
 		     /* adds 0xffff0001, returns the old value */
-		     "  test      %1,%1\n\t"
-		     /* was the count 0 before? */
+		     "  test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t"
+		     /* was the active mask 0 before? */
 		     "  jz        1f\n"
 		     "  call call_rwsem_down_write_failed\n"
 		     "1:\n"
@@ -126,11 +126,25 @@ static inline void __down_write(struct rw_semaphore *sem)
  */
 static inline int __down_write_trylock(struct rw_semaphore *sem)
 {
-	long ret = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
-			   RWSEM_ACTIVE_WRITE_BIAS);
-	if (ret == RWSEM_UNLOCKED_VALUE)
-		return 1;
-	return 0;
+	long result, tmp;
+	asm volatile("# beginning __down_write_trylock\n\t"
+		     "  mov          %0,%1\n\t"
+		     "1:\n\t"
+		     "  test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t"
+		     /* was the active mask 0 before? */
+		     "  jnz          2f\n\t"
+		     "  mov          %1,%2\n\t"
+		     "  add          %3,%2\n\t"
+		     LOCK_PREFIX "  cmpxchg  %2,%0\n\t"
+		     "  jnz	     1b\n\t"
+		     "2:\n\t"
+		     "  sete         %b1\n\t"
+		     "  movzbl       %b1, %k1\n\t"
+		     "# ending __down_write_trylock\n\t"
+		     : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
+		     : "er" (RWSEM_ACTIVE_WRITE_BIAS)
+		     : "memory", "cc");
+	return result;
 }
 
 /*
-- 
1.8.2.1


  parent reply	other threads:[~2013-05-07 13:47 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-07 13:45 [PATCH v3 00/14] rwsem fast-path write lock stealing Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 01/14] rwsem: make the waiter type an enumeration rather than a bitmask Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 02/14] rwsem: shorter spinlocked section in rwsem_down_failed_common() Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 03/14] rwsem: move rwsem_down_failed_common code into rwsem_down_{read,write}_failed Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 04/14] rwsem: simplify rwsem_down_read_failed Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 05/14] rwsem: simplify rwsem_down_write_failed Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 06/14] rwsem: more agressive lock stealing in rwsem_down_write_failed Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 07/14] rwsem: use cmpxchg for trying to steal write lock Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 08/14] rwsem: avoid taking wait_lock in rwsem_down_write_failed Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 09/14] rwsem: skip initial trylock " Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 10/14] rwsem: simplify __rwsem_do_wake Michel Lespinasse
2013-05-07 13:45 ` [PATCH v3 11/14] rwsem: implement support for write lock stealing on the fastpath Michel Lespinasse
2013-05-07 13:46 ` [PATCH v3 12/14] rwsem: do not block readers at head of queue if other readers are active Michel Lespinasse
2013-05-07 13:46 ` Michel Lespinasse [this message]
2013-05-07 13:46 ` [PATCH v3 14/14] rwsem: no need for explicit signed longs Michel Lespinasse
2013-05-07 22:39 ` [PATCH v3 15/14] rwsem: check counter to avoid cmpxchg calls Davidlohr Bueso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1367934362-10433-14-git-send-email-walken@google.com \
    --to=walken@google.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=alex.shi@intel.com \
    --cc=davidlohr.bueso@hp.com \
    --cc=dhowells@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peter@hurleysoftware.com \
    --cc=riel@redhat.com \
    --cc=torvalds@linux-foundation.org \
    --cc=yuanhan.liu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®