diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-10-01 02:27:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-01 03:39:22 -0400 |
commit | 3c1fcfe229e99752c74efb945a4a3f560be04204 (patch) | |
tree | 44085d9b599e06a92426141811a6f712beac17aa /include/asm-s390/spinlock.h | |
parent | cdc39363d33506b0e067d41fc91f89d186bdf7f7 (diff) |
[PATCH] Directed yield: direct yield of spinlocks for s390.
Use the new diagnose 0x9c in the spinlock implementation for s390. It
yields the remaining timeslice of the virtual cpu that tries to acquire a
lock to the virtual cpu that is the current holder of the lock.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-s390/spinlock.h')
-rw-r--r-- | include/asm-s390/spinlock.h | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index 5f00feaf1be6..6b78af16999b 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h | |||
@@ -13,6 +13,8 @@ | |||
13 | 13 | ||
14 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 14 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
15 | 15 | ||
16 | #include <linux/smp.h> | ||
17 | |||
16 | static inline int | 18 | static inline int |
17 | _raw_compare_and_swap(volatile unsigned int *lock, | 19 | _raw_compare_and_swap(volatile unsigned int *lock, |
18 | unsigned int old, unsigned int new) | 20 | unsigned int old, unsigned int new) |
@@ -50,34 +52,46 @@ _raw_compare_and_swap(volatile unsigned int *lock, | |||
50 | * (the type definitions are in asm/spinlock_types.h) | 52 | * (the type definitions are in asm/spinlock_types.h) |
51 | */ | 53 | */ |
52 | 54 | ||
53 | #define __raw_spin_is_locked(x) ((x)->lock != 0) | 55 | #define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) |
54 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) | 56 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) |
55 | #define __raw_spin_unlock_wait(lock) \ | 57 | #define __raw_spin_unlock_wait(lock) \ |
56 | do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) | 58 | do { while (__raw_spin_is_locked(lock)) \ |
59 | _raw_spin_relax(lock); } while (0) | ||
57 | 60 | ||
58 | extern void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc); | 61 | extern void _raw_spin_lock_wait(raw_spinlock_t *, unsigned int pc); |
59 | extern int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc); | 62 | extern int _raw_spin_trylock_retry(raw_spinlock_t *, unsigned int pc); |
63 | extern void _raw_spin_relax(raw_spinlock_t *lock); | ||
60 | 64 | ||
61 | static inline void __raw_spin_lock(raw_spinlock_t *lp) | 65 | static inline void __raw_spin_lock(raw_spinlock_t *lp) |
62 | { | 66 | { |
63 | unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); | 67 | unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); |
64 | 68 | int old; | |
65 | if (unlikely(_raw_compare_and_swap(&lp->lock, 0, pc) != 0)) | 69 | |
66 | _raw_spin_lock_wait(lp, pc); | 70 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); |
71 | if (likely(old == 0)) { | ||
72 | lp->owner_pc = pc; | ||
73 | return; | ||
74 | } | ||
75 | _raw_spin_lock_wait(lp, pc); | ||
67 | } | 76 | } |
68 | 77 | ||
69 | static inline int __raw_spin_trylock(raw_spinlock_t *lp) | 78 | static inline int __raw_spin_trylock(raw_spinlock_t *lp) |
70 | { | 79 | { |
71 | unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); | 80 | unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); |
81 | int old; | ||
72 | 82 | ||
73 | if (likely(_raw_compare_and_swap(&lp->lock, 0, pc) == 0)) | 83 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); |
84 | if (likely(old == 0)) { | ||
85 | lp->owner_pc = pc; | ||
74 | return 1; | 86 | return 1; |
87 | } | ||
75 | return _raw_spin_trylock_retry(lp, pc); | 88 | return _raw_spin_trylock_retry(lp, pc); |
76 | } | 89 | } |
77 | 90 | ||
78 | static inline void __raw_spin_unlock(raw_spinlock_t *lp) | 91 | static inline void __raw_spin_unlock(raw_spinlock_t *lp) |
79 | { | 92 | { |
80 | _raw_compare_and_swap(&lp->lock, lp->lock, 0); | 93 | lp->owner_pc = 0; |
94 | _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0); | ||
81 | } | 95 | } |
82 | 96 | ||
83 | /* | 97 | /* |
@@ -154,7 +168,6 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) | |||
154 | return _raw_write_trylock_retry(rw); | 168 | return _raw_write_trylock_retry(rw); |
155 | } | 169 | } |
156 | 170 | ||
157 | #define _raw_spin_relax(lock) cpu_relax() | ||
158 | #define _raw_read_relax(lock) cpu_relax() | 171 | #define _raw_read_relax(lock) cpu_relax() |
159 | #define _raw_write_relax(lock) cpu_relax() | 172 | #define _raw_write_relax(lock) cpu_relax() |
160 | 173 | ||