|
@@ -238,144 +238,10 @@ void amdgpu_test_moves(struct amdgpu_device *adev)
|
|
|
amdgpu_do_test_moves(adev);
|
|
|
}
|
|
|
|
|
|
-static int amdgpu_test_create_and_emit_fence(struct amdgpu_device *adev,
|
|
|
- struct amdgpu_ring *ring,
|
|
|
- struct fence **fence)
|
|
|
-{
|
|
|
- uint32_t handle = ring->idx ^ 0xdeafbeef;
|
|
|
- int r;
|
|
|
-
|
|
|
- if (ring == &adev->uvd.ring) {
|
|
|
- r = amdgpu_uvd_get_create_msg(ring, handle, NULL);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to get dummy create msg\n");
|
|
|
- return r;
|
|
|
- }
|
|
|
-
|
|
|
- r = amdgpu_uvd_get_destroy_msg(ring, handle, fence);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to get dummy destroy msg\n");
|
|
|
- return r;
|
|
|
- }
|
|
|
-
|
|
|
- } else if (ring == &adev->vce.ring[0] ||
|
|
|
- ring == &adev->vce.ring[1]) {
|
|
|
- r = amdgpu_vce_get_create_msg(ring, handle, NULL);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to get dummy create msg\n");
|
|
|
- return r;
|
|
|
- }
|
|
|
-
|
|
|
- r = amdgpu_vce_get_destroy_msg(ring, handle, fence);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to get dummy destroy msg\n");
|
|
|
- return r;
|
|
|
- }
|
|
|
- } else {
|
|
|
- struct amdgpu_fence *a_fence = NULL;
|
|
|
- r = amdgpu_ring_lock(ring, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring A %d\n", ring->idx);
|
|
|
- return r;
|
|
|
- }
|
|
|
- amdgpu_fence_emit(ring, AMDGPU_FENCE_OWNER_UNDEFINED, &a_fence);
|
|
|
- amdgpu_ring_unlock_commit(ring);
|
|
|
- *fence = &a_fence->base;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
void amdgpu_test_ring_sync(struct amdgpu_device *adev,
|
|
|
struct amdgpu_ring *ringA,
|
|
|
struct amdgpu_ring *ringB)
|
|
|
{
|
|
|
- struct fence *fence1 = NULL, *fence2 = NULL;
|
|
|
- struct amdgpu_semaphore *semaphore = NULL;
|
|
|
- int r;
|
|
|
-
|
|
|
- r = amdgpu_semaphore_create(adev, &semaphore);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to create semaphore\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringA, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring A %d\n", ringA->idx);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_wait(ringA, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringA);
|
|
|
-
|
|
|
- r = amdgpu_test_create_and_emit_fence(adev, ringA, &fence1);
|
|
|
- if (r)
|
|
|
- goto out_cleanup;
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringA, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring A %d\n", ringA->idx);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_wait(ringA, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringA);
|
|
|
-
|
|
|
- r = amdgpu_test_create_and_emit_fence(adev, ringA, &fence2);
|
|
|
- if (r)
|
|
|
- goto out_cleanup;
|
|
|
-
|
|
|
- mdelay(1000);
|
|
|
-
|
|
|
- if (fence_is_signaled(fence1)) {
|
|
|
- DRM_ERROR("Fence 1 signaled without waiting for semaphore.\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringB, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring B %p\n", ringB);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_signal(ringB, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringB);
|
|
|
-
|
|
|
- r = fence_wait(fence1, false);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to wait for sync fence 1\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- mdelay(1000);
|
|
|
-
|
|
|
- if (fence_is_signaled(fence2)) {
|
|
|
- DRM_ERROR("Fence 2 signaled without waiting for semaphore.\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringB, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring B %p\n", ringB);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_signal(ringB, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringB);
|
|
|
-
|
|
|
- r = fence_wait(fence2, false);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to wait for sync fence 1\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
-out_cleanup:
|
|
|
- amdgpu_semaphore_free(adev, &semaphore, NULL);
|
|
|
-
|
|
|
- if (fence1)
|
|
|
- fence_put(fence1);
|
|
|
-
|
|
|
- if (fence2)
|
|
|
- fence_put(fence2);
|
|
|
-
|
|
|
- if (r)
|
|
|
- printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
|
|
|
}
|
|
|
|
|
|
static void amdgpu_test_ring_sync2(struct amdgpu_device *adev,
|
|
@@ -383,109 +249,6 @@ static void amdgpu_test_ring_sync2(struct amdgpu_device *adev,
|
|
|
struct amdgpu_ring *ringB,
|
|
|
struct amdgpu_ring *ringC)
|
|
|
{
|
|
|
- struct fence *fenceA = NULL, *fenceB = NULL;
|
|
|
- struct amdgpu_semaphore *semaphore = NULL;
|
|
|
- bool sigA, sigB;
|
|
|
- int i, r;
|
|
|
-
|
|
|
- r = amdgpu_semaphore_create(adev, &semaphore);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to create semaphore\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringA, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring A %d\n", ringA->idx);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_wait(ringA, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringA);
|
|
|
-
|
|
|
- r = amdgpu_test_create_and_emit_fence(adev, ringA, &fenceA);
|
|
|
- if (r)
|
|
|
- goto out_cleanup;
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringB, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring B %d\n", ringB->idx);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_wait(ringB, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringB);
|
|
|
- r = amdgpu_test_create_and_emit_fence(adev, ringB, &fenceB);
|
|
|
- if (r)
|
|
|
- goto out_cleanup;
|
|
|
-
|
|
|
- mdelay(1000);
|
|
|
-
|
|
|
- if (fence_is_signaled(fenceA)) {
|
|
|
- DRM_ERROR("Fence A signaled without waiting for semaphore.\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- if (fence_is_signaled(fenceB)) {
|
|
|
- DRM_ERROR("Fence B signaled without waiting for semaphore.\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringC, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring B %p\n", ringC);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_signal(ringC, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringC);
|
|
|
-
|
|
|
- for (i = 0; i < 30; ++i) {
|
|
|
- mdelay(100);
|
|
|
- sigA = fence_is_signaled(fenceA);
|
|
|
- sigB = fence_is_signaled(fenceB);
|
|
|
- if (sigA || sigB)
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (!sigA && !sigB) {
|
|
|
- DRM_ERROR("Neither fence A nor B has been signaled\n");
|
|
|
- goto out_cleanup;
|
|
|
- } else if (sigA && sigB) {
|
|
|
- DRM_ERROR("Both fence A and B has been signaled\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- DRM_INFO("Fence %c was first signaled\n", sigA ? 'A' : 'B');
|
|
|
-
|
|
|
- r = amdgpu_ring_lock(ringC, 64);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to lock ring B %p\n", ringC);
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- amdgpu_semaphore_emit_signal(ringC, semaphore);
|
|
|
- amdgpu_ring_unlock_commit(ringC);
|
|
|
-
|
|
|
- mdelay(1000);
|
|
|
-
|
|
|
- r = fence_wait(fenceA, false);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to wait for sync fence A\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
- r = fence_wait(fenceB, false);
|
|
|
- if (r) {
|
|
|
- DRM_ERROR("Failed to wait for sync fence B\n");
|
|
|
- goto out_cleanup;
|
|
|
- }
|
|
|
-
|
|
|
-out_cleanup:
|
|
|
- amdgpu_semaphore_free(adev, &semaphore, NULL);
|
|
|
-
|
|
|
- if (fenceA)
|
|
|
- fence_put(fenceA);
|
|
|
-
|
|
|
- if (fenceB)
|
|
|
- fence_put(fenceB);
|
|
|
-
|
|
|
- if (r)
|
|
|
- printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
|
|
|
}
|
|
|
|
|
|
static bool amdgpu_test_sync_possible(struct amdgpu_ring *ringA,
|