diff options
| author | Fan Wu <fanwu01@zju.edu.cn> | 2026-09-15 09:51:03 +0000 |
|---|---|---|
| committer | Maíra Canal <mcanal@igalia.com> | 2026-09-25 11:05:17 -0300 |
| commit | 94cf5971b1d04c6382437387c4dc3836cc7a1437 (patch) | |
| tree | 3bc394a1ebdffb1a2b26543621ddae703bdd8584 /drivers/gpu | |
| parent | 45585c3aa285854face65293acc95eff73063d6d (diff) | |
| download | linux-next-94cf5971b1d04c6382437387c4dc3836cc7a1437.tar.gz linux-next-94cf5971b1d04c6382437387c4dc3836cc7a1437.zip | |
drm/vc4: drain the hangcheck timer and works on V3D unbind
Nothing stops the hangcheck timer that submitted jobs arm, or the
job_done_work that the render-done interrupt queues, at teardown:
vc4_irq_disable() cancels only overflow_mem_work, and vc4_gem_destroy()
runs from the drm-managed release, after vc4_v3d_unbind() has already
uninstalled the V3D interrupt and cleared vc4->v3d. A timer still armed
by then reads V3D registers through the NULL vc4->v3d pointer, and the
late callbacks run on the vc4_dev embedding them after it has been
freed.
Drain them in vc4_v3d_unbind(): shut the timer down and cancel
reset_work before the interrupt is taken down, because its
vc4_irq_reset() re-enables it, then flush job_done_work so that
completions queued at teardown still release their jobs.
This issue was found by an in-house static analysis tool.
Fixes: d5b1a78a772f ("drm/vc4: Add support for drawing 3D frames.")
Cc: stable@vger.kernel.org # 6.2+
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260915095103.156007-1-fanwu01@zju.edu.cn
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_v3d.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index f32410420d3e..0f0c090afa6e 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -9,6 +9,7 @@ #include <linux/component.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/timer.h> #include <drm/drm_print.h> @@ -497,8 +498,15 @@ static void vc4_v3d_unbind(struct device *dev, struct device *master, struct drm_device *drm = data; struct vc4_dev *vc4 = to_vc4_dev(drm); + /* A straggler vc4_reset() re-enables the interrupt. */ + timer_shutdown_sync(&vc4->hangcheck.timer); + cancel_work_sync(&vc4->hangcheck.reset_work); + vc4_irq_uninstall(drm); + /* Flush rather than cancel, so queued completions release their jobs. */ + flush_work(&vc4->job_done_work); + /* Disable the binner's overflow memory address, so the next * driver probe (if any) doesn't try to reuse our old * allocation. |
