On Thu Dec 4 17:41:52 2025 +0800, Xulin Sun wrote:
> Fix the cleanup order in polling mode (irq < 0) to prevent kernel warnings
> during module removal. Cancel the hrtimer before destroying the kthread
> worker to ensure work queues are empty.
> 
> In polling mode, the driver uses hrtimer to periodically trigger
> wave5_vpu_timer_callback() which queues work via kthread_queue_work().
> The kthread_destroy_worker() function validates that both work queues
> are empty with WARN_ON(!list_empty(&worker->work_list)) and
> WARN_ON(!list_empty(&worker->delayed_work_list)).
> 
> The original code called kthread_destroy_worker() before hrtimer_cancel(),
> creating a race condition where the timer could fire during worker
> destruction and queue new work, triggering the WARN_ON.
> 
> This causes the following warning on every module unload in polling mode:
> 
>   ------------[ cut here ]------------
>   WARNING: CPU: 2 PID: 1034 at kernel/kthread.c:1430
>     kthread_destroy_worker+0x84/0x98
>   Modules linked in: wave5(-) rpmsg_ctrl rpmsg_char ...
>   Call trace:
>    kthread_destroy_worker+0x84/0x98
>    wave5_vpu_remove+0xc8/0xe0 [wave5]
>    platform_remove+0x30/0x58
>   ...
>   ---[ end trace 0000000000000000 ]---
> 
> Fixes: ed7276ed2fd0 ("media: chips-media: wave5: Add hrtimer based polling 
> support")
> Cc: [email protected]
> Signed-off-by: Xulin Sun <[email protected]>
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/chips-media/wave5/wave5-vpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

---

diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.c 
b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
index 23aa3ab51a0e..0bcd48df49d0 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
@@ -352,8 +352,9 @@ static void wave5_vpu_remove(struct platform_device *pdev)
        struct vpu_device *dev = dev_get_drvdata(&pdev->dev);
 
        if (dev->irq < 0) {
-               kthread_destroy_worker(dev->worker);
                hrtimer_cancel(&dev->hrtimer);
+               kthread_cancel_work_sync(&dev->work);
+               kthread_destroy_worker(dev->worker);
        }
 
        pm_runtime_dont_use_autosuspend(&pdev->dev);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to