/* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */ staticvoid radeon_do_test_moves(struct radeon_device *rdev, int flag)
{ struct radeon_bo *vram_obj = NULL; struct radeon_bo **gtt_obj = NULL;
uint64_t gtt_addr, vram_addr; unsigned n, size; int i, r, ring;
switch (flag) { case RADEON_TEST_COPY_DMA:
ring = radeon_copy_dma_ring_index(rdev); break; case RADEON_TEST_COPY_BLIT:
ring = radeon_copy_blit_ring_index(rdev); break; default:
DRM_ERROR("Unknown copy method\n"); return;
}
size = 1024 * 1024;
/* Number of tests = *(TotalGTT-IBpool-writebackpage-ringbuffers)/testsize
*/
n = rdev->mc.gtt_size - rdev->gart_pin_size;
n /= size;
gtt_obj = kcalloc(n, sizeof(*gtt_obj), GFP_KERNEL); if (!gtt_obj) {
DRM_ERROR("Failed to allocate %d pointers\n", n);
r = 1; goto out_cleanup;
}
r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, &vram_obj); if (r) {
DRM_ERROR("Failed to create VRAM object\n"); goto out_cleanup;
}
r = radeon_bo_reserve(vram_obj, false); if (unlikely(r != 0)) goto out_unref;
r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); if (r) {
DRM_ERROR("Failed to pin VRAM object\n"); goto out_unres;
} for (i = 0; i < n; i++) { void *gtt_map, *vram_map; void **gtt_start, **gtt_end; void **vram_start, **vram_end; struct radeon_fence *fence = NULL;
r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT, 0, NULL, NULL,
gtt_obj + i); if (r) {
DRM_ERROR("Failed to create GTT object %d\n", i); goto out_lclean;
}
r = radeon_bo_reserve(gtt_obj[i], false); if (unlikely(r != 0)) goto out_lclean_unref;
r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr); if (r) {
DRM_ERROR("Failed to pin GTT object %d\n", i); goto out_lclean_unres;
}
r = radeon_bo_kmap(gtt_obj[i], >t_map); if (r) {
DRM_ERROR("Failed to map GTT object %d\n", i); goto out_lclean_unpin;
}
if (ring->idx == R600_RING_TYPE_UVD_INDEX) {
r = radeon_uvd_get_create_msg(rdev, ring->idx, handle, NULL); if (r) {
DRM_ERROR("Failed to get dummy create msg\n"); return r;
}
r = radeon_uvd_get_destroy_msg(rdev, ring->idx, handle, fence); if (r) {
DRM_ERROR("Failed to get dummy destroy msg\n"); return r;
}
} elseif (ring->idx == TN_RING_TYPE_VCE1_INDEX ||
ring->idx == TN_RING_TYPE_VCE2_INDEX) {
r = radeon_vce_get_create_msg(rdev, ring->idx, handle, NULL); if (r) {
DRM_ERROR("Failed to get dummy create msg\n"); return r;
}
r = radeon_vce_get_destroy_msg(rdev, ring->idx, handle, fence); if (r) {
DRM_ERROR("Failed to get dummy destroy msg\n"); return r;
}
} else {
r = radeon_ring_lock(rdev, ring, 64); if (r) {
DRM_ERROR("Failed to lock ring A %d\n", ring->idx); return r;
}
r = radeon_fence_emit(rdev, fence, ring->idx); if (r) {
DRM_ERROR("Failed to emit fence\n");
radeon_ring_unlock_undo(rdev, ring); return r;
}
radeon_ring_unlock_commit(rdev, ring, false);
} return0;
}
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", ringA->idx); goto out_cleanup;
}
radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringA, false);
r = radeon_test_create_and_emit_fence(rdev, ringA, &fence1); if (r) goto out_cleanup;
r = radeon_ring_lock(rdev, ringA, 64); if (r) {
DRM_ERROR("Failed to lock ring A %d\n", ringA->idx); goto out_cleanup;
}
radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringA, false);
r = radeon_test_create_and_emit_fence(rdev, ringA, &fence2); if (r) goto out_cleanup;
msleep(1000);
if (radeon_fence_signaled(fence1)) {
DRM_ERROR("Fence 1 signaled without waiting for semaphore.\n"); goto out_cleanup;
}
r = radeon_ring_lock(rdev, ringB, 64); if (r) {
DRM_ERROR("Failed to lock ring B %p\n", ringB); goto out_cleanup;
}
radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringB, false);
r = radeon_fence_wait(fence1, false); if (r) {
DRM_ERROR("Failed to wait for sync fence 1\n"); goto out_cleanup;
}
msleep(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) {
DRM_ERROR("Failed to lock ring B %p\n", ringB); goto out_cleanup;
}
radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringB, false);
r = radeon_fence_wait(fence2, false); if (r) {
DRM_ERROR("Failed to wait for sync fence 1\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", ringA->idx); goto out_cleanup;
}
radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringA, false);
r = radeon_test_create_and_emit_fence(rdev, ringA, &fenceA); if (r) goto out_cleanup;
r = radeon_ring_lock(rdev, ringB, 64); if (r) {
DRM_ERROR("Failed to lock ring B %d\n", ringB->idx); goto out_cleanup;
}
radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringB, false);
r = radeon_test_create_and_emit_fence(rdev, ringB, &fenceB); if (r) goto out_cleanup;
msleep(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 B 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, ringC->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringC, false);
for (i = 0; i < 30; ++i) {
msleep(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;
} elseif (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, ringC->idx, semaphore);
radeon_ring_unlock_commit(rdev, ringC, false);
msleep(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;
}
void radeon_test_syncing(struct radeon_device *rdev)
{ int i, j, k;
for (i = 1; i < RADEON_NUM_RINGS; ++i) { struct radeon_ring *ringA = &rdev->ring[i]; if (!ringA->ready) continue;
for (j = 0; j < i; ++j) { struct radeon_ring *ringB = &rdev->ring[j]; if (!ringB->ready) continue;
if (!radeon_test_sync_possible(ringA, ringB)) continue;
DRM_INFO("Testing syncing between rings %d and %d...\n", i, j);
radeon_test_ring_sync(rdev, ringA, ringB);
DRM_INFO("Testing syncing between rings %d and %d...\n", j, i);
radeon_test_ring_sync(rdev, ringB, ringA);
for (k = 0; k < j; ++k) { struct radeon_ring *ringC = &rdev->ring[k]; if (!ringC->ready) continue;
if (!radeon_test_sync_possible(ringA, ringC)) continue;
if (!radeon_test_sync_possible(ringB, ringC)) continue;
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);
}
}
}
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.