diff options
author | Jiri Slaby <jslaby@suse.cz> | 2021-05-05 11:19:05 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-05-13 16:57:16 +0200 |
commit | 6e94dbc7a4e49a028b81302d755bba1a518f973b (patch) | |
tree | f96593e04f90e65cdca2110661b239cface50743 /include | |
parent | 0f3dcf3b5d76669123bf99fec812b8b0acd60375 (diff) |
tty: cumulate and document tty_struct::flow* members
Group the flow flags under a single struct called flow. The new struct
contains 'stopped' and 'tco_stopped' bools which used to be bits in a
bitfield. The struct also contains the lock protecting them to
potentially share the same cache line.
Note that commit c545b66c6922b (tty: Serialize tcflow() with other tty
flow control changes) added a padding to the original bitfield. It was
for the bitfield to occupy a whole 64b word to avoid interferring stores
on Alpha (cannot we evaporate this arch with weird implications to C
code yet?). But it doesn't work as expected as the padding
(tty_struct::unused) is aligned to a 8B boundary too and occupies some
bytes from the next word.
So make it reliable by:
1) setting __aligned of the struct -- that aligns the start, and
2) making 'unsigned long unused[0]' as the last member of the struct --
pads the end.
This is also the perfect time to start the documentation of tty_struct
where all this lives. So we start by documenting what these bools
actually serve for. And why we do all the alignment dances. Only the few
up-to-date information from the Theodore's comment made it into this new
Kerneldoc comment.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: "Maciej W. Rozycki" <macro@orcam.me.uk>
Link: https://lore.kernel.org/r/20210505091928.22010-13-jslaby@suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/serial_core.h | 2 | ||||
-rw-r--r-- | include/linux/tty.h | 38 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 4 |
3 files changed, 25 insertions, 19 deletions
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index d7ed00f1594e..7445c8fd88c0 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -428,7 +428,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 && tty->stopped) || port->hw_stopped) + if ((tty && tty->flow.stopped) || port->hw_stopped) return 1; return 0; } diff --git a/include/linux/tty.h b/include/linux/tty.h index 5aad2220266c..df3a69b2e1ea 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -243,20 +243,22 @@ struct tty_port { #define TTY_PORT_KOPENED 5 /* device exclusively opened by kernel */ -/* - * Where all of the state associated with a tty is kept while the tty - * is open. Since the termios state should be kept even if the tty - * has been closed --- for things like the baud rate, etc --- it is - * not stored here, but rather a pointer to the real state is stored - * here. Possible the winsize structure should have the same - * treatment, but (1) the default 80x24 is usually right and (2) it's - * most often used by a windowing system, which will set the correct - * size each time the window is created or resized anyway. - * - TYT, 9/14/92 - */ - struct tty_operations; +/** + * struct tty_struct - state associated with a tty while open + * + * @flow.lock: lock for flow members + * @flow.stopped: tty stopped/started by tty_stop/tty_start + * @flow.tco_stopped: tty stopped/started by TCOOFF/TCOON ioctls (it has + * precedense over @flow.stopped) + * @flow.unused: alignment for Alpha, so that no members other than @flow.* are + * modified by the same 64b word store. The @flow's __aligned is + * there for the very same reason. + * + * All of the state associated with a tty while the tty is open. Persistent + * storage for tty devices is referenced here as @port in struct tty_port. + */ struct tty_struct { int magic; struct kref kref; @@ -275,7 +277,6 @@ struct tty_struct { struct rw_semaphore termios_rwsem; struct mutex winsize_mutex; spinlock_t ctrl_lock; - spinlock_t flow_lock; /* Termios values are protected by the termios rwsem */ struct ktermios termios, termios_locked; char name[64]; @@ -288,9 +289,14 @@ struct tty_struct { unsigned long flags; int count; struct winsize winsize; /* winsize_mutex */ - unsigned long stopped:1, /* flow_lock */ - flow_stopped:1, - unused:BITS_PER_LONG - 2; + + struct { + spinlock_t lock; + bool stopped; + bool tco_stopped; + unsigned long unused[0]; + } __aligned(sizeof(unsigned long)) flow; + int hw_stopped; unsigned long ctrl_status:8, /* ctrl_lock */ packet:1, diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 2f719b471d52..653fa5af3a22 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -153,7 +153,7 @@ * This routine notifies the tty driver that it should stop * outputting characters to the tty device. * - * Called with ->flow_lock held. Serialized with start() method. + * Called with ->flow.lock held. Serialized with start() method. * * Optional: * @@ -164,7 +164,7 @@ * This routine notifies the tty driver that it resume sending * characters to the tty device. * - * Called with ->flow_lock held. Serialized with stop() method. + * Called with ->flow.lock held. Serialized with stop() method. * * Optional: * |