linux/drivers/tty/serial
Al Cooper dbb3b1ca56 8250: Fix race condition in serial8250_backup_timeout().
This is to fix an issue where output will suddenly become very slow.
The problem occurs on 8250 UARTS with the hardware bug UART_BUG_THRE.

BACKGROUND
For normal UARTs (without UART_BUG_THRE): When the serial core layer
gets new transmit data and the transmitter is idle, it buffers the
data and calls the 8250s' serial8250_start_tx() routine which will
simply enable the TX interrupt in the IER register and return. This
should immediately fire a THRE interrupt and begin transmitting the
data.
For buggy UARTs (with UART_BUG_THRE): merely enabling the TX interrupt
in IER does not necessarily generate a new THRE interrupt.
Therefore, a background timer periodically checks to see if there is
pending data, and starts transmission if that is the case.

The bug happens on SMP systems when the system has nothing to transmit,
the transmit interrupt is disabled and the following sequence occurs:
- CPU0: The background timer routine serial8250_backup_timeout()
  starts and saves the state of the interrupt enable register (IER)
  and then disables all interrupts in IER. NOTE: The transmit interrupt
  (TI) bit is saved as disabled.
- CPU1: The serial core gets data to transmit, grabs the port lock and
  calls serial8250_start_tx() which enables the TI in IER.
- CPU0: serial8250_backup_timeout() waits for the port lock.
- CPU1: finishes (with TI enabled) and releases the port lock.
- CPU0: serial8250_backup_timeout() calls the interrupt routine which
  will transmit the next fifo's worth of data and then restores the
  IER from the previously saved value (TI disabled).
At this point, as long as the serial core has more transmit data
buffered, it will not call serial8250_start_tx() again and the
background timer routine will slowly transmit the data.

The fix is to have serial8250_start_tx() get the port lock before
it saves the IER state and release it after restoring IER. This will
prevent serial8250_start_tx() from running in parallel.

Signed-off-by: Al Cooper <alcooperx@gmail.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-08-23 10:10:37 -07:00
..
cpm_uart tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
jsm serial: ioremap warning fix for jsm driver. 2011-06-07 09:25:34 -07:00
8250_accent.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
8250_acorn.c
8250_boca.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
8250_early.c
8250_exar_st16c554.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
8250_fourport.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
8250_gsc.c
8250_hp300.c
8250_hub6.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
8250_mca.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
8250_pci.c serial/8250_pci: delete duplicate data definition 2011-08-23 10:06:28 -07:00
8250_pnp.c serial: 8250_pnp: add Intermec CV60 touchscreen device 2011-08-22 14:18:44 -07:00
8250.c 8250: Fix race condition in serial8250_backup_timeout(). 2011-08-23 10:10:37 -07:00
8250.h tty/serial: Add explicit PORT_TEGRA type 2011-05-19 16:51:01 -07:00
21285.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
68328serial.c arch, mm: filter disallowed nodes from arch specific show_mem functions 2011-05-25 08:39:03 -07:00
68328serial.h
68360serial.c Merge 2.6.38-rc6 into tty-next 2011-02-24 11:36:31 -08:00
altera_jtaguart.c Merge branch 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6 2011-03-16 17:28:10 -07:00
altera_uart.c serial: altera_uart: Scan for a free port if platform device id is -1 2011-04-19 16:31:19 -07:00
amba-pl010.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
amba-pl011.c amba pl011: workaround for uart registers lockup 2011-07-08 15:09:23 -07:00
apbuart.c sparc32,leon: Fixed APBUART frequency detection 2011-03-30 04:28:54 -07:00
apbuart.h
atmel_serial.c atmel_serial: fix atmel_default_console_device 2011-08-22 14:18:44 -07:00
bcm63xx_uart.c serial: bcm63xx_uart: fix irq storm after rx fifo overrun. 2011-06-16 12:01:58 -07:00
bfin_5xx.c serial: bfin_5xx: fix off-by-one with resource size 2011-07-01 15:35:46 -07:00
bfin_sport_uart.c treewide: cleanup continuations and remove logging message whitespace 2011-04-26 10:24:37 +02:00
bfin_sport_uart.h
clps711x.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
crisv10.c tty: now phase out the ioctl file pointer for good 2011-02-17 11:59:56 -08:00
crisv10.h
dz.c atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
dz.h
icom.c Fix common misspellings 2011-03-31 11:26:23 -03:00
icom.h
ifx6x60.c net: remove mm.h inclusion from netdevice.h 2011-06-21 19:17:20 -07:00
ifx6x60.h serial: ifx6x60: minor cleanup 2011-02-17 11:16:15 -08:00
imx.c dt: remove of_alias_get_id() reference 2011-08-04 11:16:04 +01:00
ioc3_serial.c
ioc4_serial.c
ip22zilog.c Fix common misspellings 2011-03-31 11:26:23 -03:00
ip22zilog.h
Kconfig Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-3.x 2011-08-01 06:10:16 -10:00
kgdboc.c kgdboc,kgdbts: strlen() doesn't count the terminator 2011-03-25 16:37:30 -05:00
lantiq.c SERIAL: Lantiq: Add driver for MIPS Lantiq SOCs. 2011-05-19 09:55:43 +01:00
m32r_sio_reg.h
m32r_sio.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
m32r_sio.h
Makefile ARM: mach-s3c2400: delete 2011-07-18 10:59:26 -04:00
max3100.c workqueue, freezer: unify spelling of 'freeze' + 'able' to 'freezable' 2011-02-16 17:48:59 +01:00
max3107-aava.c tty: Add "spi:" prefix for spi modalias 2011-08-23 10:02:01 -07:00
max3107.c tty: Add "spi:" prefix for spi modalias 2011-08-23 10:02:01 -07:00
max3107.h Fix common misspellings 2011-03-31 11:26:23 -03:00
mcf.c
mfd.c treewide: cleanup continuations and remove logging message whitespace 2011-04-26 10:24:37 +02:00
mpc52xx_uart.c dt/serial: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:46 -07:00
mpsc.c
mrst_max3110.c tty: Add "spi:" prefix for spi modalias 2011-08-23 10:02:01 -07:00
mrst_max3110.h Fix common misspellings 2011-03-31 11:26:23 -03:00
msm_serial_hs.c Fix common misspellings 2011-03-31 11:26:23 -03:00
msm_serial.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
msm_serial.h tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
msm_smd_tty.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
mux.c
mxs-auart.c Freescale STMP37XX/STMP378X Application UART driver: remove duplicate linux/device.h include 2011-02-15 18:35:42 +01:00
netx-serial.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
nwpserial.c
of_serial.c tty/serial: Add devicetree support for nVidia Tegra serial ports 2011-07-10 06:37:43 +09:00
omap-serial.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
pch_uart.c pch_uart: Set PCIe bus number using probe parameter 2011-08-22 14:18:42 -07:00
pmac_zilog.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
pmac_zilog.h
pnx8xxx_uart.c
pxa.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
s3c2410.c serial: Remove redundant console_initcall from s3c and s5p console drivers 2011-07-20 19:10:43 +09:00
s3c2412.c serial: Remove redundant console_initcall from s3c and s5p console drivers 2011-07-20 19:10:43 +09:00
s3c2440.c serial: Remove redundant console_initcall from s3c and s5p console drivers 2011-07-20 19:10:43 +09:00
s3c6400.c serial: Remove redundant console_initcall from s3c and s5p console drivers 2011-07-20 19:10:43 +09:00
s5pv210.c Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6 2011-07-25 23:09:27 -07:00
sa1100.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
samsung.c serial: samsung: Fix build error 2011-08-08 13:54:50 -07:00
samsung.h serial: Remove redundant console_initcall from s3c and s5p console drivers 2011-07-20 19:10:43 +09:00
sb1250-duart.c atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
sc26xx.c
serial_core.c TTY: serial_core, remove superfluous set_task_state 2011-04-25 14:19:12 -07:00
serial_cs.c pcmcia: Convert pcmcia_device_id declarations to const 2011-05-06 07:46:22 +02:00
serial_ks8695.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
serial_txx9.c tty: remove invalid location line in file header 2011-04-19 16:33:36 -07:00
sh-sci.c sh: Fix boot crash related to SCI 2011-08-07 15:51:45 -07:00
sh-sci.h serial: sh-sci: FIFO sizing helper consolidation. 2011-06-14 17:38:19 +09:00
sn_console.c Fix common misspellings 2011-03-31 11:26:23 -03:00
suncore.c
suncore.h
sunhv.c dt/serial: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:46 -07:00
sunsab.c dt/serial: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:46 -07:00
sunsab.h
sunsu.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
sunzilog.c Fix common misspellings 2011-03-31 11:26:23 -03:00
sunzilog.h
timbuart.c
timbuart.h
uartlite.c dt: uartlite: merge platform and of_platform driver bindings 2011-02-28 13:22:43 -07:00
ucc_uart.c drivers/serial/ucc_uart.c: Fix compiler warning 2011-08-22 14:18:43 -07:00
vr41xx_siu.c
vt8500_serial.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
xilinx_uartps.c tty/serial: add support for Xilinx PS UART 2011-05-03 10:26:39 -07:00
zs.c atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
zs.h