linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "tip-bot2 for Waiman Long" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Waiman Long <longman@redhat.com>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Davidlohr Bueso <dbueso@suse.de>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: locking/core] locking/rwsem: Enable reader optimistic lock stealing
Date: Wed, 09 Dec 2020 18:38:47 -0000	[thread overview]
Message-ID: <160753912756.3364.6893166069488987740.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20201121041416.12285-4-longman@redhat.com>

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     1a728dff855a318bb58bcc1259b1826a7ad9f0bd
Gitweb:        https://git.kernel.org/tip/1a728dff855a318bb58bcc1259b1826a7ad9f0bd
Author:        Waiman Long <longman@redhat.com>
AuthorDate:    Fri, 20 Nov 2020 23:14:14 -05:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 09 Dec 2020 17:08:48 +01:00

locking/rwsem: Enable reader optimistic lock stealing

If the optimistic spinning queue is empty and the rwsem does not have
the handoff or write-lock bits set, it is actually not necessary to
call rwsem_optimistic_spin() to spin on it. Instead, it can steal the
lock directly as its reader bias is in the count already.  If it is
the first reader in this state, it will try to wake up other readers
in the wait queue.

With this patch applied, the following were the lock event counts
after rebooting a 2-socket system and a "make -j96" kernel rebuild.

  rwsem_opt_rlock=4437
  rwsem_rlock=29
  rwsem_rlock_steal=19

So lock stealing represents about 0.4% of all the read locks acquired
in the slow path.

Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Davidlohr Bueso <dbueso@suse.de>
Link: https://lkml.kernel.org/r/20201121041416.12285-4-longman@redhat.com
---
 kernel/locking/lock_events_list.h |  1 +
 kernel/locking/rwsem.c            | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/kernel/locking/lock_events_list.h b/kernel/locking/lock_events_list.h
index 239039d..270a0d3 100644
--- a/kernel/locking/lock_events_list.h
+++ b/kernel/locking/lock_events_list.h
@@ -63,6 +63,7 @@ LOCK_EVENT(rwsem_opt_nospin)	/* # of disabled optspins		*/
 LOCK_EVENT(rwsem_opt_norspin)	/* # of disabled reader-only optspins	*/
 LOCK_EVENT(rwsem_opt_rlock2)	/* # of opt-acquired 2ndary read locks	*/
 LOCK_EVENT(rwsem_rlock)		/* # of read locks acquired		*/
+LOCK_EVENT(rwsem_rlock_steal)	/* # of read locks by lock stealing	*/
 LOCK_EVENT(rwsem_rlock_fast)	/* # of fast read locks acquired	*/
 LOCK_EVENT(rwsem_rlock_fail)	/* # of failed read lock acquisitions	*/
 LOCK_EVENT(rwsem_rlock_handoff)	/* # of read lock handoffs		*/
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
index c055f4b..ba5e239 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -976,6 +976,12 @@ static inline bool rwsem_reader_phase_trylock(struct rw_semaphore *sem,
 	}
 	return false;
 }
+
+static inline bool rwsem_no_spinners(struct rw_semaphore *sem)
+{
+	return !osq_is_locked(&sem->osq);
+}
+
 #else
 static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem,
 					   unsigned long nonspinnable)
@@ -996,6 +1002,11 @@ static inline bool rwsem_reader_phase_trylock(struct rw_semaphore *sem,
 	return false;
 }
 
+static inline bool rwsem_no_spinners(sem)
+{
+	return false;
+}
+
 static inline int
 rwsem_spin_on_owner(struct rw_semaphore *sem, unsigned long nonspinnable)
 {
@@ -1027,6 +1038,22 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, int state)
 		goto queue;
 
 	/*
+	 * Reader optimistic lock stealing
+	 *
+	 * We can take the read lock directly without doing
+	 * rwsem_optimistic_spin() if the conditions are right.
+	 * Also wake up other readers if it is the first reader.
+	 */
+	if (!(count & (RWSEM_WRITER_LOCKED | RWSEM_FLAG_HANDOFF)) &&
+	    rwsem_no_spinners(sem)) {
+		rwsem_set_reader_owned(sem);
+		lockevent_inc(rwsem_rlock_steal);
+		if (rcnt == 1)
+			goto wake_readers;
+		return sem;
+	}
+
+	/*
 	 * Save the current read-owner of rwsem, if available, and the
 	 * reader nonspinnable bit.
 	 */
@@ -1048,6 +1075,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, int state)
 		 * Wake up other readers in the wait list if the front
 		 * waiter is a reader.
 		 */
+wake_readers:
 		if ((atomic_long_read(&sem->count) & RWSEM_FLAG_WAITERS)) {
 			raw_spin_lock_irq(&sem->wait_lock);
 			if (!list_empty(&sem->wait_list))

  reply	other threads:[~2020-12-09 18:43 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-21  4:14 [PATCH v2 0/5] locking/rwsem: Rework reader optimistic spinning Waiman Long
2020-11-21  4:14 ` [PATCH v2 1/5] locking/rwsem: Pass the current atomic count to rwsem_down_read_slowpath() Waiman Long
2020-12-09 18:38   ` [tip: locking/core] " tip-bot2 for Waiman Long
2020-11-21  4:14 ` [PATCH v2 2/5] locking/rwsem: Prevent potential lock starvation Waiman Long
2020-11-26  8:12   ` [locking/rwsem] 25d0c60b0e: vm-scalability.throughput 316.2% improvement kernel test robot
2020-12-09 18:38   ` [tip: locking/core] locking/rwsem: Prevent potential lock starvation tip-bot2 for Waiman Long
2020-11-21  4:14 ` [PATCH v2 3/5] locking/rwsem: Enable reader optimistic lock stealing Waiman Long
2020-12-09 18:38   ` tip-bot2 for Waiman Long [this message]
2020-11-21  4:14 ` [PATCH v2 4/5] locking/rwsem: Wake up all waiting readers if RWSEM_WAKE_READ_OWNED Waiman Long
2020-11-24  3:15   ` [locking/rwsem] c9847a7f94: aim7.jobs-per-min -91.8% regression kernel test robot
2020-11-21  4:14 ` [PATCH v2 5/5] locking/rwsem: Remove reader optimistic spinning Waiman Long
2020-11-23 15:53   ` [locking/rwsem] 10a59003d2: unixbench.score -25.5% regression kernel test robot
2020-11-23 19:28     ` Waiman Long
2020-12-08  3:56   ` [PATCH v2 5/5] locking/rwsem: Remove reader optimistic spinning Davidlohr Bueso
2020-12-08 10:07   ` Peter Zijlstra
2020-12-08 15:29     ` Waiman Long
2020-12-09 18:38   ` [tip: locking/core] " tip-bot2 for Waiman Long
2020-12-08 14:57 ` [PATCH v2 0/5] locking/rwsem: Rework " Peter Zijlstra
2020-12-08 16:33   ` Waiman Long
2020-12-08 17:02     ` Peter Zijlstra
2020-12-08 17:30       ` Waiman Long

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=160753912756.3364.6893166069488987740.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=dbueso@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=peterz@infradead.org \
    --cc=x86@kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).