Many serial driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
This patchset modifies these drivers to release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100 [ARM] 4417/1: Serial: Fix AMBA drivers locking This is build tested for all drivers and tested on Samsung's Arndale board for samsung.c driver. Rebased over linux-next (Problem was reproduced on this branch):
commit 1e712b0818569846d6b926ecb6bf32b3dea73609 Author: Stephen Rothwell sfr@canb.auug.org.au Date: Fri Aug 16 17:06:26 2013 +1000 Add linux-next specific files for 20130816 Signed-off-by: Stephen Rothwell sfr@canb.auug.org.au
Cc: Bryan Huntsman bryanh@codeaurora.org Cc: Daniel Walker dwalker@fifo99.com Cc: David Brown davidb@codeaurora.org Cc: Stephen Warren swarren@wwwdotorg.org Cc: Tobias Klauser tklauser@distanz.ch Cc: Tony Prisk linux@prisktech.co.nz
Viresh Kumar (25): tty: serial: altera_jtag: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: altera: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: apbuart: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: ar933x: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: arc: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: bcm63xx: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: bfin_sport: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: efm32: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: icom: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: lpc32xx_hs: don't call tty_flip_buffer_push() twice tty: serial: lpc32xx_hs: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: m32r_sio: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: mcf: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: mfd: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: mpsc: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: msm: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: netx: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: nwpserial: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: pnx8xxx: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: rp2: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: sa1100: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: samsung: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: tegra: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: sirfsoc: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: vt8500: drop uart_port->lock before calling tty_flip_buffer_push()
drivers/tty/serial/altera_jtaguart.c | 2 ++ drivers/tty/serial/altera_uart.c | 2 ++ drivers/tty/serial/apbuart.c | 2 ++ drivers/tty/serial/ar933x_uart.c | 2 ++ drivers/tty/serial/arc_uart.c | 2 ++ drivers/tty/serial/bcm63xx_uart.c | 2 ++ drivers/tty/serial/bfin_sport_uart.c | 5 +++-- drivers/tty/serial/efm32-uart.c | 4 ++-- drivers/tty/serial/icom.c | 3 +++ drivers/tty/serial/lpc32xx_hs.c | 7 ++++--- drivers/tty/serial/m32r_sio.c | 3 +++ drivers/tty/serial/mcf.c | 2 ++ drivers/tty/serial/mfd.c | 14 ++++++++++---- drivers/tty/serial/mpsc.c | 11 ++++++++--- drivers/tty/serial/msm_serial.c | 5 +++++ drivers/tty/serial/netx-serial.c | 6 ++++-- drivers/tty/serial/nwpserial.c | 3 +++ drivers/tty/serial/pnx8xxx_uart.c | 3 +++ drivers/tty/serial/rp2.c | 2 ++ drivers/tty/serial/sa1100.c | 3 +++ drivers/tty/serial/samsung.c | 5 ++++- drivers/tty/serial/serial-tegra.c | 10 ++++++++-- drivers/tty/serial/sirfsoc_uart.c | 3 +++ drivers/tty/serial/vt8500_serial.c | 2 ++ 24 files changed, 84 insertions(+), 19 deletions(-)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Cc: Tobias Klauser tklauser@distanz.ch Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/altera_jtaguart.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 2299a34..18e038f 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -139,7 +139,9 @@ static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) uart_insert_char(port, 0, 0, ch, flag); }
+ spin_unlock(&port->lock); tty_flip_buffer_push(&port->state->port); + spin_lock(&port->lock); }
static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Cc: Tobias Klauser tklauser@distanz.ch Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/altera_uart.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index fa638db..6431472 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -231,7 +231,9 @@ static void altera_uart_rx_chars(struct altera_uart *pp) flag); }
+ spin_unlock(&port->lock); tty_flip_buffer_push(&port->state->port); + spin_lock(&port->lock); }
static void altera_uart_tx_chars(struct altera_uart *pp)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/apbuart.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 6331464d..de11ab8 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -125,7 +125,9 @@ static void apbuart_rx_chars(struct uart_port *port) status = UART_GET_STATUS(port); }
+ spin_unlock(&port->lock); tty_flip_buffer_push(&port->state->port); + spin_lock(&port->lock); }
static void apbuart_tx_chars(struct uart_port *port)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/ar933x_uart.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index a712a3f..78be13a 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -322,7 +322,9 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) tty_insert_flip_char(port, ch, TTY_NORMAL); } while (max_count-- > 0);
+ spin_unlock(&up->port.lock); tty_flip_buffer_push(port); + spin_lock(&up->port.lock); }
static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/arc_uart.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 37abf6c..569872f 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -251,7 +251,9 @@ static void arc_serial_rx_chars(struct arc_uart_port *uart, unsigned int status) if (!(uart_handle_sysrq_char(&uart->port, ch))) uart_insert_char(&uart->port, status, RXOERR, ch, flg);
+ spin_unlock(&uart->port.lock); tty_flip_buffer_push(&uart->port.state->port); + spin_lock(&uart->port.lock); } while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)); }
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/bcm63xx_uart.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index d14ba5a..649d512 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -302,7 +302,9 @@ static void bcm_uart_do_rx(struct uart_port *port)
} while (--max_count);
+ spin_unlock(&port->lock); tty_flip_buffer_push(tty_port); + spin_lock(&port->lock); }
/*
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/bfin_sport_uart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index 016c3e9..87636cc 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c @@ -161,11 +161,12 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) if (!uart_handle_sysrq_char(&up->port, ch)) tty_insert_flip_char(port, ch, TTY_NORMAL); } - /* XXX this won't deadlock with lowlat? */ - tty_flip_buffer_push(port);
spin_unlock(&up->port.lock);
+ /* XXX this won't deadlock with lowlat? */ + tty_flip_buffer_push(port); + return IRQ_HANDLED; }
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/efm32-uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index 98adaa1..0eb5b56 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c @@ -268,10 +268,10 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) handled = IRQ_HANDLED; }
- tty_flip_buffer_push(tport); - spin_unlock(&port->lock);
+ tty_flip_buffer_push(tport); + return handled; }
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/icom.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 06555dd..7c9a067 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -834,7 +834,10 @@ ignore_char: status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); } icom_port->next_rcv = rcv_buff; + + spin_unlock(&icom_port->uart_port.lock); tty_flip_buffer_push(port); + spin_lock(&icom_port->uart_port.lock); }
static void process_interrupt(u16 port_int_reg,
serial_lpc32xx_interrupt() calls __serial_lpc32xx_rx() first and then tty_flip_buffer_push() immediately after that. But last statement of __serial_lpc32xx_rx() already called tty_flip_buffer_push()..
So, probably its not required to be called twice. Lets remove one of them.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/lpc32xx_hs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index dffea6b..8fdf6a8 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -351,10 +351,8 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) }
/* Data received? */ - if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { + if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) __serial_lpc32xx_rx(port); - tty_flip_buffer_push(tport); - }
/* Transmit data request? */ if ((status & LPC32XX_HSU_TX_INT) && (!uart_tx_stopped(port))) {
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/lpc32xx_hs.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index 8fdf6a8..701644f 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -279,7 +279,10 @@ static void __serial_lpc32xx_rx(struct uart_port *port)
tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); } + + spin_unlock(&port->lock); tty_flip_buffer_push(tport); + spin_lock(&port->lock); }
static void __serial_lpc32xx_tx(struct uart_port *port)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/m32r_sio.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index bb1afa0..9cd9b4e 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c @@ -368,7 +368,10 @@ static void receive_chars(struct uart_sio_port *up, int *status) ignore_char: *status = serial_in(up, UART_LSR); } while ((*status & UART_LSR_DR) && (max_count-- > 0)); + + spin_unlock(&up->port.lock); tty_flip_buffer_push(port); + spin_lock(&up->port.lock); }
static void transmit_chars(struct uart_sio_port *up)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/mcf.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index a2e97c9..0edfaf8 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -325,7 +325,9 @@ static void mcf_rx_chars(struct mcf_uart *pp) uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); }
+ spin_unlock(&port->lock); tty_flip_buffer_push(&port->state->port); + spin_lock(&port->lock); }
/****************************************************************************/
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/mfd.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 4a82267..d3db042 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -386,7 +386,7 @@ static void serial_hsu_stop_tx(struct uart_port *port)
/* This is always called in spinlock protected mode, so * modify timeout timer is safe here */ -void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) +void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts, unsigned long *flags) { struct hsu_dma_buffer *dbuf = &up->rxbuf; struct hsu_dma_chan *chan = up->rxc; @@ -438,7 +438,9 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | (0x1 << 16) | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ ); + spin_unlock_irqrestore(&up->port.lock, *flags); tty_flip_buffer_push(tport); + spin_lock_irqsave(&up->port.lock, *flags);
chan_writel(chan, HSU_CH_CR, 0x3);
@@ -459,7 +461,8 @@ static void serial_hsu_stop_rx(struct uart_port *port) } }
-static inline void receive_chars(struct uart_hsu_port *up, int *status) +static inline void receive_chars(struct uart_hsu_port *up, int *status, + unsigned long *flags) { unsigned int ch, flag; unsigned int max_count = 256; @@ -519,7 +522,10 @@ static inline void receive_chars(struct uart_hsu_port *up, int *status) ignore_char: *status = serial_in(up, UART_LSR); } while ((*status & UART_LSR_DR) && max_count--); + + spin_unlock_irqrestore(&up->port.lock, *flags); tty_flip_buffer_push(&up->port.state->port); + spin_lock_irqsave(&up->port.lock, *flags); }
static void transmit_chars(struct uart_hsu_port *up) @@ -613,7 +619,7 @@ static irqreturn_t port_irq(int irq, void *dev_id)
lsr = serial_in(up, UART_LSR); if (lsr & UART_LSR_DR) - receive_chars(up, &lsr); + receive_chars(up, &lsr, &flags); check_modem_status(up);
/* lsr will be renewed during the receive_chars */ @@ -643,7 +649,7 @@ static inline void dma_chan_irq(struct hsu_dma_chan *chan)
/* Rx channel */ if (chan->dirt == DMA_FROM_DEVICE) - hsu_dma_rx(up, int_sts); + hsu_dma_rx(up, int_sts, &flags);
/* Tx channel */ if (chan->dirt == DMA_TO_DEVICE) {
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/mpsc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index fba5257..8d70267 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c @@ -934,7 +934,7 @@ static int serial_polled; ****************************************************************************** */
-static int mpsc_rx_intr(struct mpsc_port_info *pi) +static int mpsc_rx_intr(struct mpsc_port_info *pi, unsigned long *flags) { struct mpsc_rx_desc *rxre; struct tty_port *port = &pi->port.state->port; @@ -969,8 +969,11 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) #endif /* Following use of tty struct directly is deprecated */ if (tty_buffer_request_room(port, bytes_in) < bytes_in) { - if (port->low_latency) + if (port->low_latency) { + spin_unlock_irqrestore(&pi->port.lock, *flags); tty_flip_buffer_push(port); + spin_lock_irqsave(&pi->port.lock, *flags); + } /* * If this failed then we will throw away the bytes * but must do so to clear interrupts. @@ -1080,7 +1083,9 @@ next_frame: if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) mpsc_start_rx(pi);
+ spin_unlock_irqrestore(&pi->port.lock, *flags); tty_flip_buffer_push(port); + spin_lock_irqsave(&pi->port.lock, *flags); return rc; }
@@ -1222,7 +1227,7 @@ static irqreturn_t mpsc_sdma_intr(int irq, void *dev_id)
spin_lock_irqsave(&pi->port.lock, iflags); mpsc_sdma_intr_ack(pi); - if (mpsc_rx_intr(pi)) + if (mpsc_rx_intr(pi, &iflags)) rc = IRQ_HANDLED; if (mpsc_tx_intr(pi)) rc = IRQ_HANDLED;
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Cc: David Brown davidb@codeaurora.org (maintainer:ARM/QUALCOMM MSM...) Cc: Daniel Walker dwalker@fifo99.com (maintainer:ARM/QUALCOMM MSM...) Cc: Bryan Huntsman bryanh@codeaurora.org (maintainer:ARM/QUALCOMM MSM...) Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/msm_serial.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 8f58540..cc44ef4 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -140,7 +140,10 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) count -= 4; }
+ spin_unlock(&port->lock); tty_flip_buffer_push(tport); + spin_lock(&port->lock); + if (misr & (UART_IMR_RXSTALE)) msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); msm_write(port, 0xFFFFFF, UARTDM_DMRX); @@ -192,7 +195,9 @@ static void handle_rx(struct uart_port *port) tty_insert_flip_char(tport, c, flag); }
+ spin_unlock(&port->lock); tty_flip_buffer_push(tport); + spin_lock(&port->lock); }
static void reset_dm_count(struct uart_port *port, int count)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/netx-serial.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/netx-serial.c b/drivers/tty/serial/netx-serial.c index ce04f3f..0a4dd70 100644 --- a/drivers/tty/serial/netx-serial.c +++ b/drivers/tty/serial/netx-serial.c @@ -196,7 +196,7 @@ static void netx_txint(struct uart_port *port) uart_write_wakeup(port); }
-static void netx_rxint(struct uart_port *port) +static void netx_rxint(struct uart_port *port, unsigned long *flags) { unsigned char rx, flg, status;
@@ -236,7 +236,9 @@ static void netx_rxint(struct uart_port *port) uart_insert_char(port, status, SR_OE, rx, flg); }
+ spin_unlock_irqrestore(&port->lock, *flags); tty_flip_buffer_push(&port->state->port); + spin_lock_irqsave(&port->lock, *flags); }
static irqreturn_t netx_int(int irq, void *dev_id) @@ -250,7 +252,7 @@ static irqreturn_t netx_int(int irq, void *dev_id) status = readl(port->membase + UART_IIR) & IIR_MASK; while (status) { if (status & IIR_RIS) - netx_rxint(port); + netx_rxint(port, &flags); if (status & IIR_TIS) netx_txint(port); if (status & IIR_MIS) {
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/nwpserial.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index 549c70a..693bc6c 100644 --- a/drivers/tty/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c @@ -149,7 +149,10 @@ static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) tty_insert_flip_char(port, ch, TTY_NORMAL); } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR);
+ spin_unlock(&up->port.lock); tty_flip_buffer_push(port); + spin_lock(&up->port.lock); + ret = IRQ_HANDLED;
/* clear interrupt */
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/pnx8xxx_uart.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/pnx8xxx_uart.c b/drivers/tty/serial/pnx8xxx_uart.c index b6b7aca..de6c05c 100644 --- a/drivers/tty/serial/pnx8xxx_uart.c +++ b/drivers/tty/serial/pnx8xxx_uart.c @@ -237,7 +237,10 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); } + + spin_unlock(&sport->port.lock); tty_flip_buffer_push(&sport->port.state->port); + spin_lock(&sport->port.lock); }
static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/rp2.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index a314a94..328d6de 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -427,7 +427,9 @@ static void rp2_rx_chars(struct rp2_uart_port *up) up->port.icount.rx++; }
+ spin_unlock(&up->port.lock); tty_flip_buffer_push(port); + spin_lock(&up->port.lock); }
static void rp2_tx_chars(struct rp2_uart_port *up)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/sa1100.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index fc23ea19..ba25722 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -232,7 +232,10 @@ sa1100_rx_chars(struct sa1100_port *sport) status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | UTSR0_TO_SM(UART_GET_UTSR0(sport)); } + + spin_unlock(&sport->port.lock); tty_flip_buffer_push(&sport->port.state->port); + spin_lock(&sport->port.lock); }
static void sa1100_tx_chars(struct sa1100_port *sport)
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/samsung.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 019b915..f3dfa19 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -249,6 +249,8 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) ufcon |= S3C2410_UFCON_RESETRX; wr_regl(port, S3C2410_UFCON, ufcon); rx_enabled(port) = 1; + spin_unlock_irqrestore(&port->lock, + flags); goto out; } continue; @@ -297,10 +299,11 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) ignore_char: continue; } + + spin_unlock_irqrestore(&port->lock, flags); tty_flip_buffer_push(&port->state->port);
out: - spin_unlock_irqrestore(&port->lock, flags); return IRQ_HANDLED; }
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Cc: Stephen Warren swarren@wwwdotorg.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/serial-tegra.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 94a2484..d0d972f 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -571,7 +571,9 @@ static void tegra_uart_rx_dma_complete(void *args)
tegra_uart_handle_rx_pio(tup, port); if (tty) { + spin_unlock_irqrestore(&u->lock, flags); tty_flip_buffer_push(port); + spin_lock_irqsave(&u->lock, flags); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); @@ -583,11 +585,13 @@ static void tegra_uart_rx_dma_complete(void *args) spin_unlock_irqrestore(&u->lock, flags); }
-static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) +static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup, + unsigned long *flags) { struct dma_tx_state state; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &tup->uport.state->port; + struct uart_port *u = &tup->uport; int count;
/* Deactivate flow control to stop sender */ @@ -604,7 +608,9 @@ static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup)
tegra_uart_handle_rx_pio(tup, port); if (tty) { + spin_unlock_irqrestore(&u->lock, *flags); tty_flip_buffer_push(port); + spin_lock_irqsave(&u->lock, *flags); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); @@ -671,7 +677,7 @@ static irqreturn_t tegra_uart_isr(int irq, void *data) iir = tegra_uart_read(tup, UART_IIR); if (iir & UART_IIR_NO_INT) { if (is_rx_int) { - tegra_uart_handle_rx_dma(tup); + tegra_uart_handle_rx_dma(tup, &flags); if (tup->rx_in_progress) { ier = tup->ier_shadow; ier |= (UART_IER_RLSI | UART_IER_RTOIE |
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/sirfsoc_uart.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index ed3b890..54f6b4d 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -299,7 +299,10 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) }
port->icount.rx += rx_count; + + spin_unlock(&port->lock); tty_flip_buffer_push(&port->state->port); + spin_lock(&port->lock);
return rx_count; }
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) -----
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Cc: Tony Prisk linux@prisktech.co.nz Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/tty/serial/vt8500_serial.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index a90bf04..93b697a 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -170,7 +170,9 @@ static void handle_rx(struct uart_port *port) tty_insert_flip_char(tport, c, flag); }
+ spin_unlock(&port->lock); tty_flip_buffer_push(tport); + spin_lock(&port->lock); }
static void handle_tx(struct uart_port *port)
On 08/19/2013 10:44 AM, Viresh Kumar wrote:
Many serial driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels.
Crash looks like this (produced with samsung.c driver):
Please review commit 677fe555cbfb188af58cce105f4dae9505e58c31 'serial: imx: Fix recursive locking bug' to see if that is actually the problem you're having with the samsung serial driver.
[<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c)
This patchset modifies these drivers to release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100 [ARM] 4417/1: Serial: Fix AMBA drivers locking This is build tested for all drivers and tested on Samsung's Arndale board for samsung.c driver. Rebased over linux-next (Problem was reproduced on this branch):
commit 1e712b0818569846d6b926ecb6bf32b3dea73609 Author: Stephen Rothwell sfr@canb.auug.org.au Date: Fri Aug 16 17:06:26 2013 +1000 Add linux-next specific files for 20130816 Signed-off-by: Stephen Rothwell sfr@canb.auug.org.au
Cc: Bryan Huntsman bryanh@codeaurora.org Cc: Daniel Walker dwalker@fifo99.com Cc: David Brown davidb@codeaurora.org Cc: Stephen Warren swarren@wwwdotorg.org Cc: Tobias Klauser tklauser@distanz.ch Cc: Tony Prisk linux@prisktech.co.nz
Viresh Kumar (25): tty: serial: altera_jtag: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: altera: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: apbuart: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: ar933x: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: arc: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: bcm63xx: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: bfin_sport: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: efm32: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: icom: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: lpc32xx_hs: don't call tty_flip_buffer_push() twice tty: serial: lpc32xx_hs: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: m32r_sio: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: mcf: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: mfd: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: mpsc: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: msm: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: netx: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: nwpserial: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: pnx8xxx: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: rp2: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: sa1100: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: samsung: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: tegra: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: sirfsoc: drop uart_port->lock before calling tty_flip_buffer_push() tty: serial: vt8500: drop uart_port->lock before calling tty_flip_buffer_push()
drivers/tty/serial/altera_jtaguart.c | 2 ++ drivers/tty/serial/altera_uart.c | 2 ++ drivers/tty/serial/apbuart.c | 2 ++ drivers/tty/serial/ar933x_uart.c | 2 ++ drivers/tty/serial/arc_uart.c | 2 ++ drivers/tty/serial/bcm63xx_uart.c | 2 ++ drivers/tty/serial/bfin_sport_uart.c | 5 +++-- drivers/tty/serial/efm32-uart.c | 4 ++-- drivers/tty/serial/icom.c | 3 +++ drivers/tty/serial/lpc32xx_hs.c | 7 ++++--- drivers/tty/serial/m32r_sio.c | 3 +++ drivers/tty/serial/mcf.c | 2 ++ drivers/tty/serial/mfd.c | 14 ++++++++++---- drivers/tty/serial/mpsc.c | 11 ++++++++--- drivers/tty/serial/msm_serial.c | 5 +++++ drivers/tty/serial/netx-serial.c | 6 ++++-- drivers/tty/serial/nwpserial.c | 3 +++ drivers/tty/serial/pnx8xxx_uart.c | 3 +++ drivers/tty/serial/rp2.c | 2 ++ drivers/tty/serial/sa1100.c | 3 +++ drivers/tty/serial/samsung.c | 5 ++++- drivers/tty/serial/serial-tegra.c | 10 ++++++++-- drivers/tty/serial/sirfsoc_uart.c | 3 +++ drivers/tty/serial/vt8500_serial.c | 2 ++ 24 files changed, 84 insertions(+), 19 deletions(-)
Hi Peter,
On 19 August 2013 21:01, Peter Hurley peter@hurleysoftware.com wrote:
Please review commit 677fe555cbfb188af58cce105f4dae9505e58c31 'serial: imx: Fix recursive locking bug' to see if that is actually the problem you're having with the samsung serial driver.
No, this doesn't seem to be the same issue... The issue here is:
s3c24xx_serial_rx_chars() -> spin_lock_irqsave(&port->lock, flags); -> tty_flip_buffer_push() -> flush_to_ldisc() -> n_tty_receive_buf2() -> __receive_buf() -> uart_start() -> spin_lock_irqsave(&port->lock, flags);
This seems to be a generic enough problem as many drivers are already doing the right thing. They release lock before calling tty_flip_buffer_push()..
And that's why my patchset had only 25 patches :)
On 08/19/2013 08:18 PM, Viresh Kumar wrote:
Hi Peter,
On 19 August 2013 21:01, Peter Hurley peter@hurleysoftware.com wrote:
Please review commit 677fe555cbfb188af58cce105f4dae9505e58c31 'serial: imx: Fix recursive locking bug' to see if that is actually the problem you're having with the samsung serial driver.
No, this doesn't seem to be the same issue... The issue here is:
s3c24xx_serial_rx_chars() -> spin_lock_irqsave(&port->lock, flags); -> tty_flip_buffer_push() -> flush_to_ldisc() -> n_tty_receive_buf2() -> __receive_buf() -> uart_start() -> spin_lock_irqsave(&port->lock, flags);
Nope.
First, you have two stack traces from your previous message. The BUG report is the second stack trace:
worker_thread process_one_work flush_to_ldisc n_tty_receive_buf2 __receive_buf uart_start raw_spin_lock_irqsave(&port->lock)
IOW, no lock recursion because it's running on a separate kworker thread, and did not arrive from s3c24xx_serial_rx_chars() (other than indirectly via schedule_work()).
It's BUGing because the uart_port spinlock cannot be acquired _even though apparently there is no owning CPU_.
The key to why the flush_to_disc() worker thread cannot acquire the uart_port spinlock is in the first stack trace:
s3c24xx_serial_rx_chars raw_spin_unlock_irqrestore do_raw_spin_unlock dump_stack
So the real question here is why do_raw_spin_unlock() is doing a dump_stack()? Is one of the SPIN_BUG_ON() asserts in debug_spin_unlock() triggering?
This seems to be a generic enough problem as many drivers are already doing the right thing. They release lock before calling tty_flip_buffer_push()..
No. Those drivers are carrying vestige code from the original 2.6 tree import.
As documented in tty_flip_buffer_push():
* Queue a push of the terminal flip buffers to the line discipline. This * function must not be called from IRQ context if port->low_latency is * set.
IOW, s3c24xx_serial_rx_chars() executing in IRQ context cannot call flush_to_ldisc() -- the work must be scheduled instead. Since flush_to_ldisc() will be scheduled on a separate kworker thread, the uart_port spin lock will not be recursively claimed.
So, recursive locking of the uart_port lock is not the problem (at least, not wrt the flush_to_ldisc() call chain).
Regards, Peter Hurley
Hi Peter,
On 20 August 2013 08:05, Peter Hurley peter@hurleysoftware.com wrote:
The key to why the flush_to_disc() worker thread cannot acquire the uart_port spinlock is in the first stack trace:
s3c24xx_serial_rx_chars raw_spin_unlock_irqrestore do_raw_spin_unlock dump_stack
So the real question here is why do_raw_spin_unlock() is doing a dump_stack()? Is one of the SPIN_BUG_ON() asserts in debug_spin_unlock() triggering?
Ahh, you are right and SPIN_BUG_ON() is indeed getting asserted.
I am embarrassed to say this but it happened due to my stupid mistake :(
And yes, non-rt kernels doesn't see this crash as we simply schedule work from our interrupt handlers instead of calling flush_to_ldisc()
This is how I got the wrong crash dump: - Applied my patch over latest linux-next - Some more debug messages
Tested: No crashes found..
Thought maybe I should try without my patch first, if it really crashes or not.
- Reverted my patch and got some conflicts due the "debug patch".. and ended up resolving them in the wrong way:
- spin_unlock_irqrestore(&port->lock, flags); pr_info("%s\n", __func__); tty_flip_buffer_push(&port->state->port); + spin_unlock_irqrestore(&port->lock, flags);
out: + spin_unlock_irqrestore(&port->lock, flags);
Got two unlocks and so the dump.. Sorry for the incorrect information :(
But yes there are some issues with the RT kernel, which are going to stay without this patchset.. Here are the logs with 3.10.6 + rt kernel (attached as well, in case lines are wrapped by gmail :( ):
root@localhost:~# [ 128.771800] ------------[ cut here ]------------ [ 128.771815] kernel BUG at /home/arm/work/kernel/linaro/lng/lng.git/kernel/rtmutex.c:738! [ 128.771829] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP THUMB2 [ 128.771844] Modules linked in: [ 128.771868] CPU: 0 PID: 1895 Comm: irq/85-12c20000 Not tainted 3.10.6-rt3+ #7 [ 128.771885] task: ef2d9cc0 ti: ee2b0000 task.ti: ee2b0000 [ 128.771915] PC is at rt_spin_lock_slowlock+0x18c/0x1a0 [ 128.771933] LR is at rt_spin_lock_slowlock+0x3f/0x1a0 [ 128.771956] pc : [<80406b9c>] lr : [<80406a4f>] psr: 60070033 [ 128.771956] sp : ee2b1d68 ip : 00000000 fp : 00000000 [ 128.771968] r10: ee6e641e r9 : ef2d9cc0 r8 : 00000000 [ 128.771982] r7 : ee6e7800 r6 : 00000000 r5 : ee2b0000 r4 : 806a9ccc [ 128.771995] r3 : ef2d9cc0 r2 : 00000000 r1 : ef2d9cc0 r0 : 00000000 [ 128.772011] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment kernel [ 128.772026] Control: 50c5387d Table: aeac406a DAC: 00000015 [ 128.772041] Process irq/85-12c20000 (pid: 1895, stack limit = 0xee2b0238) [ 128.772054] Stack: (0xee2b1d68 to 0xee2b2000) [ 128.772080] 1d60: 00000000 00000000 00000000 00000000 00000400 80654380 [ 128.772105] 1d80: ef07d800 00000002 ef07d800 81767800 00000002 00000000 00000001 80043101 [ 128.772128] 1da0: 00000002 806a9ccc eea47400 0000002e ee6e7800 00000000 ee6e7800 ee6e641e [ 128.772150] 1dc0: 00000000 80288639 8028864d eea47400 ee6e651d 80278af5 81767380 800451c9 [ 128.772173] 1de0: 00000064 ef2d9e18 81767380 80654380 ef2d9cc0 80406a4f ef2d9e18 80037a0d [ 128.772195] 1e00: eea11250 ee2b0000 eea11240 eea11250 eea11240 80406a4f 00000000 ffffffff [ 128.772216] 1e20: ef33a000 80037be5 00000000 80406a4f 00000100 00000001 eea11250 ee2b0000 [ 128.772238] 1e40: eea11250 806582c0 ee75a500 80406a4f eea11250 ee2b0000 00000000 806582c0 [ 128.772260] 1e60: 0000003f 80406a4f eea11240 eea11250 00000000 8027bcdd 00000001 00000000 [ 128.772282] 1e80: ee2b1ebc 271ae71a eea11240 eea11240 eea47400 eea11250 80278a59 ee75a500 [ 128.772304] 1ea0: eea11308 00000001 ee6e651c 8027bbe5 00000000 806a9cac 806a9ccc 00000000 [ 128.772325] 1ec0: 806582c0 0000003f 00000000 ee75a300 00000000 8028d4db 00000000 8003ca2b [ 128.772347] 1ee0: 00000001 ee2b0000 806a9cac 00000001 00000055 00000000 ee75a320 80067da1 [ 128.772368] 1f00: ee75a300 8028dbdd ee75a300 8065c800 ee2b0000 80067db9 00000001 8067b750 [ 128.772390] 1f20: ee2b0000 80067e91 ee75a300 8065c800 ee75a300 00000000 00000000 80067cfd [ 128.772411] 1f40: ee2b1f58 ee6bdcd0 ee2b1f88 ee75a300 80067dd9 00000000 00000000 00000000 [ 128.772432] 1f60: 00000000 80033561 00000000 00000000 000000f8 ee75a300 00000000 00000000 [ 128.772453] 1f80: ee2b1f80 ee2b1f80 00000000 00000000 ee2b1f90 ee2b1f90 00000000 ee6bdcd0 [ 128.772473] 1fa0: 800334f5 00000000 00000000 8000cf3d 00000000 00000000 00000000 00000000 [ 128.772492] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 128.772512] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 128.772564] [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) from [<80288639>] (uart_start+0x1d/0x30) [ 128.772608] [<80288639>] (uart_start+0x1d/0x30) from [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) [ 128.772650] [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) from [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) [ 128.772697] [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) from [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) [ 128.772742] [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) from [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) [ 128.772793] [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) from [<80067db9>] (irq_forced_thread_fn+0x19/0x38) [ 128.772837] [<80067db9>] (irq_forced_thread_fn+0x19/0x38) from [<80067e91>] (irq_thread+0xb9/0x118) [ 128.772884] [<80067e91>] (irq_thread+0xb9/0x118) from [<80033561>] (kthread+0x6d/0x74) [ 128.772932] [<80033561>] (kthread+0x6d/0x74) from [<8000cf3d>] (ret_from_fork+0x11/0x20) [ 128.772962] Code: f7ff fae4 e7ac de02 (de02) 1d23 [ 129.122974] ---[ end trace 0000000000000002 ]--- [ 129.122994] note: irq/85-12c20000[1895] exited with preempt_count 1 [ 129.123041] Unable to handle kernel paging request at virtual address ffffffec [ 129.123049] pgd = 80004000 [ 129.123077] [ffffffec] *pgd=af7fd821, *pte=00000000, *ppte=00000000 [ 129.123095] Internal error: Oops: 17 [#2] PREEMPT SMP THUMB2 [ 129.123108] Modules linked in: [ 129.123131] CPU: 0 PID: 1895 Comm: irq/85-12c20000 Tainted: G D 3.10.6-rt3+ #7 [ 129.123144] task: ef2d9cc0 ti: ee2b0000 task.ti: ee2b0000 [ 129.123173] PC is at kthread_data+0xa/0x10 [ 129.123196] LR is at irq_thread_dtor+0x21/0x80 [ 129.123218] pc : [<80033886>] lr : [<80067d1d>] psr: 800700b3 [ 129.123218] sp : ee2b1bd8 ip : 00000031 fp : 20070093 [ 129.123231] r10: ef2d9cc0 r9 : 80680008 r8 : ee2b0000 [ 129.123243] r7 : ef2d9cc0 r6 : 806d8c88 r5 : 00000000 r4 : ef2d9cc0 [ 129.123254] r3 : 00000000 r2 : 80000000 r1 : ee2b1f38 r0 : ef2d9cc0 [ 129.123269] Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA Thumb Segment user [ 129.123283] Control: 50c5387d Table: aeac406a DAC: 00000015 [ 129.123297] Process irq/85-12c20000 (pid: 1895, stack limit = 0xee2b0238) [ 129.123307] Stack: (0xee2b1bd8 to 0xee2b2000) [ 129.123324] 1bc0: 80067cfd ef2da124 [ 129.123348] 1be0: 00000000 8003136f ee2b0000 002f002f 00000000 0000000b 00000000 00000000 [ 129.123370] 1c00: ee2b1d20 8001f619 20070093 00000001 8053407c 8001dccf 002f002f 806855ec [ 129.123392] 1c20: ee2b0000 806c5f84 0000000b ee2b0000 ee2b1d20 8052fd08 80680008 00000000 [ 129.123413] 1c40: 20070093 8000fcf1 ee2b0238 0000000b 8176f34c 00000000 00030001 00000004 [ 129.123434] 1c60: 0000de02 ee2b1d20 80406b9c ee6e641e 00000000 80008235 00000006 00000002 [ 129.123456] 1c80: 00000004 00000000 00030001 80406b9c 00000193 80651d84 0111c000 80021859 [ 129.123477] 1ca0: 00000001 80021c2b 8176dd84 8006dd4f 00000000 81770380 00000001 00000001 [ 129.123498] 1cc0: 00000001 00000000 00000400 80042a73 0000041d 000003e3 00000400 00000000 [ 129.123519] 1ce0: 80654380 ef07e950 80654380 ef07e8c0 00000000 80654380 ffffffff 00000000 [ 129.123540] 1d00: ee2b1d0c 80406b9e 60070033 ffffffff ee2b1d54 00000000 ef2d9cc0 8000cac1 [ 129.123561] 1d20: 00000000 ef2d9cc0 00000000 ef2d9cc0 806a9ccc ee2b0000 00000000 ee6e7800 [ 129.123581] 1d40: 00000000 ef2d9cc0 ee6e641e 00000000 00000000 ee2b1d68 80406a4f 80406b9c [ 129.123601] 1d60: 60070033 ffffffff 00000000 00000000 00000000 00000000 00000400 80654380 [ 129.123622] 1d80: ef07d800 00000002 ef07d800 81767800 00000002 00000000 00000001 80043101 [ 129.123643] 1da0: 00000002 806a9ccc eea47400 0000002e ee6e7800 00000000 ee6e7800 ee6e641e [ 129.123664] 1dc0: 00000000 80288639 8028864d eea47400 ee6e651d 80278af5 81767380 800451c9 [ 129.123686] 1de0: 00000064 ef2d9e18 81767380 80654380 ef2d9cc0 80406a4f ef2d9e18 80037a0d [ 129.123708] 1e00: eea11250 ee2b0000 eea11240 eea11250 eea11240 80406a4f 00000000 ffffffff [ 129.123729] 1e20: ef33a000 80037be5 00000000 80406a4f 00000100 00000001 eea11250 ee2b0000 [ 129.123750] 1e40: eea11250 806582c0 ee75a500 80406a4f eea11250 ee2b0000 00000000 806582c0 [ 129.123770] 1e60: 0000003f 80406a4f eea11240 eea11250 00000000 8027bcdd 00000001 00000000 [ 129.123792] 1e80: ee2b1ebc 271ae71a eea11240 eea11240 eea47400 eea11250 80278a59 ee75a500 [ 129.123813] 1ea0: eea11308 00000001 ee6e651c 8027bbe5 00000000 806a9cac 806a9ccc 00000000 [ 129.123834] 1ec0: 806582c0 0000003f 00000000 ee75a300 00000000 8028d4db 00000000 8003ca2b [ 129.123855] 1ee0: 00000001 ee2b0000 806a9cac 00000001 00000055 00000000 ee75a320 80067da1 [ 129.123876] 1f00: ee75a300 8028dbdd ee75a300 8065c800 ee2b0000 80067db9 00000001 8067b750 [ 129.123897] 1f20: ee2b0000 80067e91 ee75a300 8065c800 ee75a300 00000000 00000000 80067cfd [ 129.123918] 1f40: ee2b1f58 ee6bdcd0 ee2b1f88 ee75a300 80067dd9 00000000 00000000 00000000 [ 129.123938] 1f60: 00000000 80033561 00000000 00000000 000000f8 ee75a300 00000000 00000000 [ 129.123959] 1f80: ee2b1f80 ee2b1f80 00000001 00010001 ee2b1f90 ee2b1f90 00000000 ee6bdcd0 [ 129.123979] 1fa0: 800334f5 00000000 00000000 8000cf3d 00000000 00000000 00000000 00000000 [ 129.123998] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 129.124017] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 129.124070] [<80033886>] (kthread_data+0xa/0x10) from [<80067d1d>] (irq_thread_dtor+0x21/0x80) [ 129.124116] [<80067d1d>] (irq_thread_dtor+0x21/0x80) from [<8003136f>] (task_work_run+0x73/0xac) [ 129.124156] [<8003136f>] (task_work_run+0x73/0xac) from [<8001f619>] (do_exit+0x215/0x6fc) [ 129.124189] [<8001f619>] (do_exit+0x215/0x6fc) from [<8000fcf1>] (die+0x155/0x1e8) [ 129.124221] [<8000fcf1>] (die+0x155/0x1e8) from [<80008235>] (do_undefinstr+0x69/0x14c) [ 129.124261] [<80008235>] (do_undefinstr+0x69/0x14c) from [<8000cac1>] (__und_svc_finish+0x1/0x40) [ 129.124272] Exception stack(0xee2b1d20 to 0xee2b1d68) [ 129.124296] 1d20: 00000000 ef2d9cc0 00000000 ef2d9cc0 806a9ccc ee2b0000 00000000 ee6e7800 [ 129.124318] 1d40: 00000000 ef2d9cc0 ee6e641e 00000000 00000000 ee2b1d68 80406a4f 80406b9c [ 129.124329] 1d60: 60070033 ffffffff [ 129.124372] [<8000cac1>] (__und_svc_finish+0x1/0x40) from [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) [ 129.124408] [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) from [<80288639>] (uart_start+0x1d/0x30) [ 129.124445] [<80288639>] (uart_start+0x1d/0x30) from [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) [ 129.124484] [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) from [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) [ 129.124527] [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) from [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) [ 129.124569] [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) from [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) [ 129.124615] [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) from [<80067db9>] (irq_forced_thread_fn+0x19/0x38) [ 129.124657] [<80067db9>] (irq_forced_thread_fn+0x19/0x38) from [<80067e91>] (irq_thread+0xb9/0x118) [ 129.124700] [<80067e91>] (irq_thread+0xb9/0x118) from [<80033561>] (kthread+0x6d/0x74) [ 129.124745] [<80033561>] (kthread+0x6d/0x74) from [<8000cf3d>] (ret_from_fork+0x11/0x20) [ 129.124775] Code: f85d eb04 f8d0 3264 (f853) 0c14
---------x-----------------x------------
Here we haven't scheduled work from tty_flip_buffer_push() because of following change in RT kernel:
commit 714cc6dc551136b8f88b53361b504a5f624308b9 Author: Ingo Molnar mingo@elte.hu Date: Fri Jul 3 08:30:01 2009 -0500
serial: 8250: Call flush_to_ldisc when the irq is threaded
Signed-off-by: Ingo Molnar mingo@elte.hu --- drivers/tty/tty_buffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 9121c1f..94d3215 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -517,10 +517,15 @@ void tty_flip_buffer_push(struct tty_port *port) buf->tail->commit = buf->tail->used; spin_unlock_irqrestore(&buf->lock, flags);
+#ifndef CONFIG_PREEMPT_RT_FULL if (port->low_latency) flush_to_ldisc(&buf->work); else schedule_work(&buf->work); +#else + flush_to_ldisc(&buf->work); +#endif + } EXPORT_SYMBOL(tty_flip_buffer_push);
@@ -545,4 +550,3 @@ void tty_buffer_init(struct tty_port *port) buf->memory_used = 0; INIT_WORK(&buf->work, flush_to_ldisc); }
---------x------------------x-------------------
How do you guys suggest me to fix this problem now? The fix I suggested? Or something specific to the RT kernel only? Or maybe send these patches for RT kernel only.
One more thing: We are calling tty_flip_buffer_push() with (from interrupt context) and without (from process context) port->lock held.. Shouldn't we make this flat, like don't acquire port->lock while calling tty_flip_buffer_push() as that may cause recursive locking?
Thanks for your help and patience.
-- viresh
On 08/20/2013 06:52 AM, Viresh Kumar wrote:
Hi Peter,
On 20 August 2013 08:05, Peter Hurley peter@hurleysoftware.com wrote:
The key to why the flush_to_disc() worker thread cannot acquire the uart_port spinlock is in the first stack trace:
s3c24xx_serial_rx_chars raw_spin_unlock_irqrestore do_raw_spin_unlock dump_stack
So the real question here is why do_raw_spin_unlock() is doing a dump_stack()? Is one of the SPIN_BUG_ON() asserts in debug_spin_unlock() triggering?
Ahh, you are right and SPIN_BUG_ON() is indeed getting asserted.
I am embarrassed to say this but it happened due to my stupid mistake :(
And yes, non-rt kernels doesn't see this crash as we simply schedule work from our interrupt handlers instead of calling flush_to_ldisc()
This is how I got the wrong crash dump:
- Applied my patch over latest linux-next
- Some more debug messages
Tested: No crashes found..
Thought maybe I should try without my patch first, if it really crashes or not.
- Reverted my patch and got some conflicts due the "debug patch"..
and ended up resolving them in the wrong way:
spin_unlock_irqrestore(&port->lock, flags); pr_info("%s\n", __func__); tty_flip_buffer_push(&port->state->port);
spin_unlock_irqrestore(&port->lock, flags);
out:
spin_unlock_irqrestore(&port->lock, flags);
Got two unlocks and so the dump.. Sorry for the incorrect information :(
No need to apologize. At least this part of the mystery is solved.
But yes there are some issues with the RT kernel, which are going to stay without this patchset.. Here are the logs with 3.10.6 + rt kernel (attached as well, in case lines are wrapped by gmail :( ):
root@localhost:~# [ 128.771800] ------------[ cut here ]------------ [ 128.771815] kernel BUG at /home/arm/work/kernel/linaro/lng/lng.git/kernel/rtmutex.c:738! [ 128.771829] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP THUMB2 [ 128.771844] Modules linked in: [ 128.771868] CPU: 0 PID: 1895 Comm: irq/85-12c20000 Not tainted 3.10.6-rt3+ #7 [ 128.771885] task: ef2d9cc0 ti: ee2b0000 task.ti: ee2b0000 [ 128.771915] PC is at rt_spin_lock_slowlock+0x18c/0x1a0 [ 128.771933] LR is at rt_spin_lock_slowlock+0x3f/0x1a0 [ 128.771956] pc : [<80406b9c>] lr : [<80406a4f>] psr: 60070033 [ 128.771956] sp : ee2b1d68 ip : 00000000 fp : 00000000 [ 128.771968] r10: ee6e641e r9 : ef2d9cc0 r8 : 00000000 [ 128.771982] r7 : ee6e7800 r6 : 00000000 r5 : ee2b0000 r4 : 806a9ccc [ 128.771995] r3 : ef2d9cc0 r2 : 00000000 r1 : ef2d9cc0 r0 : 00000000 [ 128.772011] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment kernel [ 128.772026] Control: 50c5387d Table: aeac406a DAC: 00000015 [ 128.772041] Process irq/85-12c20000 (pid: 1895, stack limit = 0xee2b0238) [ 128.772054] Stack: (0xee2b1d68 to 0xee2b2000) [ 128.772080] 1d60: 00000000 00000000 00000000 00000000 00000400 80654380 [ 128.772105] 1d80: ef07d800 00000002 ef07d800 81767800 00000002 00000000 00000001 80043101 [ 128.772128] 1da0: 00000002 806a9ccc eea47400 0000002e ee6e7800 00000000 ee6e7800 ee6e641e [ 128.772150] 1dc0: 00000000 80288639 8028864d eea47400 ee6e651d 80278af5 81767380 800451c9 [ 128.772173] 1de0: 00000064 ef2d9e18 81767380 80654380 ef2d9cc0 80406a4f ef2d9e18 80037a0d [ 128.772195] 1e00: eea11250 ee2b0000 eea11240 eea11250 eea11240 80406a4f 00000000 ffffffff [ 128.772216] 1e20: ef33a000 80037be5 00000000 80406a4f 00000100 00000001 eea11250 ee2b0000 [ 128.772238] 1e40: eea11250 806582c0 ee75a500 80406a4f eea11250 ee2b0000 00000000 806582c0 [ 128.772260] 1e60: 0000003f 80406a4f eea11240 eea11250 00000000 8027bcdd 00000001 00000000 [ 128.772282] 1e80: ee2b1ebc 271ae71a eea11240 eea11240 eea47400 eea11250 80278a59 ee75a500 [ 128.772304] 1ea0: eea11308 00000001 ee6e651c 8027bbe5 00000000 806a9cac 806a9ccc 00000000 [ 128.772325] 1ec0: 806582c0 0000003f 00000000 ee75a300 00000000 8028d4db 00000000 8003ca2b [ 128.772347] 1ee0: 00000001 ee2b0000 806a9cac 00000001 00000055 00000000 ee75a320 80067da1 [ 128.772368] 1f00: ee75a300 8028dbdd ee75a300 8065c800 ee2b0000 80067db9 00000001 8067b750 [ 128.772390] 1f20: ee2b0000 80067e91 ee75a300 8065c800 ee75a300 00000000 00000000 80067cfd [ 128.772411] 1f40: ee2b1f58 ee6bdcd0 ee2b1f88 ee75a300 80067dd9 00000000 00000000 00000000 [ 128.772432] 1f60: 00000000 80033561 00000000 00000000 000000f8 ee75a300 00000000 00000000 [ 128.772453] 1f80: ee2b1f80 ee2b1f80 00000000 00000000 ee2b1f90 ee2b1f90 00000000 ee6bdcd0 [ 128.772473] 1fa0: 800334f5 00000000 00000000 8000cf3d 00000000 00000000 00000000 00000000 [ 128.772492] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 128.772512] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 128.772564] [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) from [<80288639>] (uart_start+0x1d/0x30) [ 128.772608] [<80288639>] (uart_start+0x1d/0x30) from [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) [ 128.772650] [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) from [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) [ 128.772697] [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) from [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) [ 128.772742] [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) from [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) [ 128.772793] [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) from [<80067db9>] (irq_forced_thread_fn+0x19/0x38) [ 128.772837] [<80067db9>] (irq_forced_thread_fn+0x19/0x38) from [<80067e91>] (irq_thread+0xb9/0x118) [ 128.772884] [<80067e91>] (irq_thread+0xb9/0x118) from [<80033561>] (kthread+0x6d/0x74) [ 128.772932] [<80033561>] (kthread+0x6d/0x74) from [<8000cf3d>] (ret_from_fork+0x11/0x20) [ 128.772962] Code: f7ff fae4 e7ac de02 (de02) 1d23 [ 129.122974] ---[ end trace 0000000000000002 ]--- [ 129.122994] note: irq/85-12c20000[1895] exited with preempt_count 1 [ 129.123041] Unable to handle kernel paging request at virtual address ffffffec [ 129.123049] pgd = 80004000 [ 129.123077] [ffffffec] *pgd=af7fd821, *pte=00000000, *ppte=00000000 [ 129.123095] Internal error: Oops: 17 [#2] PREEMPT SMP THUMB2 [ 129.123108] Modules linked in: [ 129.123131] CPU: 0 PID: 1895 Comm: irq/85-12c20000 Tainted: G D 3.10.6-rt3+ #7 [ 129.123144] task: ef2d9cc0 ti: ee2b0000 task.ti: ee2b0000 [ 129.123173] PC is at kthread_data+0xa/0x10 [ 129.123196] LR is at irq_thread_dtor+0x21/0x80 [ 129.123218] pc : [<80033886>] lr : [<80067d1d>] psr: 800700b3 [ 129.123218] sp : ee2b1bd8 ip : 00000031 fp : 20070093 [ 129.123231] r10: ef2d9cc0 r9 : 80680008 r8 : ee2b0000 [ 129.123243] r7 : ef2d9cc0 r6 : 806d8c88 r5 : 00000000 r4 : ef2d9cc0 [ 129.123254] r3 : 00000000 r2 : 80000000 r1 : ee2b1f38 r0 : ef2d9cc0 [ 129.123269] Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA Thumb Segment user [ 129.123283] Control: 50c5387d Table: aeac406a DAC: 00000015 [ 129.123297] Process irq/85-12c20000 (pid: 1895, stack limit = 0xee2b0238) [ 129.123307] Stack: (0xee2b1bd8 to 0xee2b2000) [ 129.123324] 1bc0: 80067cfd ef2da124 [ 129.123348] 1be0: 00000000 8003136f ee2b0000 002f002f 00000000 0000000b 00000000 00000000 [ 129.123370] 1c00: ee2b1d20 8001f619 20070093 00000001 8053407c 8001dccf 002f002f 806855ec [ 129.123392] 1c20: ee2b0000 806c5f84 0000000b ee2b0000 ee2b1d20 8052fd08 80680008 00000000 [ 129.123413] 1c40: 20070093 8000fcf1 ee2b0238 0000000b 8176f34c 00000000 00030001 00000004 [ 129.123434] 1c60: 0000de02 ee2b1d20 80406b9c ee6e641e 00000000 80008235 00000006 00000002 [ 129.123456] 1c80: 00000004 00000000 00030001 80406b9c 00000193 80651d84 0111c000 80021859 [ 129.123477] 1ca0: 00000001 80021c2b 8176dd84 8006dd4f 00000000 81770380 00000001 00000001 [ 129.123498] 1cc0: 00000001 00000000 00000400 80042a73 0000041d 000003e3 00000400 00000000 [ 129.123519] 1ce0: 80654380 ef07e950 80654380 ef07e8c0 00000000 80654380 ffffffff 00000000 [ 129.123540] 1d00: ee2b1d0c 80406b9e 60070033 ffffffff ee2b1d54 00000000 ef2d9cc0 8000cac1 [ 129.123561] 1d20: 00000000 ef2d9cc0 00000000 ef2d9cc0 806a9ccc ee2b0000 00000000 ee6e7800 [ 129.123581] 1d40: 00000000 ef2d9cc0 ee6e641e 00000000 00000000 ee2b1d68 80406a4f 80406b9c [ 129.123601] 1d60: 60070033 ffffffff 00000000 00000000 00000000 00000000 00000400 80654380 [ 129.123622] 1d80: ef07d800 00000002 ef07d800 81767800 00000002 00000000 00000001 80043101 [ 129.123643] 1da0: 00000002 806a9ccc eea47400 0000002e ee6e7800 00000000 ee6e7800 ee6e641e [ 129.123664] 1dc0: 00000000 80288639 8028864d eea47400 ee6e651d 80278af5 81767380 800451c9 [ 129.123686] 1de0: 00000064 ef2d9e18 81767380 80654380 ef2d9cc0 80406a4f ef2d9e18 80037a0d [ 129.123708] 1e00: eea11250 ee2b0000 eea11240 eea11250 eea11240 80406a4f 00000000 ffffffff [ 129.123729] 1e20: ef33a000 80037be5 00000000 80406a4f 00000100 00000001 eea11250 ee2b0000 [ 129.123750] 1e40: eea11250 806582c0 ee75a500 80406a4f eea11250 ee2b0000 00000000 806582c0 [ 129.123770] 1e60: 0000003f 80406a4f eea11240 eea11250 00000000 8027bcdd 00000001 00000000 [ 129.123792] 1e80: ee2b1ebc 271ae71a eea11240 eea11240 eea47400 eea11250 80278a59 ee75a500 [ 129.123813] 1ea0: eea11308 00000001 ee6e651c 8027bbe5 00000000 806a9cac 806a9ccc 00000000 [ 129.123834] 1ec0: 806582c0 0000003f 00000000 ee75a300 00000000 8028d4db 00000000 8003ca2b [ 129.123855] 1ee0: 00000001 ee2b0000 806a9cac 00000001 00000055 00000000 ee75a320 80067da1 [ 129.123876] 1f00: ee75a300 8028dbdd ee75a300 8065c800 ee2b0000 80067db9 00000001 8067b750 [ 129.123897] 1f20: ee2b0000 80067e91 ee75a300 8065c800 ee75a300 00000000 00000000 80067cfd [ 129.123918] 1f40: ee2b1f58 ee6bdcd0 ee2b1f88 ee75a300 80067dd9 00000000 00000000 00000000 [ 129.123938] 1f60: 00000000 80033561 00000000 00000000 000000f8 ee75a300 00000000 00000000 [ 129.123959] 1f80: ee2b1f80 ee2b1f80 00000001 00010001 ee2b1f90 ee2b1f90 00000000 ee6bdcd0 [ 129.123979] 1fa0: 800334f5 00000000 00000000 8000cf3d 00000000 00000000 00000000 00000000 [ 129.123998] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 129.124017] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 129.124070] [<80033886>] (kthread_data+0xa/0x10) from [<80067d1d>] (irq_thread_dtor+0x21/0x80) [ 129.124116] [<80067d1d>] (irq_thread_dtor+0x21/0x80) from [<8003136f>] (task_work_run+0x73/0xac) [ 129.124156] [<8003136f>] (task_work_run+0x73/0xac) from [<8001f619>] (do_exit+0x215/0x6fc) [ 129.124189] [<8001f619>] (do_exit+0x215/0x6fc) from [<8000fcf1>] (die+0x155/0x1e8) [ 129.124221] [<8000fcf1>] (die+0x155/0x1e8) from [<80008235>] (do_undefinstr+0x69/0x14c) [ 129.124261] [<80008235>] (do_undefinstr+0x69/0x14c) from [<8000cac1>] (__und_svc_finish+0x1/0x40) [ 129.124272] Exception stack(0xee2b1d20 to 0xee2b1d68) [ 129.124296] 1d20: 00000000 ef2d9cc0 00000000 ef2d9cc0 806a9ccc ee2b0000 00000000 ee6e7800 [ 129.124318] 1d40: 00000000 ef2d9cc0 ee6e641e 00000000 00000000 ee2b1d68 80406a4f 80406b9c [ 129.124329] 1d60: 60070033 ffffffff [ 129.124372] [<8000cac1>] (__und_svc_finish+0x1/0x40) from [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) [ 129.124408] [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) from [<80288639>] (uart_start+0x1d/0x30) [ 129.124445] [<80288639>] (uart_start+0x1d/0x30) from [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) [ 129.124484] [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) from [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) [ 129.124527] [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) from [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) [ 129.124569] [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) from [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) [ 129.124615] [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) from [<80067db9>] (irq_forced_thread_fn+0x19/0x38) [ 129.124657] [<80067db9>] (irq_forced_thread_fn+0x19/0x38) from [<80067e91>] (irq_thread+0xb9/0x118) [ 129.124700] [<80067e91>] (irq_thread+0xb9/0x118) from [<80033561>] (kthread+0x6d/0x74) [ 129.124745] [<80033561>] (kthread+0x6d/0x74) from [<8000cf3d>] (ret_from_fork+0x11/0x20) [ 129.124775] Code: f85d eb04 f8d0 3264 (f853) 0c14
In light of the RT patch below, completely understandable why it crashes.
PS - Not automagic formatting, unless you consider my hand-editing automagic.
---------x-----------------x------------
Here we haven't scheduled work from tty_flip_buffer_push() because of following change in RT kernel:
commit 714cc6dc551136b8f88b53361b504a5f624308b9 Author: Ingo Molnar mingo@elte.hu Date: Fri Jul 3 08:30:01 2009 -0500
serial: 8250: Call flush_to_ldisc when the irq is threaded Signed-off-by: Ingo Molnar <mingo@elte.hu>
drivers/tty/tty_buffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 9121c1f..94d3215 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -517,10 +517,15 @@ void tty_flip_buffer_push(struct tty_port *port) buf->tail->commit = buf->tail->used; spin_unlock_irqrestore(&buf->lock, flags);
+#ifndef CONFIG_PREEMPT_RT_FULL if (port->low_latency) flush_to_ldisc(&buf->work); else schedule_work(&buf->work); +#else
flush_to_ldisc(&buf->work);
+#endif
As you've discovered, not correct for 25+ drivers, including the samsung driver.
- } EXPORT_SYMBOL(tty_flip_buffer_push);
@@ -545,4 +550,3 @@ void tty_buffer_init(struct tty_port *port) buf->memory_used = 0; INIT_WORK(&buf->work, flush_to_ldisc); }
---------x------------------x-------------------
How do you guys suggest me to fix this problem now? The fix I suggested? Or something specific to the RT kernel only? Or maybe send these patches for RT kernel only.
That's really Greg's call whether he wants to take up RT-specific patches into the regular tree.
One more thing: We are calling tty_flip_buffer_push() with (from interrupt context) and without (from process context) port->lock held. Shouldn't we make this flat, like don't acquire port->lock while calling tty_flip_buffer_push() as that may cause recursive locking?
The tty buffer interface is designed for a single producer so provides no locking of its own. Provided a uart port mini-driver only uses the tty buffer interface serially, then no locking is required (to protect the internals of the tty buffer).
When you note that tty_flip_buffer_push() is called from 'process context', I assume you mean kworker threads handling rx DMA. Besides the pty driver and the fwserial staging driver that has loopback mode, I'm not aware of any other drivers that do rx from process context.
Regards, Peter Hurley
On 21 August 2013 01:08, Peter Hurley peter@hurleysoftware.com wrote:
On 08/20/2013 06:52 AM, Viresh Kumar wrote:
That's really Greg's call whether he wants to take up RT-specific patches into the regular tree.
Yeah.. Lets wait for Greg..
One more thing: We are calling tty_flip_buffer_push() with (from interrupt context) and without (from process context) port->lock held. Shouldn't we
make this flat, like don't acquire port->lock while calling tty_flip_buffer_push() as that may cause recursive locking?
When you note that tty_flip_buffer_push() is called from 'process context', I assume you mean kworker threads handling rx DMA. Besides the pty driver and the fwserial staging driver that has loopback mode, I'm not aware of any other drivers that do rx from process context.
Okay.. And so most of the people call it from interrupt context (25+ of them, I am trying to fix for RT and others are already doing the right thing) and all of these must have set port->low_latency to false.
Now my questions is, what exactly we want to protect in this function while calling it from interrupt or process context? For which we need a port->lock to be held by caller?
There are drivers which are sustaining without a lock being held by caller and others shouldn't have any problem doing that... That might be a clean solution for Mainline and that will fix the RT issues we are facing :)
-- viresh
On 21 August 2013 10:05, Viresh Kumar viresh.kumar@linaro.org wrote:
On 21 August 2013 01:08, Peter Hurley peter@hurleysoftware.com wrote:
On 08/20/2013 06:52 AM, Viresh Kumar wrote:
That's really Greg's call whether he wants to take up RT-specific patches into the regular tree.
Yeah.. Lets wait for Greg..
Hi Greg,
Should I resend my patches with better commit logs if you are going to take these patches?
-- viresh
On Fri, Aug 23, 2013 at 01:56:08PM +0530, Viresh Kumar wrote:
On 21 August 2013 10:05, Viresh Kumar viresh.kumar@linaro.org wrote:
On 21 August 2013 01:08, Peter Hurley peter@hurleysoftware.com wrote:
On 08/20/2013 06:52 AM, Viresh Kumar wrote:
That's really Greg's call whether he wants to take up RT-specific patches into the regular tree.
Yeah.. Lets wait for Greg..
Hi Greg,
Should I resend my patches with better commit logs if you are going to take these patches?
No need, I took them as-is, thanks for doing this work.
greg k-h
On 28 August 2013 04:49, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
No need, I took them as-is, thanks for doing this work.
Thanks Greg..
But I think the current commit log is poor and doesn't communicate the problem well.. I have prepared another patchset with the same diff and updated log (below), I can resend them if you are willing to drop current version and take next one..
----------x--------------x---------------------
The current driver triggers a lockdep warning for RT kernel if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels on RT kernels.
This happened due to following commit in rt kernels:
commit 714cc6dc551136b8f88b53361b504a5f624308b9 Author: Ingo Molnar mingo@elte.hu Date: Fri Jul 3 08:30:01 2009 -0500
serial: 8250: Call flush_to_ldisc when the irq is threaded
Signed-off-by: Ingo Molnar mingo@elte.hu --- drivers/tty/tty_buffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 9121c1f..94d3215 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -517,10 +517,15 @@ void tty_flip_buffer_push(struct tty_port *port) buf->tail->commit = buf->tail->used; spin_unlock_irqrestore(&buf->lock, flags);
+#ifndef CONFIG_PREEMPT_RT_FULL if (port->low_latency) flush_to_ldisc(&buf->work); else schedule_work(&buf->work); +#else + flush_to_ldisc(&buf->work); +#endif + } EXPORT_SYMBOL(tty_flip_buffer_push);
And the crash looks like this (produced with samsung.c driver):
----- kernel BUG at /home/arm/work/kernel/linaro/lng/lng.git/kernel/rtmutex.c:738! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP THUMB2 Modules linked in: CPU: 0 PID: 1895 Comm: irq/85-12c20000 Not tainted 3.10.6-rt3+ #7 task: ef2d9cc0 ti: ee2b0000 task.ti: ee2b0000 PC is at rt_spin_lock_slowlock+0x18c/0x1a0 LR is at rt_spin_lock_slowlock+0x3f/0x1a0 pc : [<80406b9c>] lr : [<80406a4f>] psr: 60070033 sp : ee2b1d68 ip : 00000000 fp : 00000000 r10: ee6e641e r9 : ef2d9cc0 r8 : 00000000 r7 : ee6e7800 r6 : 00000000 r5 : ee2b0000 r4 : 806a9ccc r3 : ef2d9cc0 r2 : 00000000 r1 : ef2d9cc0 r0 : 00000000 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment kernel Control: 50c5387d Table: aeac406a DAC: 00000015 Process irq/85-12c20000 (pid: 1895, stack limit = 0xee2b0238) Stack: (0xee2b1d68 to 0xee2b2000)
[snip]
[<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) from [<80288639>] (uart_start+0x1d/0x30) [<80288639>] (uart_start+0x1d/0x30) from [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) from [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) from [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) from [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) from [<80067db9>] (irq_forced_thread_fn+0x19/0x38) [<80067db9>] (irq_forced_thread_fn+0x19/0x38) from [<80067e91>] (irq_thread+0xb9/0x118) [<80067e91>] (irq_thread+0xb9/0x118) from [<80033561>] (kthread+0x6d/0x74) [<80033561>] (kthread+0x6d/0x74) from [<8000cf3d>] (ret_from_fork+0x11/0x20) Code: f7ff fae4 e7ac de02 (de02) 1d23 ---[ end trace 0000000000000002 ]--- note: irq/85-12c20000[1895] exited with preempt_count 1 Unable to handle kernel paging request at virtual address ffffffec pgd = 80004000 [ffffffec] *pgd=af7fd821, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#2] PREEMPT SMP THUMB2 Modules linked in: CPU: 0 PID: 1895 Comm: irq/85-12c20000 Tainted: G D 3.10.6-rt3+ #7 task: ef2d9cc0 ti: ee2b0000 task.ti: ee2b0000 PC is at kthread_data+0xa/0x10 LR is at irq_thread_dtor+0x21/0x80
[snip]
[<80033886>] (kthread_data+0xa/0x10) from [<80067d1d>] (irq_thread_dtor+0x21/0x80) [<80067d1d>] (irq_thread_dtor+0x21/0x80) from [<8003136f>] (task_work_run+0x73/0xac) [<8003136f>] (task_work_run+0x73/0xac) from [<8001f619>] (do_exit+0x215/0x6fc) [<8001f619>] (do_exit+0x215/0x6fc) from [<8000fcf1>] (die+0x155/0x1e8) [<8000fcf1>] (die+0x155/0x1e8) from [<80008235>] (do_undefinstr+0x69/0x14c) [<80008235>] (do_undefinstr+0x69/0x14c) from [<8000cac1>] (__und_svc_finish+0x1/0x40) Exception stack(0xee2b1d20 to 0xee2b1d68) 1d20: 00000000 ef2d9cc0 00000000 ef2d9cc0 806a9ccc ee2b0000 00000000 ee6e7800 1d40: 00000000 ef2d9cc0 ee6e641e 00000000 00000000 ee2b1d68 80406a4f 80406b9c 1d60: 60070033 ffffffff [<8000cac1>] (__und_svc_finish+0x1/0x40) from [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) [<80406b9c>] (rt_spin_lock_slowlock+0x18c/0x1a0) from [<80288639>] (uart_start+0x1d/0x30) [<80288639>] (uart_start+0x1d/0x30) from [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) [<80278af5>] (n_tty_receive_buf+0x9d/0xbf0) from [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) [<8027bbe5>] (flush_to_ldisc+0xb5/0xe8) from [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) [<8028d4db>] (s3c24xx_serial_rx_chars+0xbf/0x19c) from [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) [<8028dbdd>] (s3c64xx_serial_handle_irq+0x31/0x38) from [<80067db9>] (irq_forced_thread_fn+0x19/0x38) [<80067db9>] (irq_forced_thread_fn+0x19/0x38) from [<80067e91>] (irq_thread+0xb9/0x118) [<80067e91>] (irq_thread+0xb9/0x118) from [<80033561>] (kthread+0x6d/0x74) [<80033561>] (kthread+0x6d/0x74) from [<8000cf3d>] (ret_from_fork+0x11/0x20)
Moreoever port->lock isn't really required before calling tty_flip_buffer_push() and hence its better to make changes in mainline kernel instead of RT kernel.
Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call.
Similar stuff was already done for few other drivers in the past, like:
commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner tglx@linutronix.de Date: Tue May 29 21:53:50 2007 +0100
[ARM] 4417/1: Serial: Fix AMBA drivers locking
Cc: Tobias Klauser tklauser@distanz.ch
On Wed, Aug 28, 2013 at 09:01:25AM +0530, Viresh Kumar wrote:
On 28 August 2013 04:49, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
No need, I took them as-is, thanks for doing this work.
Thanks Greg..
But I think the current commit log is poor and doesn't communicate the problem well.. I have prepared another patchset with the same diff and updated log (below), I can resend them if you are willing to drop current version and take next one..
I can't drop them, I could revert them, and then apply the new ones, but that's just doing 50 patches of "churn" for no good reason. I assumed that if you really wanted the changelog changed, you would have sent me updated versions by now, so I went with what you had. :)
It's fine, don't worry.
greg k-h
On 28 August 2013 09:13, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
I can't drop them, I could revert them, and then apply the new ones, but that's just doing 50 patches of "churn" for no good reason.
Agreed..
I assumed that if you really wanted the changelog changed, you would have sent me updated versions by now, so I went with what you had. :)
I didn't wanted to spam LKML with another 25 patches in case you weren't going to apply them.. And that's why asked you specifically this:
"Should I resend my patches with better commit logs if you are going to take these patches?"
:)
It's fine, don't worry.
Okay.. Thanks.
On 28 August 2013 04:49, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
No need, I took them as-is, thanks for doing this work.
I believe this must go to few stable releases as well.. ??
On Wed, Aug 28, 2013 at 11:28:48AM +0530, Viresh Kumar wrote:
On 28 August 2013 04:49, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
No need, I took them as-is, thanks for doing this work.
I believe this must go to few stable releases as well.. ??
Why, as it doesn't cause problems unless you are running rt kernels at the moment, right? Is there some other way to trigger the problem that you know of?
Remember, stable is for "real" problems :)
thanks,
greg k-h
On 28 August 2013 11:35, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
Why, as it doesn't cause problems unless you are running rt kernels at the moment, right? Is there some other way to trigger the problem that you know of?
No, its only coming for RT kernels...
Remember, stable is for "real" problems :)
I faced this issue while working on 3.10 rt kernel and so asked :)
On Wed, Aug 28, 2013 at 11:37:21AM +0530, Viresh Kumar wrote:
On 28 August 2013 11:35, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
Why, as it doesn't cause problems unless you are running rt kernels at the moment, right? Is there some other way to trigger the problem that you know of?
No, its only coming for RT kernels...
Remember, stable is for "real" problems :)
I faced this issue while working on 3.10 rt kernel and so asked :)
Ask the -rt developers to add it to their patchset if it affects those kernels.
linaro-kernel@lists.linaro.org