mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
drm/etnaviv: take GPU lock later in the submit process
Both the fence and event alloc are safe to be done without holding the GPU lock, as they either don't need any locking (fences) or are protected by their own lock (events). This solves a bad locking interaction between the submit path and the recover worker. If userspace manages to exhaust all available events while the GPU is hung, the submit will wait for events to become available holding the GPU lock. The recover worker waits for this lock to become available before trying to recover the GPU which frees up the allocated events. Essentially both paths are deadlocked until the submit path times out waiting for available events, failing the submit that could otherwise be handled just fine if the recover worker had the chance to bring the GPU back in a working state. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
parent
29b4817d40
commit
d985349017
1 changed files with 5 additions and 5 deletions
|
@ -1333,8 +1333,6 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
/*
|
||||
* TODO
|
||||
*
|
||||
|
@ -1348,16 +1346,18 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
|||
if (unlikely(event == ~0U)) {
|
||||
DRM_ERROR("no free event\n");
|
||||
ret = -EBUSY;
|
||||
goto out_unlock;
|
||||
goto out_pm_put;
|
||||
}
|
||||
|
||||
fence = etnaviv_gpu_fence_alloc(gpu);
|
||||
if (!fence) {
|
||||
event_free(gpu, event);
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
goto out_pm_put;
|
||||
}
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
gpu->event[event].fence = fence;
|
||||
submit->fence = fence->seqno;
|
||||
gpu->active_fence = submit->fence;
|
||||
|
@ -1395,9 +1395,9 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
|||
hangcheck_timer_reset(gpu);
|
||||
ret = 0;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&gpu->lock);
|
||||
|
||||
out_pm_put:
|
||||
etnaviv_gpu_pm_put(gpu);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue