aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_ttm.c
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-05-02 09:11:18 -0400
committerDave Airlie <airlied@redhat.com>2012-05-03 04:16:27 -0400
commit8f676c4c6f0f500616560f13c0276ab6b4e39a6a (patch)
tree722ab761de1b53460f4b0308c08f0e41a18b4b5c /drivers/gpu/drm/radeon/radeon_ttm.c
parentbfb9a07785fea0c41dff1a38890bc9b4679a9430 (diff)
drm/radeon: fix a bug with the ring syncing code
Rings need to lock in order, otherwise the ring subsystem can deadlock. v2: fix error handling and number of locked doublewords. v3: stop creating unneeded semaphores. Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_ttm.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index f493c6403af5..5e3d54ded1b3 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -222,8 +222,8 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
222{ 222{
223 struct radeon_device *rdev; 223 struct radeon_device *rdev;
224 uint64_t old_start, new_start; 224 uint64_t old_start, new_start;
225 struct radeon_fence *fence; 225 struct radeon_fence *fence, *old_fence;
226 int r, i; 226 int r;
227 227
228 rdev = radeon_get_rdev(bo->bdev); 228 rdev = radeon_get_rdev(bo->bdev);
229 r = radeon_fence_create(rdev, &fence, radeon_copy_ring_index(rdev)); 229 r = radeon_fence_create(rdev, &fence, radeon_copy_ring_index(rdev));
@@ -242,6 +242,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
242 break; 242 break;
243 default: 243 default:
244 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); 244 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
245 radeon_fence_unref(&fence);
245 return -EINVAL; 246 return -EINVAL;
246 } 247 }
247 switch (new_mem->mem_type) { 248 switch (new_mem->mem_type) {
@@ -253,42 +254,35 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
253 break; 254 break;
254 default: 255 default:
255 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); 256 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
257 radeon_fence_unref(&fence);
256 return -EINVAL; 258 return -EINVAL;
257 } 259 }
258 if (!rdev->ring[radeon_copy_ring_index(rdev)].ready) { 260 if (!rdev->ring[radeon_copy_ring_index(rdev)].ready) {
259 DRM_ERROR("Trying to move memory with ring turned off.\n"); 261 DRM_ERROR("Trying to move memory with ring turned off.\n");
262 radeon_fence_unref(&fence);
260 return -EINVAL; 263 return -EINVAL;
261 } 264 }
262 265
263 BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); 266 BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0);
264 267
265 /* sync other rings */ 268 /* sync other rings */
266 if (rdev->family >= CHIP_R600) { 269 old_fence = bo->sync_obj;
267 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 270 if (old_fence && old_fence->ring != fence->ring
268 /* no need to sync to our own or unused rings */ 271 && !radeon_fence_signaled(old_fence)) {
269 if (i == radeon_copy_ring_index(rdev) || !rdev->ring[i].ready) 272 bool sync_to_ring[RADEON_NUM_RINGS] = { };
270 continue; 273 sync_to_ring[old_fence->ring] = true;
271 274
272 if (!fence->semaphore) { 275 r = radeon_semaphore_create(rdev, &fence->semaphore);
273 r = radeon_semaphore_create(rdev, &fence->semaphore); 276 if (r) {
274 /* FIXME: handle semaphore error */ 277 radeon_fence_unref(&fence);
275 if (r) 278 return r;
276 continue; 279 }
277 }
278 280
279 r = radeon_ring_lock(rdev, &rdev->ring[i], 3); 281 r = radeon_semaphore_sync_rings(rdev, fence->semaphore,
280 /* FIXME: handle ring lock error */ 282 sync_to_ring, fence->ring);
281 if (r) 283 if (r) {
282 continue; 284 radeon_fence_unref(&fence);
283 radeon_semaphore_emit_signal(rdev, i, fence->semaphore); 285 return r;
284 radeon_ring_unlock_commit(rdev, &rdev->ring[i]);
285
286 r = radeon_ring_lock(rdev, &rdev->ring[radeon_copy_ring_index(rdev)], 3);
287 /* FIXME: handle ring lock error */
288 if (r)
289 continue;
290 radeon_semaphore_emit_wait(rdev, radeon_copy_ring_index(rdev), fence->semaphore);
291 radeon_ring_unlock_commit(rdev, &rdev->ring[radeon_copy_ring_index(rdev)]);
292 } 286 }
293 } 287 }
294 288