Commit 719d1cd86780c156f954fc34f34481adac197aec

Authored by Michael Ellerman
Committed by Paul Mackerras
1 parent ffe1b7e14e

[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
... ... @@ -69,7 +69,7 @@
69 69 char *xSlicEventStackPtr; // 0x20
70 70 u8 xIndex; // 0x28 unique sequential index.
71 71 u8 xSlicRsvd[3]; // 0x29-2b
72   - u32 xInUseWord; // 0x2C
  72 + spinlock_t lock;
73 73 };
74 74  
75 75 extern struct hvlpevent_queue hvlpevent_queue;