Messages in this thread Patch in this message |  | | Subject | PATCH: psaux lockups on SMP 2.4.0-test* | From | (Kevin Buhr) | Date | 26 Aug 2000 11:17:48 -0500 |
| |
Chaskiel M Grundman <cg2v+@andrew.cmu.edu> writes: > > I have encountered a problem on several machines that causes the machine > to lock up when gpm retakes control of the ps2 mouse device after X is > shut down, but only when the system is running an SMP kernel. I could > not find any reports of similar problems, which makes me wonder if I > might be doing something wrong.... Any ideas? Any other info I should > provide?
Linus:
What a coincidence! I just got bitten by this last night while chasing down a problem with a wheel mouse. For some reason, Chaskiel's call trace seems to be missing the additional "aux_write_ack" call made by "handle_kbd_event"---maybe his compiler automagically optimized it away or something---but it looks like exactly the same problem, except I saw "keyboard_interrupt (grabs spinlock) -> handle_kbd_event -> handle_mouse_event -> aux_write_ack (grabs spinlock)".
Anyway, here's the message I composed before reading Chaskiel's report:
There's an insidious spinlock hang hidden in "drivers/char/pc_keyb.c". "handle_mouse_event" is called with the "kbd_controller_lock" held. If it sees an "AUX_RECONNECT" scancode on the wire, it tries to---according to the comments---"ping the mouse". Unfortunately, it does this using "aux_write_ack" which tries to grab the lock again.
I triggered this while playing protocol games with a new wheel mouse. Presumably, anyone who plugs a PS/2 mouse into a running SMP machine will hang their machine; and a flakey mouse that generates spurious AUX_RECONNECT messages (or even a working mouse that happens to generate that scancode validly) would lead to mysterious lockups, I think.
Anyway, here's a patch. I've tested this on 2.4.0-test5, but it should work fine on test7, too.
Kevin <buhr@stat.wisc.edu>
--- linux-2.4.0-test7/drivers/char/pc_keyb.c Fri Jul 21 00:26:15 2000 +++ linux-2.4.0-test7-local/drivers/char/pc_keyb.c Sat Aug 26 00:25:25 2000 @@ -62,6 +62,7 @@ static void kbd_write_output_w(int data); #ifdef CONFIG_PSMOUSE static void aux_write_ack(int val); +static void __aux_write_ack(int val); #endif spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; @@ -404,7 +405,7 @@ } else if(scancode == AUX_RECONNECT){ queue->head = queue->tail = 0; /* Flush input queue */ - aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */ + __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */ return; } @@ -822,11 +823,8 @@ /* * Send a byte to the mouse & handle returned ack */ -static void aux_write_ack(int val) +static void __aux_write_ack(int val) { - unsigned long flags; - - spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MOUSE); kb_wait(); @@ -834,6 +832,14 @@ /* we expect an ACK in response. */ mouse_reply_expected++; kb_wait(); +} + +static void aux_write_ack(int val) +{ + unsigned long flags; + + spin_lock_irqsave(&kbd_controller_lock, flags); + __aux_write_ack(val); spin_unlock_irqrestore(&kbd_controller_lock, flags); } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |