TencentOS-kernel/drivers/tty/serial
Sergey Senozhatsky b107f45414 serial: 8250: change lock order in serial8250_do_startup()
commit 205d300aea75623e1ae4aa43e0d265ab9cf195fd upstream.

We have a number of "uart.port->desc.lock vs desc.lock->uart.port"
lockdep reports coming from 8250 driver; this causes a bit of trouble
to people, so let's fix it.

The problem is reverse lock order in two different call paths:

chain #1:

 serial8250_do_startup()
  spin_lock_irqsave(&port->lock);
   disable_irq_nosync(port->irq);
    raw_spin_lock_irqsave(&desc->lock)

chain #2:

  __report_bad_irq()
   raw_spin_lock_irqsave(&desc->lock)
    for_each_action_of_desc()
     printk()
      spin_lock_irqsave(&port->lock);

Fix this by changing the order of locks in serial8250_do_startup():
 do disable_irq_nosync() first, which grabs desc->lock, and grab
 uart->port after that, so that chain #1 and chain #2 have same lock
 order.

Full lockdep splat:

 ======================================================
 WARNING: possible circular locking dependency detected
 5.4.39 #55 Not tainted
 ======================================================

 swapper/0/0 is trying to acquire lock:
 ffffffffab65b6c0 (console_owner){-...}, at: console_lock_spinning_enable+0x31/0x57

 but task is already holding lock:
 ffff88810a8e34c0 (&irq_desc_lock_class){-.-.}, at: __report_bad_irq+0x5b/0xba

 which lock already depends on the new lock.

 the existing dependency chain (in reverse order) is:

 -> #2 (&irq_desc_lock_class){-.-.}:
        _raw_spin_lock_irqsave+0x61/0x8d
        __irq_get_desc_lock+0x65/0x89
        __disable_irq_nosync+0x3b/0x93
        serial8250_do_startup+0x451/0x75c
        uart_startup+0x1b4/0x2ff
        uart_port_activate+0x73/0xa0
        tty_port_open+0xae/0x10a
        uart_open+0x1b/0x26
        tty_open+0x24d/0x3a0
        chrdev_open+0xd5/0x1cc
        do_dentry_open+0x299/0x3c8
        path_openat+0x434/0x1100
        do_filp_open+0x9b/0x10a
        do_sys_open+0x15f/0x3d7
        kernel_init_freeable+0x157/0x1dd
        kernel_init+0xe/0x105
        ret_from_fork+0x27/0x50

 -> #1 (&port_lock_key){-.-.}:
        _raw_spin_lock_irqsave+0x61/0x8d
        serial8250_console_write+0xa7/0x2a0
        console_unlock+0x3b7/0x528
        vprintk_emit+0x111/0x17f
        printk+0x59/0x73
        register_console+0x336/0x3a4
        uart_add_one_port+0x51b/0x5be
        serial8250_register_8250_port+0x454/0x55e
        dw8250_probe+0x4dc/0x5b9
        platform_drv_probe+0x67/0x8b
        really_probe+0x14a/0x422
        driver_probe_device+0x66/0x130
        device_driver_attach+0x42/0x5b
        __driver_attach+0xca/0x139
        bus_for_each_dev+0x97/0xc9
        bus_add_driver+0x12b/0x228
        driver_register+0x64/0xed
        do_one_initcall+0x20c/0x4a6
        do_initcall_level+0xb5/0xc5
        do_basic_setup+0x4c/0x58
        kernel_init_freeable+0x13f/0x1dd
        kernel_init+0xe/0x105
        ret_from_fork+0x27/0x50

 -> #0 (console_owner){-...}:
        __lock_acquire+0x118d/0x2714
        lock_acquire+0x203/0x258
        console_lock_spinning_enable+0x51/0x57
        console_unlock+0x25d/0x528
        vprintk_emit+0x111/0x17f
        printk+0x59/0x73
        __report_bad_irq+0xa3/0xba
        note_interrupt+0x19a/0x1d6
        handle_irq_event_percpu+0x57/0x79
        handle_irq_event+0x36/0x55
        handle_fasteoi_irq+0xc2/0x18a
        do_IRQ+0xb3/0x157
        ret_from_intr+0x0/0x1d
        cpuidle_enter_state+0x12f/0x1fd
        cpuidle_enter+0x2e/0x3d
        do_idle+0x1ce/0x2ce
        cpu_startup_entry+0x1d/0x1f
        start_kernel+0x406/0x46a
        secondary_startup_64+0xa4/0xb0

 other info that might help us debug this:

 Chain exists of:
   console_owner --> &port_lock_key --> &irq_desc_lock_class

  Possible unsafe locking scenario:

        CPU0                    CPU1
        ----                    ----
   lock(&irq_desc_lock_class);
                                lock(&port_lock_key);
                                lock(&irq_desc_lock_class);
   lock(console_owner);

  *** DEADLOCK ***

 2 locks held by swapper/0/0:
  #0: ffff88810a8e34c0 (&irq_desc_lock_class){-.-.}, at: __report_bad_irq+0x5b/0xba
  #1: ffffffffab65b5c0 (console_lock){+.+.}, at: console_trylock_spinning+0x20/0x181

 stack backtrace:
 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.39 #55
 Hardware name: XXXXXX
 Call Trace:
  <IRQ>
  dump_stack+0xbf/0x133
  ? print_circular_bug+0xd6/0xe9
  check_noncircular+0x1b9/0x1c3
  __lock_acquire+0x118d/0x2714
  lock_acquire+0x203/0x258
  ? console_lock_spinning_enable+0x31/0x57
  console_lock_spinning_enable+0x51/0x57
  ? console_lock_spinning_enable+0x31/0x57
  console_unlock+0x25d/0x528
  ? console_trylock+0x18/0x4e
  vprintk_emit+0x111/0x17f
  ? lock_acquire+0x203/0x258
  printk+0x59/0x73
  __report_bad_irq+0xa3/0xba
  note_interrupt+0x19a/0x1d6
  handle_irq_event_percpu+0x57/0x79
  handle_irq_event+0x36/0x55
  handle_fasteoi_irq+0xc2/0x18a
  do_IRQ+0xb3/0x157
  common_interrupt+0xf/0xf
  </IRQ>

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Fixes: 768aec0b5bcc ("serial: 8250: fix shared interrupts issues with SMP and RT kernels")
Reported-by: Guenter Roeck <linux@roeck-us.net>
Reported-by: Raul Rangel <rrangel@google.com>
BugLink: https://bugs.chromium.org/p/chromium/issues/detail?id=1114800
Link: https://lore.kernel.org/lkml/CAHQZ30BnfX+gxjPm1DUd5psOTqbyDh4EJE=2=VAMW_VDafctkA@mail.gmail.com/T/#u
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20200817022646.1484638-1-sergey.senozhatsky@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-03-16 16:35:12 +08:00
..
8250 serial: 8250: change lock order in serial8250_do_startup() 2021-03-16 16:35:12 +08:00
cpm_uart Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
jsm Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
21285.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
Kconfig Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
Makefile Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
altera_jtaguart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
altera_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
amba-pl010.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
amba-pl011.c serial: pl011: Don't leak amba_ports entry on driver register error 2021-03-16 16:35:11 +08:00
amba-pl011.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
apbuart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
apbuart.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ar933x_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
arc_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
atmel_serial.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
atmel_serial.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
bcm63xx_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
clps711x.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
digicolor-usart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
dz.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
dz.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
earlycon-arm-semihost.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
earlycon-riscv-sbi.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
earlycon.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
efm32-uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
fsl_linflexuart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
fsl_lpuart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
icom.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
icom.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ifx6x60.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ifx6x60.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
imx.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip22zilog.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip22zilog.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
kgdb_nmi.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
kgdboc.c kgdboc: Use a platform device to handle tty drivers showing up late 2021-03-16 16:29:32 +08:00
lantiq.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
lpc32xx_hs.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
max310x.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
max3100.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
mcf.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
men_z135_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
meson_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
milbeaut_usio.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
mpc52xx_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
mps2-uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
msm_serial.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
mux.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
mvebu-uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
mxs-auart.c serial: mxs-auart: add missed iounmap() in probe failure and remove 2021-03-16 16:32:09 +08:00
omap-serial.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
owl-uart.c tty: serial: owl: add "much needed" clk_prepare_enable() 2021-03-16 16:26:56 +08:00
pch_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
pic32_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
pic32_uart.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
pmac_zilog.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
pmac_zilog.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
pnx8xxx_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
pxa.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
qcom_geni_serial.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
rda-uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
rp2.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sa1100.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
samsung.c serial: samsung: Removes the IRQ not found warning 2021-03-16 16:35:11 +08:00
samsung.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sb1250-duart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sc16is7xx.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sccnxp.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
serial-tegra.c serial: tegra: fix CREAD handling for PIO 2021-03-16 16:32:36 +08:00
serial_core.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
serial_mctrl_gpio.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
serial_mctrl_gpio.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
serial_txx9.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sh-sci.c serial: sh-sci: Make sure status register SCxSR is read in correct sequence 2021-03-16 16:27:03 +08:00
sh-sci.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sifive.c tty: serial: add missing spin_lock_init for SiFive serial console 2021-03-16 16:28:19 +08:00
sirfsoc_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sirfsoc_uart.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sprd_serial.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
st-asc.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
stm32-usart.c serial: stm32: avoid kernel warning on absence of optional IRQ 2021-03-16 16:35:11 +08:00
stm32-usart.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
suncore.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sunhv.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sunsab.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sunsab.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sunsu.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sunzilog.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sunzilog.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
tegra-tcu.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
timbuart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
timbuart.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
uartlite.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ucc_uart.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
vr41xx_siu.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
vt8500_serial.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
xilinx_uartps.c tty: xilinx_uartps: Really fix id assignment 2021-03-16 16:32:35 +08:00
zs.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
zs.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00