Skip to content

Commit

Permalink
drm/etnaviv: take GPU lock later in the submit process
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Christian Gmeiner <[email protected]>
  • Loading branch information
lynxeye-dev committed Aug 15, 2016
1 parent 29b4817 commit d985349
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions drivers/gpu/drm/etnaviv/etnaviv_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1333,8 +1333,6 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
if (ret < 0)
return ret;

mutex_lock(&gpu->lock);

/*
* TODO
*
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit d985349

Please sign in to comment.