diff options
| author | Christian Ehrhardt <ehrhardt@de.ibm.com> | 2006-03-09 20:33:49 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-09 22:47:38 -0500 |
| commit | 96567161de0ceed45cd2eb0e5380e3c797f5c0f4 (patch) | |
| tree | eb1cf052c95b95052e281f9a0d33ea025ce39dc5 | |
| parent | 6a88231fc7da311e4da4ce2011d1a132c80c145a (diff) | |
[PATCH] s390: Increase spinlock retry code performance
Currently the code tries up to spin_retry times to grab a lock using the cs
instruction. The cs instruction has exclusive access to a memory region
and therefore invalidates the appropiate cache line of all other cpus. If
there is contention on a lock this leads to cache line trashing. This can
be avoided if we first check wether a cs instruction is likely to succeed
before the instruction gets actually executed.
Signed-off-by: Christian Ehrhardt <ehrhardt@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | arch/s390/lib/spinlock.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 60f80a4eed4e..b9b7958a226a 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c | |||
| @@ -2,8 +2,7 @@ | |||
| 2 | * arch/s390/lib/spinlock.c | 2 | * arch/s390/lib/spinlock.c |
| 3 | * Out of line spinlock code. | 3 | * Out of line spinlock code. |
| 4 | * | 4 | * |
| 5 | * S390 version | 5 | * Copyright (C) IBM Corp. 2004, 2006 |
| 6 | * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
| 7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | 6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) |
| 8 | */ | 7 | */ |
| 9 | 8 | ||
| @@ -44,6 +43,8 @@ _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) | |||
| 44 | _diag44(); | 43 | _diag44(); |
| 45 | count = spin_retry; | 44 | count = spin_retry; |
| 46 | } | 45 | } |
| 46 | if (__raw_spin_is_locked(lp)) | ||
| 47 | continue; | ||
| 47 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) | 48 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) |
| 48 | return; | 49 | return; |
| 49 | } | 50 | } |
| @@ -56,6 +57,8 @@ _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) | |||
| 56 | int count = spin_retry; | 57 | int count = spin_retry; |
| 57 | 58 | ||
| 58 | while (count-- > 0) { | 59 | while (count-- > 0) { |
| 60 | if (__raw_spin_is_locked(lp)) | ||
| 61 | continue; | ||
| 59 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) | 62 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) |
| 60 | return 1; | 63 | return 1; |
| 61 | } | 64 | } |
| @@ -74,6 +77,8 @@ _raw_read_lock_wait(raw_rwlock_t *rw) | |||
| 74 | _diag44(); | 77 | _diag44(); |
| 75 | count = spin_retry; | 78 | count = spin_retry; |
| 76 | } | 79 | } |
| 80 | if (!__raw_read_can_lock(rw)) | ||
| 81 | continue; | ||
| 77 | old = rw->lock & 0x7fffffffU; | 82 | old = rw->lock & 0x7fffffffU; |
| 78 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) | 83 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) |
| 79 | return; | 84 | return; |
| @@ -88,6 +93,8 @@ _raw_read_trylock_retry(raw_rwlock_t *rw) | |||
| 88 | int count = spin_retry; | 93 | int count = spin_retry; |
| 89 | 94 | ||
| 90 | while (count-- > 0) { | 95 | while (count-- > 0) { |
| 96 | if (!__raw_read_can_lock(rw)) | ||
| 97 | continue; | ||
| 91 | old = rw->lock & 0x7fffffffU; | 98 | old = rw->lock & 0x7fffffffU; |
| 92 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) | 99 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) |
| 93 | return 1; | 100 | return 1; |
| @@ -106,6 +113,8 @@ _raw_write_lock_wait(raw_rwlock_t *rw) | |||
| 106 | _diag44(); | 113 | _diag44(); |
| 107 | count = spin_retry; | 114 | count = spin_retry; |
| 108 | } | 115 | } |
| 116 | if (!__raw_write_can_lock(rw)) | ||
| 117 | continue; | ||
| 109 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) | 118 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) |
| 110 | return; | 119 | return; |
| 111 | } | 120 | } |
| @@ -118,6 +127,8 @@ _raw_write_trylock_retry(raw_rwlock_t *rw) | |||
| 118 | int count = spin_retry; | 127 | int count = spin_retry; |
| 119 | 128 | ||
| 120 | while (count-- > 0) { | 129 | while (count-- > 0) { |
| 130 | if (!__raw_write_can_lock(rw)) | ||
| 131 | continue; | ||
| 121 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) | 132 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) |
| 122 | return 1; | 133 | return 1; |
| 123 | } | 134 | } |
