From 719d1cd86780c156f954fc34f34481adac197aec Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:17:02 +1000 Subject: [PATCH] [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 Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 38 ++------------------------- include/asm-ppc64/iSeries/ItLpQueue.h | 2 +- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index a4f32cbf52..4231861288 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 51db08852d..69b26ad741 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; -- 2.39.5