Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial/pmac_zilog: Remove flawed mitigation for rx irq flood

The mitigation was intended to stop the irq completely. That may be
better than a hard lock-up but it turns out that you get a crash anyway
if you're using pmac_zilog as a serial console:

ttyPZ0: pmz: rx irq flood !
BUG: spinlock recursion on CPU#0, swapper/0

That's because the pr_err() call in pmz_receive_chars() results in
pmz_console_write() attempting to lock a spinlock already locked in
pmz_interrupt(). With CONFIG_DEBUG_SPINLOCK=y, this produces a fatal
BUG splat. The spinlock in question is the one in struct uart_port.

Even when it's not fatal, the serial port rx function ceases to work.
Also, the iteration limit doesn't play nicely with QEMU, as can be
seen in the bug report linked below.

A web search for other reports of the error message "pmz: rx irq flood"
didn't produce anything. So I don't think this code is needed any more.
Remove it.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: stable@kernel.org
Cc: linux-m68k@lists.linux-m68k.org
Link: https://github.com/vivier/qemu-m68k/issues/44
Link: https://lore.kernel.org/all/1078874617.9746.36.camel@gaston/
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable <stable@kernel.org>
Signed-off-by: Finn Thain <fthain@linux-m68k.org>
Link: https://lore.kernel.org/r/e853cf2c762f23101cd2ddec0cc0c2be0e72685f.1712568223.git.fthain@linux-m68k.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Finn Thain and committed by
Greg Kroah-Hartman
1be32264 90452456

-14
-14
drivers/tty/serial/pmac_zilog.c
··· 210 210 { 211 211 struct tty_port *port; 212 212 unsigned char ch, r1, drop, flag; 213 - int loops = 0; 214 213 215 214 /* Sanity check, make sure the old bug is no longer happening */ 216 215 if (uap->port.state == NULL) { ··· 290 291 if (r1 & Rx_OVR) 291 292 tty_insert_flip_char(port, 0, TTY_OVERRUN); 292 293 next_char: 293 - /* We can get stuck in an infinite loop getting char 0 when the 294 - * line is in a wrong HW state, we break that here. 295 - * When that happens, I disable the receive side of the driver. 296 - * Note that what I've been experiencing is a real irq loop where 297 - * I'm getting flooded regardless of the actual port speed. 298 - * Something strange is going on with the HW 299 - */ 300 - if ((++loops) > 1000) 301 - goto flood; 302 294 ch = read_zsreg(uap, R0); 303 295 if (!(ch & Rx_CH_AV)) 304 296 break; 305 297 } 306 298 307 - return true; 308 - flood: 309 - pmz_interrupt_control(uap, 0); 310 - pmz_error("pmz: rx irq flood !\n"); 311 299 return true; 312 300 } 313 301