Commit 719d1cd86780c156f954fc34f34481adac197aec
Committed by
Paul Mackerras
1 parent
ffe1b7e14e
Exists in
master
and in
4 other branches
[PATCH] ppc64: Replace custom locking code with a spinlock
The hvlpevent_queue (formally ItLpQueue) has a member called xInUseWord which is used for serialising access to the queue. Because it's a word (ie. 32 bit) there's a custom 32-bit version of test_and_set_bit() or thereabouts in ItLpQueue.c. The xInUseWord is not shared with they hypervisor, so we can replace it with a spinlock and remove the custom code. There is also another locking mechanism (ItLpQueueInProcess). This is redundant because it's only manipulated while the lock's held. Remove it. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Acked-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Showing 2 changed files with 3 additions and 37 deletions Side-by-side Diff
arch/ppc64/kernel/ItLpQueue.c
| ... | ... | @@ -42,35 +42,8 @@ |
| 42 | 42 | "Virtual I/O" |
| 43 | 43 | }; |
| 44 | 44 | |
| 45 | -static __inline__ int set_inUse(void) | |
| 46 | -{ | |
| 47 | - int t; | |
| 48 | - u32 * inUseP = &hvlpevent_queue.xInUseWord; | |
| 49 | - | |
| 50 | - __asm__ __volatile__("\n\ | |
| 51 | -1: lwarx %0,0,%2 \n\ | |
| 52 | - cmpwi 0,%0,0 \n\ | |
| 53 | - li %0,0 \n\ | |
| 54 | - bne- 2f \n\ | |
| 55 | - addi %0,%0,1 \n\ | |
| 56 | - stwcx. %0,0,%2 \n\ | |
| 57 | - bne- 1b \n\ | |
| 58 | -2: eieio" | |
| 59 | - : "=&r" (t), "=m" (hvlpevent_queue.xInUseWord) | |
| 60 | - : "r" (inUseP), "m" (hvlpevent_queue.xInUseWord) | |
| 61 | - : "cc"); | |
| 62 | - | |
| 63 | - return t; | |
| 64 | -} | |
| 65 | - | |
| 66 | -static __inline__ void clear_inUse(void) | |
| 67 | -{ | |
| 68 | - hvlpevent_queue.xInUseWord = 0; | |
| 69 | -} | |
| 70 | - | |
| 71 | 45 | /* Array of LpEvent handler functions */ |
| 72 | 46 | extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; |
| 73 | -unsigned long ItLpQueueInProcess = 0; | |
| 74 | 47 | |
| 75 | 48 | static struct HvLpEvent * get_next_hvlpevent(void) |
| 76 | 49 | { |
| 77 | 50 | |
| ... | ... | @@ -144,14 +117,9 @@ |
| 144 | 117 | struct HvLpEvent * event; |
| 145 | 118 | |
| 146 | 119 | /* If we have recursed, just return */ |
| 147 | - if ( !set_inUse() ) | |
| 120 | + if (!spin_trylock(&hvlpevent_queue.lock)) | |
| 148 | 121 | return; |
| 149 | 122 | |
| 150 | - if (ItLpQueueInProcess == 0) | |
| 151 | - ItLpQueueInProcess = 1; | |
| 152 | - else | |
| 153 | - BUG(); | |
| 154 | - | |
| 155 | 123 | for (;;) { |
| 156 | 124 | event = get_next_hvlpevent(); |
| 157 | 125 | if (event) { |
| ... | ... | @@ -187,9 +155,7 @@ |
| 187 | 155 | break; |
| 188 | 156 | } |
| 189 | 157 | |
| 190 | - ItLpQueueInProcess = 0; | |
| 191 | - mb(); | |
| 192 | - clear_inUse(); | |
| 158 | + spin_unlock(&hvlpevent_queue.lock); | |
| 193 | 159 | } |
| 194 | 160 | |
| 195 | 161 | static int set_spread_lpevents(char *str) |
include/asm-ppc64/iSeries/ItLpQueue.h