From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Jordan Niethe <jniethe5@gmail.com>,
Laurent Dufour <laurent.dufour@fr.ibm.com>,
Nicholas Piggin <npiggin@gmail.com>
Subject: [RFC PATCH 3/4] powerpc/qspinlock: Remove !maybe_waiters special case queue head locking
Date: Tue, 15 Nov 2022 02:11:18 +1000 [thread overview]
Message-ID: <20221114161119.2883620-4-npiggin@gmail.com> (raw)
In-Reply-To: <20221114161119.2883620-1-npiggin@gmail.com>
With the update primitive that clears the tail if it matches, and is
tolerant of other queueing activity on the lock, there is no longer a
significant reason to keep the large !maybe_stealers special case, so
remove it.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/lib/qspinlock.c | 124 +++++++++++++++--------------------
1 file changed, 53 insertions(+), 71 deletions(-)
diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
index 79793b3209ea..457e748b0078 100644
--- a/arch/powerpc/lib/qspinlock.c
+++ b/arch/powerpc/lib/qspinlock.c
@@ -523,7 +523,11 @@ static __always_inline void queued_spin_lock_mcs_queue(struct qspinlock *lock, b
struct qnode *next, *node;
u32 val, old, tail;
bool seen_preempted = false;
+ bool sleepy = false;
+ bool mustq = false;
int idx;
+ int set_yield_cpu = -1;
+ int iters = 0;
BUILD_BUG_ON(CONFIG_NR_CPUS >= (1U << _Q_TAIL_CPU_BITS));
@@ -577,90 +581,68 @@ static __always_inline void queued_spin_lock_mcs_queue(struct qspinlock *lock, b
smp_rmb(); /* acquire barrier for the mcs lock */
}
- if (!maybe_stealers) {
- int set_yield_cpu = -1;
-
- /* We're at the head of the waitqueue, wait for the lock. */
- spin_begin();
- for (;;) {
- val = READ_ONCE(lock->val);
- if (!(val & _Q_LOCKED_VAL))
- break;
-
- propagate_yield_cpu(node, val, &set_yield_cpu, paravirt);
- if (yield_head_to_locked_owner(lock, val, paravirt))
- seen_preempted = true;
- }
- spin_end();
-
- /* If we're the last queued, must clean up the tail. */
- old = trylock_clear_my_tail(lock, tail);
- BUG_ON(old & _Q_LOCKED_VAL);
- if ((old & _Q_TAIL_CPU_MASK) == tail)
- goto release;
-
- } else {
- int set_yield_cpu = -1;
- int iters = 0;
- bool sleepy = false;
- bool mustq = false;
+ /* We're at the head of the waitqueue, wait for the lock. */
+again:
+ spin_begin();
+ for (;;) {
bool preempted;
-again:
- /* We're at the head of the waitqueue, wait for the lock. */
- spin_begin();
- for (;;) {
- val = READ_ONCE(lock->val);
- if (!(val & _Q_LOCKED_VAL))
- break;
-
- if (paravirt && pv_sleepy_lock) {
- if (!sleepy) {
- if (val & _Q_SLEEPY_VAL) {
- seen_sleepy_lock();
- sleepy = true;
- } else if (recently_sleepy()) {
- sleepy = true;
- }
- }
- if (pv_sleepy_lock_sticky && seen_preempted &&
- !(val & _Q_SLEEPY_VAL)) {
- if (try_set_sleepy(lock, val))
- val |= _Q_SLEEPY_VAL;
+ val = READ_ONCE(lock->val);
+ if (!(val & _Q_LOCKED_VAL))
+ break;
+
+ if (paravirt && pv_sleepy_lock && maybe_stealers) {
+ if (!sleepy) {
+ if (val & _Q_SLEEPY_VAL) {
+ seen_sleepy_lock();
+ sleepy = true;
+ } else if (recently_sleepy()) {
+ sleepy = true;
}
}
+ if (pv_sleepy_lock_sticky && seen_preempted &&
+ !(val & _Q_SLEEPY_VAL)) {
+ if (try_set_sleepy(lock, val))
+ val |= _Q_SLEEPY_VAL;
+ }
+ }
- propagate_yield_cpu(node, val, &set_yield_cpu, paravirt);
- preempted = yield_head_to_locked_owner(lock, val, paravirt);
- if (preempted)
- seen_preempted = true;
+ propagate_yield_cpu(node, val, &set_yield_cpu, paravirt);
+ preempted = yield_head_to_locked_owner(lock, val, paravirt);
+ if (!maybe_stealers)
+ continue;
+
+ if (preempted)
+ seen_preempted = true;
- if (paravirt && preempted) {
- sleepy = true;
+ if (paravirt && preempted) {
+ sleepy = true;
- if (!pv_spin_on_preempted_owner)
- iters++;
- } else {
+ if (!pv_spin_on_preempted_owner)
iters++;
- }
+ } else {
+ iters++;
+ }
- if (!mustq && iters >= get_head_spins(paravirt, sleepy)) {
- mustq = true;
- set_mustq(lock);
- val |= _Q_MUST_Q_VAL;
- }
+ if (!mustq && iters >= get_head_spins(paravirt, sleepy)) {
+ mustq = true;
+ set_mustq(lock);
+ val |= _Q_MUST_Q_VAL;
}
- spin_end();
+ }
+ spin_end();
- /* If we're the last queued, must clean up the tail. */
- old = trylock_clear_my_tail(lock, tail);
- if (unlikely(old & _Q_LOCKED_VAL))
- goto again;
- if ((old & _Q_TAIL_CPU_MASK) == tail)
- goto release;
+ /* If we're the last queued, must clean up the tail. */
+ old = trylock_clear_my_tail(lock, tail);
+ if (unlikely(old & _Q_LOCKED_VAL)) {
+ BUG_ON(!maybe_stealers);
+ goto again; /* Can only be true if maybe_stealers. */
}
- /* contended path; must wait for next != NULL (MCS protocol) */
+ if ((old & _Q_TAIL_CPU_MASK) == tail)
+ goto release; /* We were the tail, no next. */
+
+ /* There is a next, must wait for node->next != NULL (MCS protocol) */
next = READ_ONCE(node->next);
if (!next) {
spin_begin();
--
2.37.2
next prev parent reply other threads:[~2022-11-14 16:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-14 16:11 [RFC PATCH 0/4] powerpc/qspinlock: make slowpath accesses more efficient Nicholas Piggin
2022-11-14 16:11 ` [RFC PATCH 1/4] powerpc/qspinlock: Avoid cmpxchg pattern in lock stealing Nicholas Piggin
2022-11-14 16:11 ` [RFC PATCH 2/4] powerpc/qspinlock: Avoid cmpxchg style patterns in queue head locking Nicholas Piggin
2022-11-14 16:11 ` Nicholas Piggin [this message]
2022-11-14 16:11 ` [RFC PATCH 4/4] powerpc/qspinlock: add compile-time tuning adjustments Nicholas Piggin
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=20221114161119.2883620-4-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=jniethe5@gmail.com \
--cc=laurent.dufour@fr.ibm.com \
--cc=linuxppc-dev@lists.ozlabs.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).