[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20260129103129.2928955-1-jackzxcui1989@163.com>
Date: Thu, 29 Jan 2026 18:31:29 +0800
From: Xin Zhao <jackzxcui1989@....com>
To: m.szyprowski@...sung.com
Cc: gregkh@...uxfoundation.org,
hch@...radead.org,
jackzxcui1989@....com,
jirislaby@...nel.org,
linux-kernel@...r.kernel.org,
linux-serial@...r.kernel.org,
tj@...nel.org,
tommaso.merciai.xr@...renesas.com,
geert@...ux-m68k.org
Subject: Re: [PATCH v8] tty: tty_port: add workqueue to flip TTY buffer
Hi all,
Sorry for the problems! I didn't consider all the situation.
On Tue, 27 Jan 2026 11:34:32 +0100 Marek Szyprowski <m.szyprowski@...sung.com> wrote:
> It looks that driver->name is not unique on some systems, see:
>
> $ git grep ttyMSM drivers/tty/
> drivers/tty/serial/msm_serial.c: .name = "ttyMSM",
> drivers/tty/serial/msm_serial.c: .dev_name = "ttyMSM",
> drivers/tty/serial/qcom_geni_serial.c: .name = "ttyMSM",
> drivers/tty/serial/qcom_geni_serial.c: .dev_name = "ttyMSM",
>
> This fails on Qualcomm RB5 boards, breaking the boot process (booting
> hangs, because drivers try to use the unregistered wq):
I think I should use the name format "%s-%s-flip-wq", ..., driver->name, driver->driver_name
as you suggested, and remove the 'flip-wq' part to avoid exceeding the WQ_NAME_LEN limit.
I checked the lengths of all dev_name + driver_name in all tty/* files, and none exceeded
WQ_NAME_LEN (32).
> The other issue with this patch I've observed on ARM Juno R1 board. With
> one of the above fixes for the workqueue name, the boot process is still
> broken because of the NULL pointer dereference:
>
> input: gpio-keys as /de ** replaying previous printk message ** input:
> gpio-keys as /devices/platform/gpio-keys/input/input3 Unable to handle
> kernel NULL pointer dereference at virtual address 00000000000001c0 Mem
> abort info: ... [00000000000001c0] user address but active_mm is swapper
> Internal error: Oops: 0000000096000004 [#1] SMP Modules linked in: CPU:
> 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.19.0-rc7-next-20260126+
> #16443 PREEMPT Hardware name: ARM Juno development board (r1) (DT)
> pstate: 400000c5 (nZcv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc :
> __queue_work+0x30/0x7c4 lr : queue_work_on+0xac/0xdc ... Call trace:
> __queue_work+0x30/0x7c4 (P) queue_work_on+0xac/0xdc
> tty_flip_buffer_push+0x2c/0x38 k_fn.part.0+0x7c/0xc8 k_fn+0x20/0x2c
> kbd_event+0x2d8/0x504 input_handle_events_default+0x50/0x74
> input_pass_values+0x148/0x2b4 input_handle_event+0xcc/0x5e0
> input_event+0x64/0xa4 gpio_keys_open+0x9c/0xc4
> input_open_device+0x8c/0x128 kbd_connect+0x84/0xa0
> input_attach_handler+0x9c/0xf4 input_register_device+0x308/0x48c
> gpio_keys_probe+0x40c/0xafc platform_probe+0x5c/0xac
> really_probe+0xbc/0x298 __driver_probe_device+0x78/0x12c
> driver_probe_device+0xdc/0x164 __driver_attach+0xe4/0x224
> bus_for_each_dev+0x74/0xd0 driver_attach+0x24/0x30
> bus_add_driver+0xe4/0x208 driver_register+0x60/0x128
> __platform_driver_register+0x24/0x30 gpio_keys_init+0x1c/0x28
> do_one_initcall+0x64/0x308 kernel_init_freeable+0x284/0x508
> kernel_init+0x24/0x1dc ret_from_fork+0x10/0x20 Code: a9025bf5 a90573fb
> aa0203fb 35001843 (b941c260) ---[ end trace 0000000000000000 ]--- note:
> swapper/0[1] exited with irqs disabled note: swapper/0[1] exited with
> preempt_count 3 Kernel panic - not syncing: Attempted to kill init!
> exitcode=0x0000000b SMP: stopping secondary CPUs Kernel Offset: disabled
> CPU features: 0x1040000,41858004,00020000,0400421b Memory Limit: none
> ---[ end Kernel panic - not syncing: Attempted to kill init!
> exitcode=0x0000000b ]---
>
> Reverting $subject on top of current linux-next fixes this issue.
Thank you very much for your detailed stack; it has been very helpful to me.
I followed the call stack in detail and found that the line in kbd_keycode(),
(*k_handler[type])(vc, KVAL(keysym), !down);
calls k_fn(), which ultimately calls tty_flip_buffer_push().
In kbd_keycode(), vc is set as follows:
struct vc_data *vc = vc_cons[fg_console].d;
fg_console is set to 0 in con_init().
con_init() calls tty_port_init() to init vc_cons[0].d->port but do not call
tty_port_install() which link flip_wq to the port.
Although tty_port_install() is dedicated for in-memory devices like PTY to
link port allocated on demand, the logic of tty_port_install() is so simple
that people may not call it. vc_cons[0].d->port is one such case.
On the other hand, not all instances during tty_port_init() have easy access
to the corresponding driver pointer, which makes it inconvenient to directly
link flip_wq during all tty_port_init calls. Below are some other code that
I found, which may not link wq, potentially leading to flip_wq being null:
drivers/s390/char/sclp_vt220.c:
sclp_vt220_con_init
__sclp_vt220_init
tty_port_init
drivers/tty/n_gsm.c
gsm_queue
gsm_dlci_alloc
tty_port_init
drivers/tty/vcc.c
vcc_install
tty_port_init
drivers/usb/serial/usb-serial.c
usb_serial_probe
tty_port_init
Maybe in tty_flip_buffer_push() 'checking whether flip_wq is NULL and use
system_dfl_wq instead if it is NULL' is a better choice.
--
Xin Zhao
Powered by blists - more mailing lists