Skip to content

Commit

Permalink
s390/spinlock: refactor arch_spin_lock_wait[_flags]
Browse files Browse the repository at this point in the history
Reorder the spinlock wait code to make it more readable.

Signed-off-by: Martin Schwidefsky <[email protected]>
  • Loading branch information
Martin Schwidefsky committed May 20, 2014
1 parent 939c5ae commit 470ada6
Showing 1 changed file with 47 additions and 34 deletions.
81 changes: 47 additions & 34 deletions arch/s390/lib/spinlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,31 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
int count;

while (1) {
owner = lp->lock;
if (!owner || smp_vcpu_scheduled(~owner)) {
count = spin_retry;
do {
if (arch_spin_is_locked(lp))
continue;
if (_raw_compare_and_swap(&lp->lock, 0, cpu))
return;
} while (count-- > 0);
if (MACHINE_IS_LPAR)
continue;
owner = ACCESS_ONCE(lp->lock);
/* Try to get the lock if it is free. */
if (!owner) {
if (_raw_compare_and_swap(&lp->lock, 0, cpu))
return;
continue;
}
owner = lp->lock;
if (owner)
/* Check if the lock owner is running. */
if (!smp_vcpu_scheduled(~owner)) {
smp_yield_cpu(~owner);
continue;
}
/* Loop for a while on the lock value. */
count = spin_retry;
do {
owner = ACCESS_ONCE(lp->lock);
} while (owner && count-- > 0);
if (!owner)
continue;
/*
* For multiple layers of hypervisors, e.g. z/VM + LPAR
* yield the CPU if the lock is still unavailable.
*/
if (!MACHINE_IS_LPAR)
smp_yield_cpu(~owner);
if (_raw_compare_and_swap(&lp->lock, 0, cpu))
return;
}
}
EXPORT_SYMBOL(arch_spin_lock_wait);
Expand All @@ -60,27 +68,32 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)

local_irq_restore(flags);
while (1) {
owner = lp->lock;
if (!owner || smp_vcpu_scheduled(~owner)) {
count = spin_retry;
do {
if (arch_spin_is_locked(lp))
continue;
local_irq_disable();
if (_raw_compare_and_swap(&lp->lock, 0, cpu))
return;
local_irq_restore(flags);
} while (count-- > 0);
if (MACHINE_IS_LPAR)
continue;
owner = ACCESS_ONCE(lp->lock);
/* Try to get the lock if it is free. */
if (!owner) {
local_irq_disable();
if (_raw_compare_and_swap(&lp->lock, 0, cpu))
return;
local_irq_restore(flags);
}
owner = lp->lock;
if (owner)
/* Check if the lock owner is running. */
if (!smp_vcpu_scheduled(~owner)) {
smp_yield_cpu(~owner);
continue;
}
/* Loop for a while on the lock value. */
count = spin_retry;
do {
owner = ACCESS_ONCE(lp->lock);
} while (owner && count-- > 0);
if (!owner)
continue;
/*
* For multiple layers of hypervisors, e.g. z/VM + LPAR
* yield the CPU if the lock is still unavailable.
*/
if (!MACHINE_IS_LPAR)
smp_yield_cpu(~owner);
local_irq_disable();
if (_raw_compare_and_swap(&lp->lock, 0, cpu))
return;
local_irq_restore(flags);
}
}
EXPORT_SYMBOL(arch_spin_lock_wait_flags);
Expand Down

0 comments on commit 470ada6

Please sign in to comment.