summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorHisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp>2008-01-26 14:11:28 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-01-26 14:11:31 +0100
commit894cdde26b538c77b9943bc72f0570abf6e58e37 (patch)
tree335f75460bd947c4969c9b7a1ec5764b98bf1d2b /arch/s390
parentdab5209cd878c146d9f6923f061d1c2725ff210f (diff)
downloadlinux-894cdde26b538c77b9943bc72f0570abf6e58e37.tar.gz
linux-894cdde26b538c77b9943bc72f0570abf6e58e37.tar.bz2
linux-894cdde26b538c77b9943bc72f0570abf6e58e37.zip
[S390] do local_irq_restore while spinning in spin_lock_irqsave.
In s390's spin_lock_irqsave, interrupts remain disabled while spinning. In other architectures like x86 and powerpc, interrupts are re-enabled while spinning if IRQ is not masked before spin_lock_irqsave is called. The following patch re-enables interrupts through local_irq_restore while spinning for a lock acquisition. This can improve system response. [heiko.carstens@de.ibm.com: removed saving of pc] Signed-off-by: Hisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/lib/spinlock.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 59c56c3d72d0..e41f4008afc5 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -59,6 +59,29 @@ void _raw_spin_lock_wait(raw_spinlock_t *lp)
}
EXPORT_SYMBOL(_raw_spin_lock_wait);
+void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags)
+{
+ int count = spin_retry;
+ unsigned int cpu = ~smp_processor_id();
+
+ local_irq_restore(flags);
+ while (1) {
+ if (count-- <= 0) {
+ unsigned int owner = lp->owner_cpu;
+ if (owner != 0)
+ _raw_yield_cpu(~owner);
+ count = spin_retry;
+ }
+ if (__raw_spin_is_locked(lp))
+ continue;
+ local_irq_disable();
+ if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
+ return;
+ local_irq_restore(flags);
+ }
+}
+EXPORT_SYMBOL(_raw_spin_lock_wait_flags);
+
int _raw_spin_trylock_retry(raw_spinlock_t *lp)
{
unsigned int cpu = ~smp_processor_id();