diff options
author | Darwin Dingel <darwin.dingel@alliedtelesis.co.nz> | 2018-12-10 11:29:09 +1300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-12-05 15:37:26 +0100 |
commit | 6f8c923839721a9ea266230d99e2b9452efdf434 (patch) | |
tree | 7a519767e51f7a66a0280819a9ca7e3caf73c40c /include | |
parent | ab8f3d980d5df972d577dbf1287de029187dbee2 (diff) |
serial: 8250: Rate limit serial port rx interrupts during input overruns
[ Upstream commit 6d7f677a2afa1c82d7fc7af7f9159cbffd5dc010 ]
When a serial port gets faulty or gets flooded with inputs, its interrupt
handler starts to work double time to get the characters to the workqueue
for the tty layer to handle them. When this busy time on the serial/tty
subsystem happens during boot, where it is also busy on the userspace
trying to initialise, some processes can continuously get preempted
and will be on hold until the interrupts subside.
The fix is to backoff on processing received characters for a specified
amount of time when an input overrun is seen (received a new character
before the previous one is processed). This only stops receive and will
continue to transmit characters to serial port. After the backoff period
is done, it receive will be re-enabled. This is optional and will only
be enabled by setting 'overrun-throttle-ms' in the dts.
Signed-off-by: Darwin Dingel <darwin.dingel@alliedtelesis.co.nz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/serial_8250.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index a27ef5f56431..791a6be0e394 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -134,6 +134,10 @@ struct uart_8250_port { void (*dl_write)(struct uart_8250_port *, int); struct uart_8250_em485 *em485; + + /* Serial port overrun backoff */ + struct delayed_work overrun_backoff; + u32 overrun_backoff_time_ms; }; static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) |