From: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx> Fix regression to the serial gadget code created in January (2.6.29-rc1) by the "n_tty: Fix loss of echoed characters and remove bkl from n_tty" patch. That patch made an incompatible change to the locking policy, so that combining (a) tty->low_latency with (b) tty_flip_buffer_push() calls from tasklets now generates lockdep warnings of the "you can't grab a mutex from a tasklet" flavor. This fix just disables the low_latency usage in this code, and gets rid of that lockdep warning. Driver was *NOT* retested under RX stress loads (which ISTR were the original motivation for kicking in low_latency). Signed-off-by: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx> --- Noted around RC1(?) by someone who never sent the requested patch. drivers/usb/gadget/u_serial.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -535,8 +535,9 @@ recycle: list_move(&req->list, &port->read_pool); } - /* Push from tty to ldisc; this is immediate with low_latency, and - * may trigger callbacks to this driver ... so drop the spinlock. + /* Push from tty to ldisc; this would be immediate with low_latency + * (no longer valid from tasklet context, though), and may trigger + * callbacks to this driver ... so drop the spinlock. */ if (tty && do_push) { spin_unlock_irq(&port->port_lock); @@ -555,14 +556,16 @@ recycle: * implicit tty_unthrottle() call on its way... * * REVISIT we should probably add a timer to keep the tasklet - * from starving ... but it's not clear that case ever happens. + * from starving: not throttled, but TTY layer is refusing data. + * This was observed on 2.6.27-rc1 when streaming megabytes of + * data down a raw pipe... */ if (!list_empty(queue) && tty) { if (!test_bit(TTY_THROTTLED, &tty->flags)) { if (do_push) tasklet_schedule(&port->push); else - pr_warning(PREFIX "%d: RX not scheduled?\n", + pr_warning(PREFIX "%d: RX starving?\n", port->port_num); } } @@ -783,11 +786,6 @@ static int gs_open(struct tty_struct *tt port->open_count = 1; port->openclose = false; - /* low_latency means ldiscs work in tasklet context, without - * needing a workqueue schedule ... easier to keep up. - */ - tty->low_latency = 1; - /* if connected, start the I/O stream */ if (port->port_usb) { struct gserial *gser = port->port_usb; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html