Commit ce954884 authored by Christian König's avatar Christian König Committed by Dave Airlie

drm/radeon: improve radeon_test_syncing function

Also test multiple waits on the same semaphore.
Signed-off-by: default avatarChristian König <deathsimple@vodafone.de>
Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 30eb77f4
...@@ -239,15 +239,20 @@ void radeon_test_ring_sync(struct radeon_device *rdev, ...@@ -239,15 +239,20 @@ void radeon_test_ring_sync(struct radeon_device *rdev,
struct radeon_ring *ringA, struct radeon_ring *ringA,
struct radeon_ring *ringB) struct radeon_ring *ringB)
{ {
struct radeon_fence *fence = NULL; struct radeon_fence *fence1 = NULL, *fence2 = NULL;
struct radeon_semaphore *semaphore = NULL; struct radeon_semaphore *semaphore = NULL;
int ridxA = radeon_ring_index(rdev, ringA); int ridxA = radeon_ring_index(rdev, ringA);
int ridxB = radeon_ring_index(rdev, ringB); int ridxB = radeon_ring_index(rdev, ringB);
int r; int r;
r = radeon_fence_create(rdev, &fence, ridxA); r = radeon_fence_create(rdev, &fence1, ridxA);
if (r) {
DRM_ERROR("Failed to create sync fence 1\n");
goto out_cleanup;
}
r = radeon_fence_create(rdev, &fence2, ridxA);
if (r) { if (r) {
DRM_ERROR("Failed to create sync fence\n"); DRM_ERROR("Failed to create sync fence 2\n");
goto out_cleanup; goto out_cleanup;
} }
...@@ -263,13 +268,15 @@ void radeon_test_ring_sync(struct radeon_device *rdev, ...@@ -263,13 +268,15 @@ void radeon_test_ring_sync(struct radeon_device *rdev,
goto out_cleanup; goto out_cleanup;
} }
radeon_semaphore_emit_wait(rdev, ridxA, semaphore); radeon_semaphore_emit_wait(rdev, ridxA, semaphore);
radeon_fence_emit(rdev, fence); radeon_fence_emit(rdev, fence1);
radeon_semaphore_emit_wait(rdev, ridxA, semaphore);
radeon_fence_emit(rdev, fence2);
radeon_ring_unlock_commit(rdev, ringA); radeon_ring_unlock_commit(rdev, ringA);
mdelay(1000); mdelay(1000);
if (radeon_fence_signaled(fence)) { if (radeon_fence_signaled(fence1)) {
DRM_ERROR("Fence signaled without waiting for semaphore.\n"); DRM_ERROR("Fence 1 signaled without waiting for semaphore.\n");
goto out_cleanup; goto out_cleanup;
} }
...@@ -281,20 +288,162 @@ void radeon_test_ring_sync(struct radeon_device *rdev, ...@@ -281,20 +288,162 @@ void radeon_test_ring_sync(struct radeon_device *rdev,
radeon_semaphore_emit_signal(rdev, ridxB, semaphore); radeon_semaphore_emit_signal(rdev, ridxB, semaphore);
radeon_ring_unlock_commit(rdev, ringB); radeon_ring_unlock_commit(rdev, ringB);
r = radeon_fence_wait(fence, false); r = radeon_fence_wait(fence1, false);
if (r) {
DRM_ERROR("Failed to wait for sync fence 1\n");
goto out_cleanup;
}
mdelay(1000);
if (radeon_fence_signaled(fence2)) {
DRM_ERROR("Fence 2 signaled without waiting for semaphore.\n");
goto out_cleanup;
}
r = radeon_ring_lock(rdev, ringB, 64);
if (r) { if (r) {
DRM_ERROR("Failed to wait for sync fence\n"); DRM_ERROR("Failed to lock ring B %p\n", ringB);
goto out_cleanup; goto out_cleanup;
} }
radeon_semaphore_emit_signal(rdev, ridxB, semaphore);
radeon_ring_unlock_commit(rdev, ringB);
DRM_INFO("Syncing between rings %d and %d seems to work.\n", ridxA, ridxB); r = radeon_fence_wait(fence2, false);
if (r) {
DRM_ERROR("Failed to wait for sync fence 1\n");
goto out_cleanup;
}
out_cleanup: out_cleanup:
if (semaphore) if (semaphore)
radeon_semaphore_free(rdev, semaphore); radeon_semaphore_free(rdev, semaphore);
if (fence) if (fence1)
radeon_fence_unref(&fence); radeon_fence_unref(&fence1);
if (fence2)
radeon_fence_unref(&fence2);
if (r)
printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
}
void radeon_test_ring_sync2(struct radeon_device *rdev,
struct radeon_ring *ringA,
struct radeon_ring *ringB,
struct radeon_ring *ringC)
{
struct radeon_fence *fenceA = NULL, *fenceB = NULL;
struct radeon_semaphore *semaphore = NULL;
int ridxA = radeon_ring_index(rdev, ringA);
int ridxB = radeon_ring_index(rdev, ringB);
int ridxC = radeon_ring_index(rdev, ringC);
bool sigA, sigB;
int i, r;
r = radeon_fence_create(rdev, &fenceA, ridxA);
if (r) {
DRM_ERROR("Failed to create sync fence 1\n");
goto out_cleanup;
}
r = radeon_fence_create(rdev, &fenceB, ridxB);
if (r) {
DRM_ERROR("Failed to create sync fence 2\n");
goto out_cleanup;
}
r = radeon_semaphore_create(rdev, &semaphore);
if (r) {
DRM_ERROR("Failed to create semaphore\n");
goto out_cleanup;
}
r = radeon_ring_lock(rdev, ringA, 64);
if (r) {
DRM_ERROR("Failed to lock ring A %d\n", ridxA);
goto out_cleanup;
}
radeon_semaphore_emit_wait(rdev, ridxA, semaphore);
radeon_fence_emit(rdev, fenceA);
radeon_ring_unlock_commit(rdev, ringA);
r = radeon_ring_lock(rdev, ringB, 64);
if (r) {
DRM_ERROR("Failed to lock ring B %d\n", ridxB);
goto out_cleanup;
}
radeon_semaphore_emit_wait(rdev, ridxB, semaphore);
radeon_fence_emit(rdev, fenceB);
radeon_ring_unlock_commit(rdev, ringB);
mdelay(1000);
if (radeon_fence_signaled(fenceA)) {
DRM_ERROR("Fence A signaled without waiting for semaphore.\n");
goto out_cleanup;
}
if (radeon_fence_signaled(fenceB)) {
DRM_ERROR("Fence A signaled without waiting for semaphore.\n");
goto out_cleanup;
}
r = radeon_ring_lock(rdev, ringC, 64);
if (r) {
DRM_ERROR("Failed to lock ring B %p\n", ringC);
goto out_cleanup;
}
radeon_semaphore_emit_signal(rdev, ridxC, semaphore);
radeon_ring_unlock_commit(rdev, ringC);
for (i = 0; i < 30; ++i) {
mdelay(100);
sigA = radeon_fence_signaled(fenceA);
sigB = radeon_fence_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 = radeon_ring_lock(rdev, ringC, 64);
if (r) {
DRM_ERROR("Failed to lock ring B %p\n", ringC);
goto out_cleanup;
}
radeon_semaphore_emit_signal(rdev, ridxC, semaphore);
radeon_ring_unlock_commit(rdev, ringC);
mdelay(1000);
r = radeon_fence_wait(fenceA, false);
if (r) {
DRM_ERROR("Failed to wait for sync fence A\n");
goto out_cleanup;
}
r = radeon_fence_wait(fenceB, false);
if (r) {
DRM_ERROR("Failed to wait for sync fence B\n");
goto out_cleanup;
}
out_cleanup:
if (semaphore)
radeon_semaphore_free(rdev, semaphore);
if (fenceA)
radeon_fence_unref(&fenceA);
if (fenceB)
radeon_fence_unref(&fenceB);
if (r) if (r)
printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
...@@ -302,7 +451,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, ...@@ -302,7 +451,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev,
void radeon_test_syncing(struct radeon_device *rdev) void radeon_test_syncing(struct radeon_device *rdev)
{ {
int i, j; int i, j, k;
for (i = 1; i < RADEON_NUM_RINGS; ++i) { for (i = 1; i < RADEON_NUM_RINGS; ++i) {
struct radeon_ring *ringA = &rdev->ring[i]; struct radeon_ring *ringA = &rdev->ring[i];
...@@ -314,11 +463,33 @@ void radeon_test_syncing(struct radeon_device *rdev) ...@@ -314,11 +463,33 @@ void radeon_test_syncing(struct radeon_device *rdev)
if (!ringB->ready) if (!ringB->ready)
continue; continue;
DRM_INFO("Testing syncing between rings %d and %d\n", i, j); DRM_INFO("Testing syncing between rings %d and %d...\n", i, j);
radeon_test_ring_sync(rdev, ringA, ringB); radeon_test_ring_sync(rdev, ringA, ringB);
DRM_INFO("Testing syncing between rings %d and %d\n", j, i); DRM_INFO("Testing syncing between rings %d and %d...\n", j, i);
radeon_test_ring_sync(rdev, ringB, ringA); radeon_test_ring_sync(rdev, ringB, ringA);
for (k = 0; k < j; ++k) {
struct radeon_ring *ringC = &rdev->ring[k];
DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k);
radeon_test_ring_sync2(rdev, ringA, ringB, ringC);
DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, k, j);
radeon_test_ring_sync2(rdev, ringA, ringC, ringB);
DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, i, k);
radeon_test_ring_sync2(rdev, ringB, ringA, ringC);
DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, k, i);
radeon_test_ring_sync2(rdev, ringB, ringC, ringA);
DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, i, j);
radeon_test_ring_sync2(rdev, ringC, ringA, ringB);
DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, j, i);
radeon_test_ring_sync2(rdev, ringC, ringB, ringA);
}
} }
} }
} }
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