Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: cope with foreign fences inside display

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Maarten Lankhorst and committed by
Alex Deucher
a0e84764 38aea071

+20 -12
+1 -1
drivers/gpu/drm/radeon/radeon.h
··· 712 712 uint64_t base; 713 713 struct drm_pending_vblank_event *event; 714 714 struct radeon_bo *old_rbo; 715 - struct radeon_fence *fence; 715 + struct fence *fence; 716 716 }; 717 717 718 718 struct r500_irq_stat_regs {
+19 -11
drivers/gpu/drm/radeon/radeon_display.c
··· 402 402 403 403 down_read(&rdev->exclusive_lock); 404 404 if (work->fence) { 405 - r = radeon_fence_wait(work->fence, false); 406 - if (r == -EDEADLK) { 407 - up_read(&rdev->exclusive_lock); 408 - do { 409 - r = radeon_gpu_reset(rdev); 410 - } while (r == -EAGAIN); 411 - down_read(&rdev->exclusive_lock); 412 - } 405 + struct radeon_fence *fence; 406 + 407 + fence = to_radeon_fence(work->fence); 408 + if (fence && fence->rdev == rdev) { 409 + r = radeon_fence_wait(fence, false); 410 + if (r == -EDEADLK) { 411 + up_read(&rdev->exclusive_lock); 412 + do { 413 + r = radeon_gpu_reset(rdev); 414 + } while (r == -EAGAIN); 415 + down_read(&rdev->exclusive_lock); 416 + } 417 + } else 418 + r = fence_wait(work->fence, false); 419 + 413 420 if (r) 414 421 DRM_ERROR("failed to wait on page flip fence (%d)!\n", r); 415 422 ··· 425 418 * confused about which BO the CRTC is scanning out 426 419 */ 427 420 428 - radeon_fence_unref(&work->fence); 421 + fence_put(work->fence); 422 + work->fence = NULL; 429 423 } 430 424 431 425 /* We borrow the event spin lock for protecting flip_status */ ··· 502 494 DRM_ERROR("failed to pin new rbo buffer before flip\n"); 503 495 goto cleanup; 504 496 } 505 - work->fence = (struct radeon_fence *)fence_get(reservation_object_get_excl(new_rbo->tbo.resv)); 497 + work->fence = fence_get(reservation_object_get_excl(new_rbo->tbo.resv)); 506 498 radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL); 507 499 radeon_bo_unreserve(new_rbo); 508 500 ··· 584 576 585 577 cleanup: 586 578 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); 587 - radeon_fence_unref(&work->fence); 579 + fence_put(work->fence); 588 580 kfree(work); 589 581 return r; 590 582 }