From: Hillf Danton <hdanton@sina.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: "Waiman Long" <longman@redhat.com>,
"Ingo Molnar" <mingo@redhat.com>, "Will Deacon" <will@kernel.org>,
"Boqun Feng" <boqun.feng@gmail.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
john.p.donnelly@oracle.com,
"Mukesh Ojha" <quic_mojha@quicinc.com>,
"Ting11 Wang 王婷" <wangting11@xiaomi.com>
Subject: Re: [PATCH v2 1/2] locking/rwsem: Prevent non-first waiter from spinning in down_write() slowpath
Date: Fri, 14 Oct 2022 08:21:42 +0800 [thread overview]
Message-ID: <20221014002142.275-1-hdanton@sina.com> (raw)
In-Reply-To: <20221013131505.212-1-hdanton@sina.com>
On 13 Oct 2022 21:15:05 +0800 Hillf Danton <hdanton@sina.com>
> On 13 Oct 2022 12:02:09 +0200 Peter Zijlstra <peterz@infradead.org>
> > On Wed, Oct 12, 2022 at 09:33:32AM -0400, Waiman Long wrote:
> > > It is especially problematic if the non-first waiter is an RT task and
> > > it is running on the same CPU as the first waiter as this can lead to
> > > live lock.
> > >
> > So why not do a better handoff? Specifically, have the owner set owner
> > to first-waiter instead of NULL ? (like the normal mutex code)
>
> Given a simple coding of "better handoff", with care to avoid change added
> to fast path, I see no bonus except for preventing non-first waiters from
> spinning.
Spin with a line in fast path cut.
Prevent non-first waiters from spinning too much by 1) not clearing lock owner
before releasing rwsem because new acquirer will set it and 2) setting owner
to the first waiter instead while waking lock waiters up in bid to force
non-first spinners to take a break.
Note, first waiter spinning longer than thought still makes trouble but it
is not addressed here because of known cure.
Hillf
+++ b/kernel/locking/rwsem.c
@@ -429,6 +429,7 @@ static void rwsem_mark_wake(struct rw_se
if (waiter->type == RWSEM_WAITING_FOR_WRITE) {
if (wake_type == RWSEM_WAKE_ANY) {
+ atomic_long_set(&sem->owner, (long)waiter->task);
/*
* Mark writer at the front of the queue for wakeup.
* Until the task is actually later awoken later by
@@ -752,7 +753,7 @@ rwsem_owner_state(struct task_struct *ow
static noinline enum owner_state
rwsem_spin_on_owner(struct rw_semaphore *sem)
{
- struct task_struct *new, *owner;
+ struct task_struct *new, *owner, *me = current;
unsigned long flags, new_flags;
enum owner_state state;
@@ -762,6 +763,8 @@ rwsem_spin_on_owner(struct rw_semaphore
state = rwsem_owner_state(owner, flags);
if (state != OWNER_WRITER)
return state;
+ if (owner == me)
+ return OWNER_NULL;
for (;;) {
/*
@@ -772,7 +775,10 @@ rwsem_spin_on_owner(struct rw_semaphore
*/
new = rwsem_owner_flags(sem, &new_flags);
if ((new != owner) || (new_flags != flags)) {
- state = rwsem_owner_state(new, new_flags);
+ if (new == me)
+ state = OWNER_NULL;
+ else
+ state = rwsem_owner_state(new, new_flags);
break;
}
@@ -1360,10 +1366,7 @@ static inline void __up_write(struct rw_
DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) &&
!rwsem_test_oflags(sem, RWSEM_NONSPINNABLE), sem);
- preempt_disable();
- rwsem_clear_owner(sem);
tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count);
- preempt_enable();
if (unlikely(tmp & RWSEM_FLAG_WAITERS))
rwsem_wake(sem);
}
prev parent reply other threads:[~2022-10-14 0:22 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Y0fiIdxA+Jip1vve@hirez.programming.kicks-ass.net>
2022-10-13 13:15 ` Hillf Danton
2022-10-14 0:21 ` Hillf Danton [this message]
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=20221014002142.275-1-hdanton@sina.com \
--to=hdanton@sina.com \
--cc=boqun.feng@gmail.com \
--cc=john.p.donnelly@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=longman@redhat.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=quic_mojha@quicinc.com \
--cc=wangting11@xiaomi.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox