diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-06-30 01:17:02 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-06-30 01:17:02 -0400 |
commit | 719d1cd86780c156f954fc34f34481adac197aec (patch) | |
tree | b9e0a5b98e64459ea4eba77cd9bf3839dbb3a0fd /arch | |
parent | ffe1b7e14e6b606bd84cab564aa2f481dbd4e418 (diff) |
[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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ppc64/kernel/ItLpQueue.c | 38 |
1 files changed, 2 insertions, 36 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] = { | |||
42 | "Virtual I/O" | 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 | /* Array of LpEvent handler functions */ | 45 | /* Array of LpEvent handler functions */ |
72 | extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; | 46 | extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; |
73 | unsigned long ItLpQueueInProcess = 0; | ||
74 | 47 | ||
75 | static struct HvLpEvent * get_next_hvlpevent(void) | 48 | static struct HvLpEvent * get_next_hvlpevent(void) |
76 | { | 49 | { |
@@ -144,14 +117,9 @@ void process_hvlpevents(struct pt_regs *regs) | |||
144 | struct HvLpEvent * event; | 117 | struct HvLpEvent * event; |
145 | 118 | ||
146 | /* If we have recursed, just return */ | 119 | /* If we have recursed, just return */ |
147 | if ( !set_inUse() ) | 120 | if (!spin_trylock(&hvlpevent_queue.lock)) |
148 | return; | 121 | return; |
149 | 122 | ||
150 | if (ItLpQueueInProcess == 0) | ||
151 | ItLpQueueInProcess = 1; | ||
152 | else | ||
153 | BUG(); | ||
154 | |||
155 | for (;;) { | 123 | for (;;) { |
156 | event = get_next_hvlpevent(); | 124 | event = get_next_hvlpevent(); |
157 | if (event) { | 125 | if (event) { |
@@ -187,9 +155,7 @@ void process_hvlpevents(struct pt_regs *regs) | |||
187 | break; | 155 | break; |
188 | } | 156 | } |
189 | 157 | ||
190 | ItLpQueueInProcess = 0; | 158 | spin_unlock(&hvlpevent_queue.lock); |
191 | mb(); | ||
192 | clear_inUse(); | ||
193 | } | 159 | } |
194 | 160 | ||
195 | static int set_spread_lpevents(char *str) | 161 | static int set_spread_lpevents(char *str) |