]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
powerpc/qspinlock: Propagate sleepy if previous waiter is preempted
authorNicholas Piggin <npiggin@gmail.com>
Mon, 16 Oct 2023 12:43:04 +0000 (22:43 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 20 Oct 2023 11:43:34 +0000 (22:43 +1100)
The sleepy (aka lock-owner-is-preempted) condition is propagated down
the queue by each waiter. If a waiter becomes preempted, it can no
longer propagate sleepy. To allow subsequent waiters to yield to the
lock owner, also check the lock owner in this case.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Tested-by: Shrikanth Hegde <sshegde@linux.vnet.ibm.com>
Reviewed-by: "Nysal Jan K.A" <nysal@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20231016124305.139923-6-npiggin@gmail.com
arch/powerpc/lib/qspinlock.c

index 6bb627e90a321ee8dae7d0cdb84e9947d518f9dd..c68c2bd7b853450430437e3b539b49f5ee390a68 100644 (file)
@@ -384,7 +384,11 @@ static __always_inline bool yield_to_prev(struct qspinlock *lock, struct qnode *
        if (!pv_yield_propagate_owner)
                goto yield_prev;
 
-       if (node->sleepy) {
+       /*
+        * If the previous waiter was preempted it might not be able to
+        * propagate sleepy to us, so check the lock in that case too.
+        */
+       if (node->sleepy || vcpu_is_preempted(prev_cpu)) {
                u32 val = READ_ONCE(lock->val);
 
                if (val & _Q_LOCKED_VAL) {