All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.cz>,
	One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	Peter Hurley <peter@hurleysoftware.com>
Subject: [PATCH v2 04/14] serial: core: Privatize tty->hw_stopped
Date: Wed, 10 Sep 2014 15:06:26 -0400	[thread overview]
Message-ID: <1410375996-4693-5-git-send-email-peter@hurleysoftware.com> (raw)
In-Reply-To: <1410375996-4693-1-git-send-email-peter@hurleysoftware.com>

tty->hw_stopped is not used by the tty core and is thread-unsafe;
hw_stopped is a member of a bitfield whose fields are updated
non-atomically and no lock is suitable for serializing updates.

Replace serial core usage of tty->hw_stopped with uport->hw_stopped.
Use int storage which works around Alpha EV4/5 non-atomic byte storage,
since uart_port uses different locks to protect certain fields within the
structure.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
 drivers/tty/serial/bfin_uart.c   | 14 +++++++-------
 drivers/tty/serial/serial_core.c | 28 +++++++++++++---------------
 include/linux/serial_core.h      |  3 ++-
 3 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index dec0fd7..fc9fbf3 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -108,22 +108,22 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
 static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id)
 {
 	struct bfin_serial_port *uart = dev_id;
-	unsigned int status = bfin_serial_get_mctrl(&uart->port);
+	struct uart_port *uport = &uart->port;
+	unsigned int status = bfin_serial_get_mctrl(uport);
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	struct tty_struct *tty = uart->port.state->port.tty;
 
 	UART_CLEAR_SCTS(uart);
-	if (tty->hw_stopped) {
+	if (uport->hw_stopped) {
 		if (status) {
-			tty->hw_stopped = 0;
-			uart_write_wakeup(&uart->port);
+			uport->hw_stopped = 0;
+			uart_write_wakeup(uport);
 		}
 	} else {
 		if (!status)
-			tty->hw_stopped = 1;
+			uport->hw_stopped = 1;
 	}
 #endif
-	uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
+	uart_handle_cts_change(uport, status & TIOCM_CTS);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 3c62b3f..1f52a7d 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -94,7 +94,7 @@ static void __uart_start(struct tty_struct *tty)
 	struct uart_state *state = tty->driver_data;
 	struct uart_port *port = state->uart_port;
 
-	if (!tty->stopped && !tty->hw_stopped)
+	if (!uart_tx_stopped(port))
 		port->ops->start_tx(port);
 }
 
@@ -180,10 +180,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
 		}
 
 		spin_lock_irq(&uport->lock);
-		if (uart_cts_enabled(uport)) {
-			if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS))
-				tty->hw_stopped = 1;
-		}
+		if (uart_cts_enabled(uport) &&
+		    !(uport->ops->get_mctrl(uport) & TIOCM_CTS))
+			uport->hw_stopped = 1;
+		else
+			uport->hw_stopped = 0;
 		spin_unlock_irq(&uport->lock);
 	}
 
@@ -944,7 +945,7 @@ static int uart_get_lsr_info(struct tty_struct *tty,
 	 */
 	if (uport->x_char ||
 	    ((uart_circ_chars_pending(&state->xmit) > 0) &&
-	     !tty->stopped && !tty->hw_stopped))
+	     !uart_tx_stopped(uport)))
 		result &= ~TIOCSER_TEMT;
 
 	return put_user(result, value);
