Re: [PATCH] PM: runtime: Fix check_flush_dependency warning from pm_runtime_remove
From: Rafael J. Wysocki (Intel)
Date: Wed Nov 04 2026 - 09:35:57 EST
On Wed, Nov 4, 2026 at 1:05 PM Zhou Minqiang <zhouminqiang2@xxxxxxxxxx> wrote:
>
> When a WQ_MEM_RECLAIM workqueue (e.g. iscsi_ctrl) triggers device removal
> via device_del -> pm_runtime_remove, the unconditional flush_work inside
> pm_runtime_remove can trigger a check_flush_dependency warning:
>
> CPU1: pm_wq worker CPU2: iscsi_ctrl wq
> -------- --------
>
> pm_runtime_work(starget) pm_runtime_remove(starget)
> spin_lock_irq(&starget->lock) __pm_runtime_disable(starget, false)
> request_pending = false spin_lock_irq(&starget->lock)
> (blocked, CPU1 holds the lock)
>
> rpm_suspend(starget, RPM_NOWAIT)
> status = RPM_SUSPENDING
> rpm_callback(cb, starget)
> spin_unlock_irq(&starget->lock)
> (acquires lock)
> disable_depth 0→1
> __pm_runtime_barrier():
> request_pending == false
> → skip cancel_work_sync
> status == RPM_SUSPENDING
> → enter wait_queue, sleep
> spin_unlock_irq(&starget->lock)
> cb(starget) → 0
> spin_lock_irq(&starget->lock)
> status = RPM_SUSPENDED
> wake_up_all(&wait_queue)
> (woken up, waiting for lock)
> spin_unlock(&starget->lock) spin_lock_irq(&starget->lock)
> status == RPM_SUSPENDED
> spin_lock(&parent->lock) → exit wait_queue
> rpm_idle(parent, RPM_ASYNC) barrier returns
> spin_unlock(&parent->lock) flush_work(&starget->work)
> spin_lock(&starget->lock) __flush_work(from_cancel=false)
> spin_unlock_irq(&starget->lock) check_flush_dependency()
> ← WARNING!
>
> Replace flush_work with cancel_work_sync in pm_runtime_remove.
> cancel_work_sync internally calls __flush_work with from_cancel=true,
> which causes check_flush_dependency to return early before the warning.
> This preserves the use-after-free fix from commit 29ab76827761
> ("PM: runtime: Fix a race condition related to device removal")
> without the warning.
>
> Fixes: 29ab76827761 ("PM: runtime: Fix a race condition related to device removal")
> Signed-off-by: Zhou Minqiang <zhouminqiang2@xxxxxxxxxx>
> ---
> drivers/base/power/runtime.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> index 335288e8b5b3..31537b745c81 100644
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -1895,7 +1895,7 @@ void pm_runtime_reinit(struct device *dev)
> void pm_runtime_remove(struct device *dev)
> {
> __pm_runtime_disable(dev, false);
> - flush_work(&dev->power.work);
> + cancel_work_sync(&dev->power.work);
> pm_runtime_reinit(dev);
> }
>
> --
Applied as 7.4-rc material, thanks!