Re: [PATCH v3] tty: serial: meson: hard LOCKUP on crtscts mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 12/10/2023 17:25, Pavel Krasavin wrote:
From: Pavel Krasavin <pkrasavin@xxxxxxxxxxx>

There might be hard lockup if we set crtscts mode on port without RTS/CTS configured:

# stty -F /dev/ttyAML6 crtscts; echo 1 > /dev/ttyAML6; echo 2 > /dev/ttyAML6
[   95.890386] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
[   95.890857] rcu:     3-...0: (201 ticks this GP) idle=e33c/1/0x4000000000000000 softirq=5844/5846 fqs=4984
[   95.900212] rcu:     (detected by 2, t=21016 jiffies, g=7753, q=296 ncpus=4)
[   95.906972] Task dump for CPU 3:
[   95.910178] task:bash            state:R  running task     stack:0     pid:205   ppid:1      flags:0x00000202
[   95.920059] Call trace:
[   95.922485]  __switch_to+0xe4/0x168
[   95.925951]  0xffffff8003477508
[   95.974379] watchdog: Watchdog detected hard LOCKUP on cpu 3
[   95.974424] Modules linked in: 88x2cs(O) rtc_meson_vrtc

Possible solution would be to not allow to setup crtscts on such port.

Tested on S905X3 based board.

Signed-off-by: Pavel Krasavin <pkrasavin@xxxxxxxxxxx>
---
v3: "From:" line added to the mail
v2: https://lore.kernel.org/lkml/OF950BEF72.7F425944-ON00258A46.00488A76-00258A46.00497D44@xxxxxx/
braces for single statement removed according to Dmitry's note
v1: https://lore.kernel.org/lkml/OF28B2B8C9.5BC0CD28-ON00258A46.0037688F-00258A46.0039155B@xxxxxx/
---

--- a/drivers/tty/serial/meson_uart.c	2023-10-12 15:44:02.410538523 +0300
+++ b/drivers/tty/serial/meson_uart.c	2023-10-12 15:58:06.242395253 +0300
@@ -380,10 +380,14 @@ static void meson_uart_set_termios(struc
  	else
  		val |= AML_UART_STOP_BIT_1SB;
- if (cflags & CRTSCTS)
-		val &= ~AML_UART_TWO_WIRE_EN;
-	else
+	if (cflags & CRTSCTS) {
+		if (port->flags & UPF_HARD_FLOW)
+			val &= ~AML_UART_TWO_WIRE_EN;
+		else
+			termios->c_cflag &= ~CRTSCTS;
+	} else {
  		val |= AML_UART_TWO_WIRE_EN;
+	}
writel(val, port->membase + AML_UART_CONTROL); @@ -705,6 +709,7 @@ static int meson_uart_probe(struct platf
  	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
  	int ret = 0;
  	int irq;
+	bool has_rtscts;
if (pdev->dev.of_node)
  		pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
@@ -732,6 +737,7 @@ static int meson_uart_probe(struct platf
  		return irq;
of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize);
+	has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts");
if (meson_ports[pdev->id]) {
  		return dev_err_probe(&pdev->dev, -EBUSY,
@@ -762,6 +768,8 @@ static int meson_uart_probe(struct platf
  	port->mapsize = resource_size(res_mem);
  	port->irq = irq;
  	port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY;
+	if (has_rtscts)
+		port->flags |= UPF_HARD_FLOW;
  	port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE);
  	port->dev = &pdev->dev;
  	port->line = pdev->id;

Looks fine, I expected the tty core to check uart-has-rtscts or UPF_HARD_FLOW, but seems I was naive.

LGTM
Reviewed-by: Neil Armstrong <neil.armstrong@xxxxxxxxxx>



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux