Commit a8d81b36 authored by Nicolai Hähnle's avatar Nicolai Hähnle Committed by Alex Deucher

drm/amdgpu: hold reference to fences in amdgpu_sa_bo_new (v2)

An arbitrary amount of time can pass between spin_unlock and
fence_wait_any_timeout, so we need to ensure that nobody frees the
fences from under us.

A stress test (rapidly starting and killing hundreds of glxgears
instances) ran into a deadlock in fence_wait_any_timeout after
about an hour, and this race condition appears to be a plausible
cause.

v2: agd: rebase on upstream
Signed-off-by: default avatarNicolai Hähnle <nicolai.haehnle@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Cc: stable@vger.kernel.org
parent ca198528
...@@ -354,12 +354,15 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, ...@@ -354,12 +354,15 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
for (i = 0, count = 0; i < AMDGPU_MAX_RINGS; ++i) for (i = 0, count = 0; i < AMDGPU_MAX_RINGS; ++i)
if (fences[i]) if (fences[i])
fences[count++] = fences[i]; fences[count++] = fence_get(fences[i]);
if (count) { if (count) {
spin_unlock(&sa_manager->wq.lock); spin_unlock(&sa_manager->wq.lock);
t = fence_wait_any_timeout(fences, count, false, t = fence_wait_any_timeout(fences, count, false,
MAX_SCHEDULE_TIMEOUT); MAX_SCHEDULE_TIMEOUT);
for (i = 0; i < count; ++i)
fence_put(fences[i]);
r = (t > 0) ? 0 : t; r = (t > 0) ? 0 : t;
spin_lock(&sa_manager->wq.lock); spin_lock(&sa_manager->wq.lock);
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment