[patch 2.6.31-rc6] fix serial gadget regression

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux