[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>
This commit is contained in:
parent
ffe1b7e14e
commit
719d1cd867
|
@ -42,35 +42,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = {
|
||||||
"Virtual I/O"
|
"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 */
|
/* Array of LpEvent handler functions */
|
||||||
extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
|
extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
|
||||||
unsigned long ItLpQueueInProcess = 0;
|
|
||||||
|
|
||||||
static struct HvLpEvent * get_next_hvlpevent(void)
|
static struct HvLpEvent * get_next_hvlpevent(void)
|
||||||
{
|
{
|
||||||
|
@ -144,14 +117,9 @@ void process_hvlpevents(struct pt_regs *regs)
|
||||||
struct HvLpEvent * event;
|
struct HvLpEvent * event;
|
||||||
|
|
||||||
/* If we have recursed, just return */
|
/* If we have recursed, just return */
|
||||||
if ( !set_inUse() )
|
if (!spin_trylock(&hvlpevent_queue.lock))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ItLpQueueInProcess == 0)
|
|
||||||
ItLpQueueInProcess = 1;
|
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
event = get_next_hvlpevent();
|
event = get_next_hvlpevent();
|
||||||
if (event) {
|
if (event) {
|
||||||
|
@ -187,9 +155,7 @@ void process_hvlpevents(struct pt_regs *regs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItLpQueueInProcess = 0;
|
spin_unlock(&hvlpevent_queue.lock);
|
||||||
mb();
|
|
||||||
clear_inUse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_spread_lpevents(char *str)
|
static int set_spread_lpevents(char *str)
|
||||||
|
|
|
@ -69,7 +69,7 @@ struct hvlpevent_queue {
|
||||||
char *xSlicEventStackPtr; // 0x20
|
char *xSlicEventStackPtr; // 0x20
|
||||||
u8 xIndex; // 0x28 unique sequential index.
|
u8 xIndex; // 0x28 unique sequential index.
|
||||||
u8 xSlicRsvd[3]; // 0x29-2b
|
u8 xSlicRsvd[3]; // 0x29-2b
|
||||||
u32 xInUseWord; // 0x2C
|
spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct hvlpevent_queue hvlpevent_queue;
|
extern struct hvlpevent_queue hvlpevent_queue;
|
||||||
|
|
Loading…
Reference in New Issue