aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2011-07-14 08:35:10 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-23 13:34:05 -0400
commit1f33a51d9771b34be3cb6f7fb96a325e17bbac7b (patch)
tree02af221f8f5207680caaca17748c90cd2b0bba24
parentae8dbd3eb97aad3929a981d3ab8c3cd2caee4ab1 (diff)
TTY: serial, remove BTM from wait_until_sent
During the BKL removal process, the BKL was switched to tty_lock (BTM). Now we should start pruning the BTM further. Let's start with wait_until_sent of the serial layer. This will allow us to switch to the tty port helpers and thus clean it up much. In wait_until_sent there are some uport members accessed, but neither of them is protected by BTM at the location they are set ('=>' means function call): * uport->fifosize (set in tty_ioctl => uart_ioctl => uart_set_info) * uport->type (set in add_one_port prior to tty_register_device) * uport->timeout (set usually in tty_ioctl => tty_mode_ioctl => tty_set_termios => uart_set_termios => uart_change_speed => uport->ops->set_termios => uart_update_timeout) * call to uport->ops->tx_empty() If the tx_empty hook needs some lock to protect accesses to registers, it should take &uport->lock spinlock like 8250 does. Otherwise there still might be races e.g. with ISRs. This should also fix the issue Andreas is seeing (BTM in comparison to BKL doesn't have any hidden functionality like unlocking during sleeping). Signed-off-by: Jiri Slaby <jslaby@suse.cz> References: https://lkml.org/lkml/2011/5/25/562 Cc: Alan Cox <alan@linux.intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Cc: Andreas Bombe <aeb@debian.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/tty/serial/serial_core.c30
1 files changed, 7 insertions, 23 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index db7912cb7ae0..2cbf1bd493e2 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -57,7 +57,7 @@ static struct lock_class_key port_lock_key;
57 57
58static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, 58static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
59 struct ktermios *old_termios); 59 struct ktermios *old_termios);
60static void __uart_wait_until_sent(struct uart_port *port, int timeout); 60static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
61static void uart_change_pm(struct uart_state *state, int pm_state); 61static void uart_change_pm(struct uart_state *state, int pm_state);
62 62
63/* 63/*
@@ -1304,16 +1304,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1304 tty->closing = 1; 1304 tty->closing = 1;
1305 spin_unlock_irqrestore(&port->lock, flags); 1305 spin_unlock_irqrestore(&port->lock, flags);
1306 1306
1307 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) { 1307 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1308 /* 1308 tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
1309 * hack: open-coded tty_wait_until_sent to avoid
1310 * recursive tty_lock
1311 */
1312 long timeout = msecs_to_jiffies(port->closing_wait);
1313 if (wait_event_interruptible_timeout(tty->write_wait,
1314 !tty_chars_in_buffer(tty), timeout) >= 0)
1315 __uart_wait_until_sent(uport, timeout);
1316 }
1317 1309
1318 /* 1310 /*
1319 * At this point, we stop accepting input. To do this, we 1311 * At this point, we stop accepting input. To do this, we
@@ -1329,7 +1321,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1329 * has completely drained; this is especially 1321 * has completely drained; this is especially
1330 * important if there is a transmit FIFO! 1322 * important if there is a transmit FIFO!
1331 */ 1323 */
1332 __uart_wait_until_sent(uport, uport->timeout); 1324 uart_wait_until_sent(tty, uport->timeout);
1333 } 1325 }
1334 1326
1335 uart_shutdown(tty, state); 1327 uart_shutdown(tty, state);
@@ -1363,8 +1355,10 @@ done:
1363 mutex_unlock(&port->mutex); 1355 mutex_unlock(&port->mutex);
1364} 1356}
1365 1357
1366static void __uart_wait_until_sent(struct uart_port *port, int timeout) 1358static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
1367{ 1359{
1360 struct uart_state *state = tty->driver_data;
1361 struct uart_port *port = state->uart_port;
1368 unsigned long char_time, expire; 1362 unsigned long char_time, expire;
1369 1363
1370 if (port->type == PORT_UNKNOWN || port->fifosize == 0) 1364 if (port->type == PORT_UNKNOWN || port->fifosize == 0)
@@ -1416,16 +1410,6 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout)
1416 } 1410 }
1417} 1411}
1418 1412
1419static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
1420{
1421 struct uart_state *state = tty->driver_data;
1422 struct uart_port *port = state->uart_port;
1423
1424 tty_lock();
1425 __uart_wait_until_sent(port, timeout);
1426 tty_unlock();
1427}
1428
1429/* 1413/*
1430 * This is called with the BKL held in 1414 * This is called with the BKL held in
1431 * linux/drivers/char/tty_io.c:do_tty_hangup() 1415 * linux/drivers/char/tty_io.c:do_tty_hangup()