tile: modify arch_spin_unlock_wait() semantics
authorChris Metcalf <cmetcalf@ezchip.com>
Tue, 28 Apr 2015 17:02:26 +0000 (13:02 -0400)
committerChris Metcalf <cmetcalf@ezchip.com>
Wed, 29 Apr 2015 02:43:13 +0000 (22:43 -0400)
Rather than trying to wait until all possible lockers have
unlocked the lock, we now only wait until the current locker
(if any) has released the lock.

The old code was correct, but the new code works more like the x86
code and thus hopefully is more appropriate under contention.
See commit 78bff1c8684f ("x86/ticketlock: Fix spin_unlock_wait()
livelock") for x86.

Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
arch/tile/lib/spinlock_32.c
arch/tile/lib/spinlock_64.c

index b34f79aada48efca7a1b350894f0dd7f4b98a7f4..88c2a53362e738110913134b840e1abe01df9fd9 100644 (file)
@@ -65,8 +65,17 @@ EXPORT_SYMBOL(arch_spin_trylock);
 void arch_spin_unlock_wait(arch_spinlock_t *lock)
 {
        u32 iterations = 0;
-       while (arch_spin_is_locked(lock))
+       int curr = READ_ONCE(lock->current_ticket);
+       int next = READ_ONCE(lock->next_ticket);
+
+       /* Return immediately if unlocked. */
+       if (next == curr)
+               return;
+
+       /* Wait until the current locker has released the lock. */
+       do {
                delay_backoff(iterations++);
+       } while (READ_ONCE(lock->current_ticket) == curr);
 }
 EXPORT_SYMBOL(arch_spin_unlock_wait);
 
index d6fb9581e980c67c54c8f8f4aad238827e41c083..c8d1f94ff1fe00e13f30a6c0e3ae51563a3226fa 100644 (file)
@@ -65,8 +65,17 @@ EXPORT_SYMBOL(arch_spin_trylock);
 void arch_spin_unlock_wait(arch_spinlock_t *lock)
 {
        u32 iterations = 0;
-       while (arch_spin_is_locked(lock))
+       u32 val = READ_ONCE(lock->lock);
+       u32 curr = arch_spin_current(val);
+
+       /* Return immediately if unlocked. */
+       if (arch_spin_next(val) == curr)
+               return;
+
+       /* Wait until the current locker has released the lock. */
+       do {
                delay_backoff(iterations++);
+       } while (arch_spin_current(READ_ONCE(lock->lock)) == curr);
 }
 EXPORT_SYMBOL(arch_spin_unlock_wait);
 
This page took 0.028877 seconds and 5 git commands to generate.