Re: [PATCH 12/12] drm/panthor: Fix unplug in the reset path
[email protected] Tue, 04 Aug 2026 16:01:24 +0000
| Newsgroups | org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [High] Concurrent execution of device removal and a failing reset work causes an unrecoverable AB-BA cross-thread deadlock. -- --- Patch [12]: [PATCH 12/12] drm/panthor: Fix unplug in the reset path --- commit cac1a79672cc7dc4544f4f69a02f107969842cb8 Author: Boris Brezillon <[email protected]> drm/panthor: Fix unplug in the reset path We can't use disable_work_sync() if panthor_device_unplug() is called from the reset work or we'll deadlock. Pass a from_reset_work bool to the panthor_device_unplug() function and lower the disable_work_sync() to a disable_work() in that case. > diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c > --- a/drivers/gpu/drm/panthor/panthor_device.c > +++ b/drivers/gpu/drm/panthor/panthor_device.c > @@ -189,13 +192,16 @@ static void panthor_device_reset_work(struct work_struct *work) > panthor_hw_soft_reset(ptdev); > panthor_hw_l2_power_on(ptdev); > panthor_mmu_post_reset(ptdev); > - ret = panthor_fw_post_reset(ptdev); > + if (ptdev->reset.fake_failure) > + ret = -EIO; > + else > + ret = panthor_fw_post_reset(ptdev); > atomic_set(&ptdev->reset.pending, 0); > panthor_sched_post_reset(ptdev, ret != 0); > drm_dev_exit(cookie); > > if (ret) { > - panthor_device_unplug(ptdev); > + panthor_device_unplug(ptdev, true); [Severity: High] This is a pre-existing issue, but does this sequence still leave an AB-BA deadlock if driver removal runs concurrently with a failing reset work? If CPU1 is running driver removal via panthor_remove(), it calls panthor_device_unplug(..., false). This acquires ptdev->unplug.lock earlier in the function. If CPU2 is running panthor_device_reset_work(), it holds the SRCU read lock via drm_dev_enter(). CPU1 then blocks in drm_dev_unplug() waiting for active SRCU readers. CPU2 encounters a reset error, calls drm_dev_exit() (releasing SRCU), and unblocks CPU1. CPU1 continues in panthor_device_unplug() and blocks in disable_work_sync() waiting for the reset work to finish (since it holds ptdev->unplug.lock and from_reset_work is false): CPU1: panthor_remove() panthor_device_unplug(ptdev, false) mutex_lock(&ptdev->unplug.lock); ... drm_dev_unplug(&ptdev->base); ... disable_work_sync(&ptdev->reset.work); Meanwhile, CPU2 proceeds to the error handling path and calls panthor_device_unplug(ptdev, true). This attempts to acquire ptdev->unplug.lock, but CPU1 already holds it: CPU2: panthor_device_reset_work() ... if (ret) panthor_device_unplug(ptdev, true) mutex_lock(&ptdev->unplug.lock); Could this cause both threads to hang indefinitely? -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=12