[PATCH] ppc64: Replace custom locking code with a spinlock
authorMichael Ellerman <michael@ellerman.id.au>
Thu, 30 Jun 2005 05:17:02 +0000 (15:17 +1000)
committerPaul Mackerras <paulus@samba.org>
Thu, 30 Jun 2005 05:17:02 +0000 (15:17 +1000)
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>
arch/ppc64/kernel/ItLpQueue.c
include/asm-ppc64/iSeries/ItLpQueue.h

index a4f32cbf5297ca94ad5d7407b5b4337f91f3e573..4231861288a3cb5b9fe88e6219fa7cedc19ec730 100644 (file)
@@ -42,35 +42,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = {
        "Virtual I/O"
 };
 
-static __inline__ int set_inUse(void)
-{
-       int t;
-       u32 * inUseP = &hvlpevent_queue.xInUseWord;
-
-       __asm__ __volatile__("\n\
-1:     lwarx   %0,0,%2         \n\
-       cmpwi   0,%0,0          \n\
-       li      %0,0            \n\
-       bne-    2f              \n\
-       addi    %0,%0,1         \n\
-       stwcx.  %0,0,%2         \n\
-       bne-    1b              \n\
-2:     eieio"
-       : "=&r" (t), "=m" (hvlpevent_queue.xInUseWord)
-       : "r" (inUseP), "m" (hvlpevent_queue.xInUseWord)
-       : "cc");
-
-       return t;
-}
-
-static __inline__ void clear_inUse(void)
-{
-       hvlpevent_queue.xInUseWord = 0;
-}
-
 /* Array of LpEvent handler functions */
 extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
-unsigned long ItLpQueueInProcess = 0;
 
 static struct HvLpEvent * get_next_hvlpevent(void)
 {
@@ -144,14 +117,9 @@ void process_hvlpevents(struct pt_regs *regs)
        struct HvLpEvent * event;
 
        /* If we have recursed, just return */
-       if ( !set_inUse() )
+       if (!spin_trylock(&hvlpevent_queue.lock))
                return;
 
-       if (ItLpQueueInProcess == 0)
-               ItLpQueueInProcess = 1;
-       else
-               BUG();
-
        for (;;) {
                event = get_next_hvlpevent();
                if (event) {
@@ -187,9 +155,7 @@ void process_hvlpevents(struct pt_regs *regs)
                        break;
        }
 
-       ItLpQueueInProcess = 0;
-       mb();
-       clear_inUse();
+       spin_unlock(&hvlpevent_queue.lock);
 }
 
 static int set_spread_lpevents(char *str)
index 51db08852dba7bf41215058044ea2a0c67392b53..69b26ad74135fceef296dae507336a47991e1d95 100644 (file)
@@ -69,7 +69,7 @@ struct hvlpevent_queue {
        char    *xSlicEventStackPtr;    // 0x20
        u8      xIndex;                 // 0x28 unique sequential index.
        u8      xSlicRsvd[3];           // 0x29-2b
-       u32     xInUseWord;             // 0x2C
+       spinlock_t      lock;
 };
 
 extern struct hvlpevent_queue hvlpevent_queue;