summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2016-02-05 10:59:43 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-02-10 14:07:31 -0500
commita8d81b36267366603771431747438d18f32ae2d5 (patch)
treefb6460edb485890a55b6a101751812abcfb0b7c1 /drivers
parentca19852884c8937eed89560f924f5a34cfcc22af (diff)
downloadlinux-a8d81b36267366603771431747438d18f32ae2d5.tar.bz2
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: Nicolai Hähnle <nicolai.haehnle@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
index 8b88edb0434b..ca72a2e487b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -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)
if (fences[i])
- fences[count++] = fences[i];
+ fences[count++] = fence_get(fences[i]);
if (count) {
spin_unlock(&sa_manager->wq.lock);
t = fence_wait_any_timeout(fences, count, false,
MAX_SCHEDULE_TIMEOUT);
+ for (i = 0; i < count; ++i)
+ fence_put(fences[i]);
+
r = (t > 0) ? 0 : t;
spin_lock(&sa_manager->wq.lock);
} else {