drm/radeon: Add radeon_test_syncing function v2
Tests syncing between all rings by using semaphores and fences. v2: use radeon_testing as a bit flag rather than on/off switch this allow to test for one thing at a time (bo_move or semaphore test). It kind of break the usage if user wheren't using 1 for bo move test but as it's a test feature i believe it's ok. Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
bf85279958
commit
60a7e3964d
3 changed files with 96 additions and 1 deletions
|
@ -913,6 +913,10 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number);
|
||||||
* Testing
|
* Testing
|
||||||
*/
|
*/
|
||||||
void radeon_test_moves(struct radeon_device *rdev);
|
void radeon_test_moves(struct radeon_device *rdev);
|
||||||
|
void radeon_test_ring_sync(struct radeon_device *rdev,
|
||||||
|
struct radeon_cp *cpA,
|
||||||
|
struct radeon_cp *cpB);
|
||||||
|
void radeon_test_syncing(struct radeon_device *rdev);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -823,9 +823,12 @@ int radeon_device_init(struct radeon_device *rdev,
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (radeon_testing) {
|
if ((radeon_testing & 1)) {
|
||||||
radeon_test_moves(rdev);
|
radeon_test_moves(rdev);
|
||||||
}
|
}
|
||||||
|
if ((radeon_testing & 2)) {
|
||||||
|
radeon_test_syncing(rdev);
|
||||||
|
}
|
||||||
if (radeon_benchmarking) {
|
if (radeon_benchmarking) {
|
||||||
radeon_benchmark(rdev, radeon_benchmarking);
|
radeon_benchmark(rdev, radeon_benchmarking);
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,3 +234,91 @@ out_cleanup:
|
||||||
printk(KERN_WARNING "Error while testing BO move.\n");
|
printk(KERN_WARNING "Error while testing BO move.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void radeon_test_ring_sync(struct radeon_device *rdev,
|
||||||
|
struct radeon_cp *cpA,
|
||||||
|
struct radeon_cp *cpB)
|
||||||
|
{
|
||||||
|
struct radeon_fence *fence = NULL;
|
||||||
|
struct radeon_semaphore *semaphore = NULL;
|
||||||
|
int ringA = radeon_ring_index(rdev, cpA);
|
||||||
|
int ringB = radeon_ring_index(rdev, cpB);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = radeon_fence_create(rdev, &fence, ringA);
|
||||||
|
if (r) {
|
||||||
|
DRM_ERROR("Failed to create sync fence\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, cpA, 64);
|
||||||
|
if (r) {
|
||||||
|
DRM_ERROR("Failed to lock ring %d\n", ringA);
|
||||||
|
goto out_cleanup;
|
||||||
|
}
|
||||||
|
radeon_semaphore_emit_wait(rdev, ringA, semaphore);
|
||||||
|
radeon_fence_emit(rdev, fence);
|
||||||
|
radeon_ring_unlock_commit(rdev, cpA);
|
||||||
|
|
||||||
|
mdelay(1000);
|
||||||
|
|
||||||
|
if (radeon_fence_signaled(fence)) {
|
||||||
|
DRM_ERROR("Fence signaled without waiting for semaphore.\n");
|
||||||
|
goto out_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = radeon_ring_lock(rdev, cpB, 64);
|
||||||
|
if (r) {
|
||||||
|
DRM_ERROR("Failed to lock ring %d\n", ringB);
|
||||||
|
goto out_cleanup;
|
||||||
|
}
|
||||||
|
radeon_semaphore_emit_signal(rdev, ringB, semaphore);
|
||||||
|
radeon_ring_unlock_commit(rdev, cpB);
|
||||||
|
|
||||||
|
r = radeon_fence_wait(fence, false);
|
||||||
|
if (r) {
|
||||||
|
DRM_ERROR("Failed to wait for sync fence\n");
|
||||||
|
goto out_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_INFO("Syncing between rings %d and %d seems to work.\n", ringA, ringB);
|
||||||
|
|
||||||
|
out_cleanup:
|
||||||
|
if (semaphore)
|
||||||
|
radeon_semaphore_free(rdev, semaphore);
|
||||||
|
|
||||||
|
if (fence)
|
||||||
|
radeon_fence_unref(&fence);
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void radeon_test_syncing(struct radeon_device *rdev)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 1; i < RADEON_NUM_RINGS; ++i) {
|
||||||
|
struct radeon_cp *cpA = &rdev->cp[i];
|
||||||
|
if (!cpA->ready)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < i; ++j) {
|
||||||
|
struct radeon_cp *cpB = &rdev->cp[j];
|
||||||
|
if (!cpB->ready)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DRM_INFO("Testing syncing between rings %d and %d\n", i, j);
|
||||||
|
radeon_test_ring_sync(rdev, cpA, cpB);
|
||||||
|
|
||||||
|
DRM_INFO("Testing syncing between rings %d and %d\n", j, i);
|
||||||
|
radeon_test_ring_sync(rdev, cpB, cpA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue