drm/panfrost: Introduce a reset lock

In order to avoid accessing HW register while a reset is ongoing, a
read/write semaphore that envelopes the reset sequence will help driver
entry points avoid racing with it. For now, the only such racy entry
point is the ioctl that returns the current GPU timestamp.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Link: https://patch.msgid.link/20261012-claude-fixes-v15-14-bc0a6c498553@collabora.com
Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
This commit is contained in:
Adrián Larumbe 2026-10-12 15:48:06 +01:00
parent 9373cdddb5
commit 38fb4f01d7
4 changed files with 10 additions and 3 deletions

View File

@ -509,6 +509,8 @@ bool panfrost_exception_needs_reset(const struct panfrost_device *pfdev,
void panfrost_device_reset(struct panfrost_device *pfdev, bool enable_job_int)
{
guard(rwsem_write)(&pfdev->reset.lock);
panfrost_gpu_soft_reset(pfdev);
panfrost_gpu_power_on(pfdev);

View File

@ -165,6 +165,7 @@ struct panfrost_device {
struct {
struct workqueue_struct *wq;
struct work_struct work;
struct rw_semaphore lock;
atomic_t pending;
} reset;

View File

@ -41,9 +41,12 @@ static int panfrost_ioctl_query_timestamp(struct panfrost_device *pfdev,
if (ret)
return ret;
panfrost_cycle_counter_get(pfdev);
*arg = panfrost_timestamp_read(pfdev);
panfrost_cycle_counter_put(pfdev);
/* We should not read timestamp register while the GPU is being reset */
scoped_guard(rwsem_read, &pfdev->reset.lock) {
panfrost_cycle_counter_get(pfdev);
*arg = panfrost_timestamp_read(pfdev);
panfrost_cycle_counter_put(pfdev);
}
pm_runtime_put(pfdev->base.dev);
return 0;

View File

@ -877,6 +877,7 @@ int panfrost_jm_init(struct panfrost_device *pfdev)
INIT_WORK(&pfdev->reset.work, panfrost_reset_work);
spin_lock_init(&js->job_lock);
mutex_init(&pfdev->sched_lock);
init_rwsem(&pfdev->reset.lock);
js->irq = platform_get_irq_byname(to_platform_device(pfdev->base.dev), "job");
if (js->irq < 0)