In theory, there might be MMU/FW faults happening after the FW has
successfully started, and since we clear the reset.pending bit after
panthor_fw_post_reset() has returned, there's a short window during
which a reset request can be ignored.

The other case is a reset condition in other subcomponents that would
not prevent the FW to boot, but given what's currently done in the
post_reset() helpers, I don't see how this can happen. Anyway, it's
probably safer to reset the pending bit just before the SOFT_RESET is
issued, so there's absolutely no timeframe during which a reset event
can be lost. The risk is an infinite reset loop if the reset condition
doesn't prevent the FW to boot, and keeps happening in subsequent resets.

Fixes: 5fe909cae118 ("drm/panthor: Add the device logical block")
Reported-by: [email protected]
Closes: 
https://sashiko.dev/#/patchset/[email protected]?part=2
Signed-off-by: Boris Brezillon <[email protected]>
---
 drivers/gpu/drm/panthor/panthor_device.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panthor/panthor_device.c 
b/drivers/gpu/drm/panthor/panthor_device.c
index 2520158adb03..393031ada315 100644
--- a/drivers/gpu/drm/panthor/panthor_device.c
+++ b/drivers/gpu/drm/panthor/panthor_device.c
@@ -156,11 +156,18 @@ static void panthor_device_reset_work(struct work_struct 
*work)
        panthor_sched_pre_reset(ptdev);
        panthor_fw_pre_reset(ptdev, true);
        panthor_mmu_pre_reset(ptdev);
+
+       /* Reset the pending bit just before the SOFT_RESET to catch any reset
+        * condition happening in the post reset path. If we're in such a bad
+        * state we can't even resume the FW, we will bail out and unplug
+        * anyway, at which point the reset work is disabled, which should
+        * prevent an infinite reset loop.
+        */
+       atomic_set(&ptdev->reset.pending, 0);
        panthor_hw_soft_reset(ptdev);
        panthor_hw_l2_power_on(ptdev);
        panthor_mmu_post_reset(ptdev);
        ret = panthor_fw_post_reset(ptdev);
-       atomic_set(&ptdev->reset.pending, 0);
        panthor_sched_post_reset(ptdev, ret != 0);
        drm_dev_exit(cookie);
 

-- 
2.55.0

Reply via email to