diff options
-rw-r--r-- | arch/s390/lib/spinlock.c | 23 | ||||
-rw-r--r-- | include/asm-s390/spinlock.h | 13 |
2 files changed, 35 insertions, 1 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) | |||
59 | } | 59 | } |
60 | EXPORT_SYMBOL(_raw_spin_lock_wait); | 60 | EXPORT_SYMBOL(_raw_spin_lock_wait); |
61 | 61 | ||
62 | void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags) | ||
63 | { | ||
64 | int count = spin_retry; | ||
65 | unsigned int cpu = ~smp_processor_id(); | ||
66 | |||
67 | local_irq_restore(flags); | ||
68 | while (1) { | ||
69 | if (count-- <= 0) { | ||
70 | unsigned int owner = lp->owner_cpu; | ||
71 | if (owner != 0) | ||
72 | _raw_yield_cpu(~owner); | ||
73 | count = spin_retry; | ||
74 | } | ||
75 | if (__raw_spin_is_locked(lp)) | ||
76 | continue; | ||
77 | local_irq_disable(); | ||
78 | if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) | ||
79 | return; | ||
80 | local_irq_restore(flags); | ||
81 | } | ||
82 | } | ||
83 | EXPORT_SYMBOL(_raw_spin_lock_wait_flags); | ||
84 | |||
62 | int _raw_spin_trylock_retry(raw_spinlock_t *lp) | 85 | int _raw_spin_trylock_retry(raw_spinlock_t *lp) |
63 | { | 86 | { |
64 | unsigned int cpu = ~smp_processor_id(); | 87 | unsigned int cpu = ~smp_processor_id(); |
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index c1d6e7e304e2..df84ae96915f 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h | |||
@@ -53,12 +53,12 @@ _raw_compare_and_swap(volatile unsigned int *lock, | |||
53 | */ | 53 | */ |
54 | 54 | ||
55 | #define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) | 55 | #define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) |
56 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) | ||
57 | #define __raw_spin_unlock_wait(lock) \ | 56 | #define __raw_spin_unlock_wait(lock) \ |
58 | do { while (__raw_spin_is_locked(lock)) \ | 57 | do { while (__raw_spin_is_locked(lock)) \ |
59 | _raw_spin_relax(lock); } while (0) | 58 | _raw_spin_relax(lock); } while (0) |
60 | 59 | ||
61 | extern void _raw_spin_lock_wait(raw_spinlock_t *); | 60 | extern void _raw_spin_lock_wait(raw_spinlock_t *); |
61 | extern void _raw_spin_lock_wait_flags(raw_spinlock_t *, unsigned long flags); | ||
62 | extern int _raw_spin_trylock_retry(raw_spinlock_t *); | 62 | extern int _raw_spin_trylock_retry(raw_spinlock_t *); |
63 | extern void _raw_spin_relax(raw_spinlock_t *lock); | 63 | extern void _raw_spin_relax(raw_spinlock_t *lock); |
64 | 64 | ||
@@ -72,6 +72,17 @@ static inline void __raw_spin_lock(raw_spinlock_t *lp) | |||
72 | _raw_spin_lock_wait(lp); | 72 | _raw_spin_lock_wait(lp); |
73 | } | 73 | } |
74 | 74 | ||
75 | static inline void __raw_spin_lock_flags(raw_spinlock_t *lp, | ||
76 | unsigned long flags) | ||
77 | { | ||
78 | int old; | ||
79 | |||
80 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); | ||
81 | if (likely(old == 0)) | ||
82 | return; | ||
83 | _raw_spin_lock_wait_flags(lp, flags); | ||
84 | } | ||
85 | |||
75 | static inline int __raw_spin_trylock(raw_spinlock_t *lp) | 86 | static inline int __raw_spin_trylock(raw_spinlock_t *lp) |
76 | { | 87 | { |
77 | int old; | 88 | int old; |