aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2007-12-11 22:58:12 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-13 23:50:46 -0500
commit88f0178e6ec2c73167de973e4af86905b4dbfd45 (patch)
treefa55f0649178d9c87e0608f9ee3560938f931e7a
parentda8cadb31b82c9d41fc593c8deab6aa20b162d6b (diff)
[POWERPC] iSeries: don't printk with HV spinlock held
Printk was observed to hang during module unload due to a limited window of characters that may be sent to the hypervisor. The window only reexpands when we receive an ack from the HV and the spinlock here prevents us from ever processing that ack. This fixes it by dropping the lock before doing the printk, then looping back to the top to reacquire the lock. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
index 34bdbbe3ce59..275f49449839 100644
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -121,6 +121,7 @@ void process_hvlpevents(void)
121{ 121{
122 struct HvLpEvent * event; 122 struct HvLpEvent * event;
123 123
124 restart:
124 /* If we have recursed, just return */ 125 /* If we have recursed, just return */
125 if (!spin_trylock(&hvlpevent_queue.hq_lock)) 126 if (!spin_trylock(&hvlpevent_queue.hq_lock))
126 return; 127 return;
@@ -146,8 +147,20 @@ void process_hvlpevents(void)
146 if (event->xType < HvLpEvent_Type_NumTypes && 147 if (event->xType < HvLpEvent_Type_NumTypes &&
147 lpEventHandler[event->xType]) 148 lpEventHandler[event->xType])
148 lpEventHandler[event->xType](event); 149 lpEventHandler[event->xType](event);
149 else 150 else {
150 printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); 151 u8 type = event->xType;
152
153 /*
154 * Don't printk in the spinlock as printk
155 * may require ack events form the HV to send
156 * any characters there.
157 */
158 hvlpevent_clear_valid(event);
159 spin_unlock(&hvlpevent_queue.hq_lock);
160 printk(KERN_INFO
161 "Unexpected Lp Event type=%d\n", type);
162 goto restart;
163 }
151 164
152 hvlpevent_clear_valid(event); 165 hvlpevent_clear_valid(event);
153 } else if (hvlpevent_queue.hq_overflow_pending) 166 } else if (hvlpevent_queue.hq_overflow_pending)