All of lore.kernel.org
 help / color / mirror / Atom feed
From: Waiman Long <longman@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>, Will Deacon <will@kernel.org>
Cc: linux-kernel@vger.kernel.org, Davidlohr Bueso <dave@stgolabs.net>,
	Phil Auld <pauld@redhat.com>, Waiman Long <longman@redhat.com>
Subject: [PATCH v2 4/5] locking/rwsem: Wake up all waiting readers if RWSEM_WAKE_READ_OWNED
Date: Fri, 20 Nov 2020 23:14:15 -0500	[thread overview]
Message-ID: <20201121041416.12285-5-longman@redhat.com> (raw)
In-Reply-To: <20201121041416.12285-1-longman@redhat.com>

The rwsem wakeup logic has been modified by commit d3681e269fff
("locking/rwsem: Wake up almost all readers in wait queue") to wake up
all readers in the wait queue if the first waiter is a reader. This
change was made to implement a phase-fair reader/writer lock. Once a
reader gets the lock, all the current waiting readers will be allowed
to join. Other readers that come after that will not be allowed to
prevent writer starvation.

In the case of RWSEM_WAKE_READ_OWNED, not all currently waiting readers
can be woken up if the first waiter happens to be a writer. Complete
the phase-fair logic by waking up all readers even for this case.

Signed-off-by: Waiman Long <longman@redhat.com>
---
 kernel/locking/rwsem.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
index b373990fcab8..e0ad2019c518 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -404,6 +404,7 @@ static void rwsem_mark_wake(struct rw_semaphore *sem,
 	struct rwsem_waiter *waiter, *tmp;
 	long oldcount, woken = 0, adjustment = 0;
 	struct list_head wlist;
+	bool first_is_reader = true;
 
 	lockdep_assert_held(&sem->wait_lock);
 
@@ -426,7 +427,13 @@ static void rwsem_mark_wake(struct rw_semaphore *sem,
 			lockevent_inc(rwsem_wake_writer);
 		}
 
-		return;
+		/*
+		 * If rwsem has already been owned by reader, wake up other
+		 * readers in the wait queue even if first one is a writer.
+		 */
+		if (wake_type != RWSEM_WAKE_READ_OWNED)
+			return;
+		first_is_reader = false;
 	}
 
 	/*
@@ -520,10 +527,12 @@ static void rwsem_mark_wake(struct rw_semaphore *sem,
 	}
 
 	/*
-	 * When we've woken a reader, we no longer need to force writers
-	 * to give up the lock and we can clear HANDOFF.
+	 * When readers are woken, we no longer need to force writers to
+	 * give up the lock and we can clear HANDOFF unless the first
+	 * waiter is a writer.
 	 */
-	if (woken && (atomic_long_read(&sem->count) & RWSEM_FLAG_HANDOFF))
+	if (woken && first_is_reader &&
+	   (atomic_long_read(&sem->count) & RWSEM_FLAG_HANDOFF))
 		adjustment -= RWSEM_FLAG_HANDOFF;
 
 	if (adjustment)
@@ -1053,8 +1062,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state, long count)
 	if (rwsem_optimistic_spin(sem, false)) {
 		/* rwsem_optimistic_spin() implies ACQUIRE on success */
 		/*
-		 * Wake up other readers in the wait list if the front
-		 * waiter is a reader.
+		 * Wake up other readers in the wait queue.
 		 */
 wake_readers:
 		if ((atomic_long_read(&sem->count) & RWSEM_FLAG_WAITERS)) {
-- 
2.18.1


  parent reply	other threads:[~2020-11-21  4:14 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: locking/core] " tip-bot2 for Waiman Long
2020-11-21  4:14 ` Waiman Long [this message]
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=20201121041416.12285-5-longman@redhat.com \
    --to=longman@redhat.com \
    --cc=dave@stgolabs.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pauld@redhat.com \
    --cc=peterz@infradead.org \
    --cc=will@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.