summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-06-30 15:17:02 +1000
committerPaul Mackerras <paulus@samba.org>2005-06-30 15:17:02 +1000
commit719d1cd86780c156f954fc34f34481adac197aec (patch)
treeb9e0a5b98e64459ea4eba77cd9bf3839dbb3a0fd
parentffe1b7e14e6b606bd84cab564aa2f481dbd4e418 (diff)
downloadlinux-719d1cd86780c156f954fc34f34481adac197aec.tar.gz
linux-719d1cd86780c156f954fc34f34481adac197aec.tar.bz2
linux-719d1cd86780c156f954fc34f34481adac197aec.zip
[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>
-rw-r--r--arch/ppc64/kernel/ItLpQueue.c38
-rw-r--r--include/asm-ppc64/iSeries/ItLpQueue.h2
2 files changed, 3 insertions, 37 deletions
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c
index a4f32cbf5297..4231861288a3 100644
--- a/arch/ppc64/kernel/ItLpQueue.c
+++ b/arch/ppc64/kernel/ItLpQueue.c
@@ -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)
diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h
index 51db08852dba..69b26ad74135 100644
--- a/include/asm-ppc64/iSeries/ItLpQueue.h
+++ b/include/asm-ppc64/iSeries/ItLpQueue.h
@@ -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;