diff options
author | Boris Brezillon <boris.brezillon@collabora.com> | 2021-06-30 08:27:44 +0200 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@collabora.com> | 2021-07-01 08:53:32 +0200 |
commit | a11c4711238ad39761cc0e04f3e8aa7b28fe1923 (patch) | |
tree | 9760b4a65e96c103cd3974811983a3f9e3fc7fa7 /drivers/gpu/drm/panfrost/panfrost_device.h | |
parent | 070ce7657bdfaab5913908c93d57281c639cdca4 (diff) |
drm/panfrost: Simplify the reset serialization logic
Now that we can pass our own workqueue to drm_sched_init(), we can use
an ordered workqueue on for both the scheduler timeout tdr and our own
reset work (which we use when the reset is not caused by a fault/timeout
on a specific job, like when we have AS_ACTIVE bit stuck). This
guarantees that the timeout handlers and reset handler can't run
concurrently which drastically simplifies the locking.
v5:
* Don't call cancel_delayed_timeout() in the reset path (those works
are canceled in drm_sched_stop())
v4:
* Actually pass the reset workqueue to drm_sched_init()
* Don't call cancel_work_sync() in panfrost_reset(). It will deadlock
since it might be called from the reset work, which is executing and
cancel_work_sync() will wait for the handler to return. Checking the
reset pending status should avoid spurious resets
v3:
* New patch
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210630062751.2832545-10-boris.brezillon@collabora.com
Diffstat (limited to 'drivers/gpu/drm/panfrost/panfrost_device.h')
-rw-r--r-- | drivers/gpu/drm/panfrost/panfrost_device.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index aec11b6f5abc..d37bc09809e8 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -109,6 +109,7 @@ struct panfrost_device { struct mutex sched_lock; struct { + struct workqueue_struct *wq; struct work_struct work; atomic_t pending; } reset; @@ -247,9 +248,8 @@ const char *panfrost_exception_name(u32 exception_code); static inline void panfrost_device_schedule_reset(struct panfrost_device *pfdev) { - /* Schedule a reset if there's no reset in progress. */ - if (!atomic_xchg(&pfdev->reset.pending, 1)) - schedule_work(&pfdev->reset.work); + atomic_set(&pfdev->reset.pending, 1); + queue_work(pfdev->reset.wq, &pfdev->reset.work); } #endif |