@@ -1290,7 +1291,7 @@ static void uart_set_termios(struct tty_struct *tty,
 
 	/*
 	 * If the port is doing h/w assisted flow control, do nothing.
-	 * We assume that tty->hw_stopped has never been set.
+	 * We assume that port->hw_stopped has never been set.
 	 */
 	if (uport->flags & UPF_HARD_FLOW)
 		return;
@@ -1298,7 +1299,7 @@ static void uart_set_termios(struct tty_struct *tty,
 	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
 		spin_lock_irqsave(&uport->lock, flags);
-		tty->hw_stopped = 0;
+		uport->hw_stopped = 0;
 		__uart_start(tty);
 		spin_unlock_irqrestore(&uport->lock, flags);
 	}
@@ -1306,7 +1307,7 @@ static void uart_set_termios(struct tty_struct *tty,
 	else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
 		spin_lock_irqsave(&uport->lock, flags);
 		if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) {
-			tty->hw_stopped = 1;
+			uport->hw_stopped = 1;
 			uport->ops->stop_tx(uport);
 		}
 		spin_unlock_irqrestore(&uport->lock, flags);
@@ -2776,23 +2777,20 @@ EXPORT_SYMBOL_GPL(uart_handle_dcd_change);
  */
 void uart_handle_cts_change(struct uart_port *uport, unsigned int status)
 {
-	struct tty_port *port = &uport->state->port;
-	struct tty_struct *tty = port->tty;
-
 	lockdep_assert_held_once(&uport->lock);
 
 	uport->icount.cts++;
 
 	if (uart_cts_enabled(uport)) {
-		if (tty->hw_stopped) {
+		if (uport->hw_stopped) {
 			if (status) {
-				tty->hw_stopped = 0;
+				uport->hw_stopped = 0;
 				uport->ops->start_tx(uport);
 				uart_write_wakeup(uport);
 			}
 		} else {
 			if (!status) {
-				tty->hw_stopped = 1;
+				uport->hw_stopped = 1;
 				uport->ops->stop_tx(uport);
 			}
 		}
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index bc70048..677a97c 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -195,6 +195,7 @@ struct uart_port {
 #define UPSTAT_CTS_ENABLE	((__force upstat_t) (1 << 0))
 #define UPSTAT_DCD_ENABLE	((__force upstat_t) (1 << 1))
 
+	int			hw_stopped;		/* sw-assisted CTS flow state */
 	unsigned int		mctrl;			/* current modem ctrl settings */
 	unsigned int		timeout;		/* character-based timeout */
 	unsigned int		type;			/* port type */
@@ -353,7 +354,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
 static inline int uart_tx_stopped(struct uart_port *port)
 {
 	struct tty_struct *tty = port->state->port.tty;
-	if(tty->stopped || tty->hw_stopped)
+	if (tty->stopped || port->hw_stopped)
 		return 1;
 	return 0;
 }
-- 
2.1.0

  parent reply	other threads:[~2014-09-10 19:06 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-02 21:39 [PATCH 00/26] tty/serial flow control fixes Peter Hurley
2014-09-02 21:39 ` [PATCH 01/26] Revert "serial: uart: add hw flow control support configuration" Peter Hurley
2014-09-02 21:50   ` Murali Karicheri
2014-09-02 21:50     ` Murali Karicheri
2014-09-02 21:58     ` Peter Hurley
2014-09-02 22:17       ` Murali Karicheri
2014-09-02 22:17         ` Murali Karicheri
2014-09-02 21:39 ` [PATCH 02/26] serial: Style fix Peter Hurley
2014-09-02 21:39 ` [PATCH 03/26] serial: imx: Fix x_char handling and tx flow control Peter Hurley
2014-09-02 21:39 ` [PATCH 04/26] serial: core: Fix x_char race Peter Hurley
2014-09-02 21:39 ` [PATCH 05/26] serial: core: Remove unsafe x_char optimization Peter Hurley
2014-09-02 21:39 ` [PATCH 06/26] serial: Fix send_xchar() handlers Peter Hurley
2014-09-02 21:39   ` Peter Hurley
2014-09-02 21:39   ` Peter Hurley
2014-09-02 21:39 ` [PATCH 07/26] serial: mpc52xx: Use default serial core x_char handler Peter Hurley
2014-09-02 21:39 ` [PATCH 08/26] serial: sunsab: Don't enable tx if tx stopped Peter Hurley
2014-09-02 21:39   ` Peter Hurley
2014-09-02 21:39   ` Peter Hurley
2014-09-02 21:39 ` [PATCH 09/26] serial: blackfin: Fix missing gpio.h Peter Hurley
2014-09-02 21:39 ` [PATCH 10/26] serial: core: Document lock requirement for UPF_* flags updates Peter Hurley
2014-09-02 21:39 ` [PATCH 11/26] serial: 8250: Document serial8250_modem_status() locking Peter Hurley
2014-09-02 21:39 ` [PATCH 12/26] serial: core: Unwrap tertiary assignment in uart_handle_dcd_change() Peter Hurley
2014-09-02 21:39 ` [PATCH 13/26] locking: Add non-fatal spin lock assert Peter Hurley
2014-09-03  9:27   ` Peter Zijlstra
2014-09-03 11:20     ` Peter Hurley
2014-09-03 14:40       ` Peter Zijlstra
2014-09-03 14:50         ` Peter Hurley
2014-09-03 15:07           ` Peter Zijlstra
2014-09-04  5:14             ` Ingo Molnar
2014-09-10 11:02               ` Peter Hurley
2014-09-10 13:08                 ` Peter Zijlstra
2014-09-10 14:45                   ` Peter Hurley
2014-09-10 18:34                     ` Greg Kroah-Hartman
2014-09-02 21:39 ` [PATCH 14/26] serial: core: Document and assert lock requirements for irq helpers Peter Hurley
2014-09-02 21:39 ` [PATCH 15/26] serial: core: Privatize modem status enable flags Peter Hurley
2014-09-02 21:39 ` [PATCH 16/26] isdn: i4l: Remove ASYNC_CTS_FLOW Peter Hurley
2014-09-02 21:39   ` Peter Hurley
2014-09-02 21:39 ` [PATCH 17/26] serial: core: Privatize tty->hw_stopped Peter Hurley
2014-09-09  0:29   ` Peter Hurley
2014-09-02 21:39 ` [PATCH 18/26] usb: serial: Remove unused tty->hw_stopped Peter Hurley
2014-09-02 21:39 ` [PATCH 19/26] serial: bfin-uart: Fix auto CTS Peter Hurley
2014-09-02 21:39 ` [PATCH 20/26] serial: core: Use spin_lock_irq() in uart_set_termios() Peter Hurley
2014-09-02 21:39 ` [PATCH 21/26] tty: Convert tty_struct bitfield to bools Peter Hurley
2014-09-03 10:58   ` One Thousand Gnomes
2014-09-03 12:14     ` Peter Hurley
2014-09-03 12:19       ` One Thousand Gnomes
2014-09-03 15:10         ` Peter Hurley
2014-09-03 17:56           ` Greg Kroah-Hartman
2014-09-04 16:08             ` Peter Hurley
2014-09-02 21:39 ` [PATCH 22/26] tty: Serialize tty flow control changes with flow_lock Peter Hurley
2014-09-02 21:39 ` [PATCH 23/26] tty: Move packet mode flow control notifications to pty driver Peter Hurley
2014-09-02 21:39 ` [PATCH 24/26] tty: Serialize tcflow() with other tty flow control changes Peter Hurley
2014-09-02 21:39 ` [PATCH 25/26] tty: Move and rename send_prio_char() as tty_send_xchar() Peter Hurley
2014-09-02 21:39 ` [PATCH 26/26] tty: Hold termios_rwsem for tcflow(TCIxxx) Peter Hurley
2014-09-08 23:24 ` [PATCH 00/26] tty/serial flow control fixes Greg Kroah-Hartman
2014-09-08 23:33   ` Peter Hurley
2014-09-08 23:43     ` Greg Kroah-Hartman
2014-09-08 23:46       ` Peter Hurley
2014-09-09  0:01         ` Greg Kroah-Hartman
2014-09-10 19:06 ` [PATCH v2 00/14] " Peter Hurley
2014-09-10 19:06   ` [PATCH v2 01/14] serial: core: Document and assert lock requirements for irq helpers Peter Hurley
2014-09-10 19:06   ` [PATCH v2 02/14] serial: core: Privatize modem status enable flags Peter Hurley
2014-09-10 19:06   ` [PATCH v2 03/14] isdn: i4l: Remove ASYNC_CTS_FLOW Peter Hurley
2014-09-10 19:06     ` Peter Hurley
2014-09-10 19:06   ` Peter Hurley [this message]
2014-09-10 19:06   ` [PATCH v2 05/14] usb: serial: Remove unused tty->hw_stopped Peter Hurley
2014-09-23 15:33     ` Johan Hovold
2014-09-10 19:06   ` [PATCH v2 06/14] serial: bfin-uart: Fix auto CTS Peter Hurley
2014-09-10 19:06   ` [PATCH v2 07/14] serial: core: Use spin_lock_irq() in uart_set_termios() Peter Hurley
2014-09-10 19:06   ` [PATCH v2 08/14] tty: Convert tty_struct bitfield to ints Peter Hurley
2014-09-10 19:06   ` [PATCH v2 09/14] tty: Serialize tty flow control changes with flow_lock Peter Hurley
2014-09-10 19:06   ` [PATCH v2 10/14] tty: Move packet mode flow control notifications to pty driver Peter Hurley
2014-09-10 19:06   ` [PATCH v2 11/14] tty: Serialize tcflow() with other tty flow control changes Peter Hurley
2014-09-10 19:06   ` [PATCH v2 12/14] tty: Move and rename send_prio_char() as tty_send_xchar() Peter Hurley
2014-09-10 19:06   ` [PATCH v2 13/14] tty: Hold termios_rwsem for tcflow(TCIxxx) Peter Hurley
2014-09-10 19:06   ` [PATCH v2 14/14] tty: Workaround Alpha non-atomic byte storage in tty_struct Peter Hurley

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=1410375996-4693-5-git-send-email-peter@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=gnomes@lxorguk.ukuu.org.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    /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.