[Added printk maintainers CC.] On 2023-11-24, Xuewen Yan <xuewen.yan@xxxxxxxxxx> wrote: > The commit 84a9582fd203("serial: core: Start managing serial > controllers to enable runtime PM") use the pm_runtime_get() after > uart_port_lock() which would close the irq and disable preement. At > this time, pm_runtime_get may cause the following two problems: > > (1) deadlock in try_to_wake_up: > > uart_write() > uart_port_lock() <<< get lock > __uart_start > __pm_runtime_resume > rpm_resume > queue_work_on > try_to_wake_up > _printk > uart_console_write > ... > uart_port_lock() <<< wait forever I suppose you got this because of the lockdep message generated by #2. It probably would make sense to call __printk_safe_enter() inside uart_port_lock(). This would allow printk() to automatically defer the printing for that CPU until the port lock is released. > (2) scheduling while atomic: > uart_write() > uart_port_lock() <<< get lock > __uart_start > __pm_runtime_resume > rpm_resume > schedule() << sleep rpm_resume() is a fascinating function. It requires the caller to hold a spin_lock (dev->power.lock) with interrupts disabled. But it seems to believe that this is the *only* spin_lock held so that it can temporarily spin_unlock and call might_sleep() functions. In the case of uart_write(), it certainly is not the only spin_lock held. I do not know enough about the internals of RPM to suggest a proper solution. But it looks like rpm_resume() cannot assume dev->power.lock is the only spin_lock held by the caller. John Ogness