All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johan Hovold <johan@kernel.org>
To: linux-usb@vger.kernel.org
Cc: "Ahmed S . Darwish" <a.darwish@linutronix.de>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	linux-kernel@vger.kernel.org, Johan Hovold <johan@kernel.org>,
	stable <stable@vger.kernel.org>
Subject: [PATCH 06/14] USB: serial: keyspan_pda: fix write unthrottling
Date: Sun, 25 Oct 2020 18:45:52 +0100	[thread overview]
Message-ID: <20201025174600.27896-7-johan@kernel.org> (raw)
In-Reply-To: <20201025174600.27896-1-johan@kernel.org>

The driver did not update its view of the available device buffer space
until write() was called in task context. This meant that write_room()
would return 0 even after the device had sent a write-unthrottle
notification, something which could lead to blocked writers not being
woken up (e.g. when using OPOST).

Note that we must also request an unthrottle notification is case a
write() request fills the device buffer exactly.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/keyspan_pda.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 781b6723379f..39ed3ad32365 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -40,6 +40,8 @@
 #define DRIVER_AUTHOR "Brian Warner <warner@lothar.com>"
 #define DRIVER_DESC "USB Keyspan PDA Converter driver"
 
+#define KEYSPAN_TX_THRESHOLD	16
+
 struct keyspan_pda_private {
 	int			tx_room;
 	int			tx_throttled;
@@ -110,7 +112,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work)
 				 7, /* request_unthrottle */
 				 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
 				 | USB_DIR_OUT,
-				 16, /* value: threshold */
+				 KEYSPAN_TX_THRESHOLD,
 				 0, /* index */
 				 NULL,
 				 0,
@@ -129,6 +131,8 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
 	int retval;
 	int status = urb->status;
 	struct keyspan_pda_private *priv;
+	unsigned long flags;
+
 	priv = usb_get_serial_port_data(port);
 
 	switch (status) {
@@ -171,7 +175,10 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
 		case 1: /* modemline change */
 			break;
 		case 2: /* tx unthrottle interrupt */
+			spin_lock_irqsave(&port->lock, flags);
 			priv->tx_throttled = 0;
+			priv->tx_room = max(priv->tx_room, KEYSPAN_TX_THRESHOLD);
+			spin_unlock_irqrestore(&port->lock, flags);
 			/* queue up a wakeup at scheduler time */
 			usb_serial_port_softint(port);
 			break;
@@ -505,7 +512,8 @@ static int keyspan_pda_write(struct tty_struct *tty,
 			goto exit;
 		}
 	}
-	if (count > priv->tx_room) {
+
+	if (count >= priv->tx_room) {
 		/* we're about to completely fill the Tx buffer, so
 		   we'll be throttled afterwards. */
 		count = priv->tx_room;
@@ -560,14 +568,17 @@ static void keyspan_pda_write_bulk_callback(struct urb *urb)
 static int keyspan_pda_write_room(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	struct keyspan_pda_private *priv;
-	priv = usb_get_serial_port_data(port);
-	/* used by n_tty.c for processing of tabs and such. Giving it our
-	   conservative guess is probably good enough, but needs testing by
-	   running a console through the device. */
-	return priv->tx_room;
-}
+	struct keyspan_pda_private *priv = usb_get_serial_port_data(port);
+	unsigned long flags;
+	int room = 0;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (test_bit(0, &port->write_urbs_free) && !priv->tx_throttled)
+		room = priv->tx_room;
+	spin_unlock_irqrestore(&port->lock, flags);
 
+	return room;
+}
 
 static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)
 {
-- 
2.26.2


  parent reply	other threads:[~2020-10-25 17:47 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-25 17:45 [PATCH 00/14] USB: serial: keyspan_pda: fix up write implementation Johan Hovold
2020-10-25 17:45 ` [PATCH 01/14] USB: serial: keyspan_pda: fix dropped unthrottle interrupts Johan Hovold
2020-10-25 17:45 ` [PATCH 02/14] USB: serial: keyspan_pda: fix write deadlock Johan Hovold
2020-10-25 17:45 ` [PATCH 03/14] USB: serial: keyspan_pda: fix stalled writes Johan Hovold
2020-10-25 17:45 ` [PATCH 04/14] USB: serial: keyspan_pda: fix write-wakeup use-after-free Johan Hovold
2020-10-25 17:45 ` [PATCH 05/14] USB: serial: keyspan_pda: fix tx-unthrottle use-after-free Johan Hovold
2020-10-25 17:45 ` Johan Hovold [this message]
2020-10-25 17:45 ` [PATCH 07/14] USB: serial: keyspan_pda: refactor write-room handling Johan Hovold
2020-10-25 17:45 ` [PATCH 08/14] USB: serial: keyspan_pda: fix write implementation Johan Hovold
2020-10-25 17:45 ` [PATCH 09/14] USB: serial: keyspan_pda: increase transmitter threshold Johan Hovold
2020-10-25 17:45 ` [PATCH 10/14] USB: serial: keyspan_pda: add write-fifo support Johan Hovold
2020-10-25 17:45 ` [PATCH 11/14] USB: serial: keyspan_pda: clean up xircom/entrega support Johan Hovold
2020-10-26 12:00   ` Sebastian Andrzej Siewior
2020-10-27  8:09     ` Johan Hovold
2020-10-27  9:25       ` [PATCH v2 " Johan Hovold
2020-10-27  9:25         ` Johan Hovold
2020-10-25 17:45 ` [PATCH 12/14] USB: serial: keyspan_pda: clean up comments and whitespace Johan Hovold
2020-10-25 17:45 ` [PATCH 13/14] USB: serial: keyspan_pda: use BIT() macro Johan Hovold
2020-10-25 17:46 ` [PATCH 14/14] USB: serial: keyspan_pda: drop redundant usb-serial pointer Johan Hovold
2020-10-26 12:13 ` [PATCH 00/14] USB: serial: keyspan_pda: fix up write implementation Sebastian Andrzej Siewior
2020-10-27  8:11   ` Johan Hovold
2020-10-28  9:38 ` Greg KH
2020-11-04 10:04   ` Johan Hovold

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201025174600.27896-7-johan@kernel.org \
    --to=johan@kernel.org \
    --cc=a.darwish@linutronix.de \
    --cc=bigeasy@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.