162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2009 Jerome Glisse. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Authors: Jerome Glisse 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include <drm/amdgpu_drm.h> 2662306a36Sopenharmony_ci#include "amdgpu.h" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define AMDGPU_BENCHMARK_ITERATIONS 1024 2962306a36Sopenharmony_ci#define AMDGPU_BENCHMARK_COMMON_MODES_N 17 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size, 3262306a36Sopenharmony_ci uint64_t saddr, uint64_t daddr, int n, s64 *time_ms) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci ktime_t stime, etime; 3562306a36Sopenharmony_ci struct dma_fence *fence; 3662306a36Sopenharmony_ci int i, r; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci stime = ktime_get(); 3962306a36Sopenharmony_ci for (i = 0; i < n; i++) { 4062306a36Sopenharmony_ci struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; 4162306a36Sopenharmony_ci r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence, 4262306a36Sopenharmony_ci false, false, false); 4362306a36Sopenharmony_ci if (r) 4462306a36Sopenharmony_ci goto exit_do_move; 4562306a36Sopenharmony_ci r = dma_fence_wait(fence, false); 4662306a36Sopenharmony_ci dma_fence_put(fence); 4762306a36Sopenharmony_ci if (r) 4862306a36Sopenharmony_ci goto exit_do_move; 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciexit_do_move: 5262306a36Sopenharmony_ci etime = ktime_get(); 5362306a36Sopenharmony_ci *time_ms = ktime_ms_delta(etime, stime); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return r; 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic void amdgpu_benchmark_log_results(struct amdgpu_device *adev, 6062306a36Sopenharmony_ci int n, unsigned size, 6162306a36Sopenharmony_ci s64 time_ms, 6262306a36Sopenharmony_ci unsigned sdomain, unsigned ddomain, 6362306a36Sopenharmony_ci char *kind) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci s64 throughput = (n * (size >> 10)); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci throughput = div64_s64(throughput, time_ms); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci dev_info(adev->dev, "amdgpu: %s %u bo moves of %u kB from" 7062306a36Sopenharmony_ci " %d to %d in %lld ms, throughput: %lld Mb/s or %lld MB/s\n", 7162306a36Sopenharmony_ci kind, n, size >> 10, sdomain, ddomain, time_ms, 7262306a36Sopenharmony_ci throughput * 8, throughput); 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic int amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, 7662306a36Sopenharmony_ci unsigned sdomain, unsigned ddomain) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci struct amdgpu_bo *dobj = NULL; 7962306a36Sopenharmony_ci struct amdgpu_bo *sobj = NULL; 8062306a36Sopenharmony_ci uint64_t saddr, daddr; 8162306a36Sopenharmony_ci s64 time_ms; 8262306a36Sopenharmony_ci int r, n; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci n = AMDGPU_BENCHMARK_ITERATIONS; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci r = amdgpu_bo_create_kernel(adev, size, 8762306a36Sopenharmony_ci PAGE_SIZE, sdomain, 8862306a36Sopenharmony_ci &sobj, 8962306a36Sopenharmony_ci &saddr, 9062306a36Sopenharmony_ci NULL); 9162306a36Sopenharmony_ci if (r) 9262306a36Sopenharmony_ci goto out_cleanup; 9362306a36Sopenharmony_ci r = amdgpu_bo_create_kernel(adev, size, 9462306a36Sopenharmony_ci PAGE_SIZE, ddomain, 9562306a36Sopenharmony_ci &dobj, 9662306a36Sopenharmony_ci &daddr, 9762306a36Sopenharmony_ci NULL); 9862306a36Sopenharmony_ci if (r) 9962306a36Sopenharmony_ci goto out_cleanup; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci if (adev->mman.buffer_funcs) { 10262306a36Sopenharmony_ci r = amdgpu_benchmark_do_move(adev, size, saddr, daddr, n, &time_ms); 10362306a36Sopenharmony_ci if (r) 10462306a36Sopenharmony_ci goto out_cleanup; 10562306a36Sopenharmony_ci else 10662306a36Sopenharmony_ci amdgpu_benchmark_log_results(adev, n, size, time_ms, 10762306a36Sopenharmony_ci sdomain, ddomain, "dma"); 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ciout_cleanup: 11162306a36Sopenharmony_ci /* Check error value now. The value can be overwritten when clean up.*/ 11262306a36Sopenharmony_ci if (r < 0) 11362306a36Sopenharmony_ci dev_info(adev->dev, "Error while benchmarking BO move.\n"); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (sobj) 11662306a36Sopenharmony_ci amdgpu_bo_free_kernel(&sobj, &saddr, NULL); 11762306a36Sopenharmony_ci if (dobj) 11862306a36Sopenharmony_ci amdgpu_bo_free_kernel(&dobj, &daddr, NULL); 11962306a36Sopenharmony_ci return r; 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ciint amdgpu_benchmark(struct amdgpu_device *adev, int test_number) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci int i, r; 12562306a36Sopenharmony_ci static const int common_modes[AMDGPU_BENCHMARK_COMMON_MODES_N] = { 12662306a36Sopenharmony_ci 640 * 480 * 4, 12762306a36Sopenharmony_ci 720 * 480 * 4, 12862306a36Sopenharmony_ci 800 * 600 * 4, 12962306a36Sopenharmony_ci 848 * 480 * 4, 13062306a36Sopenharmony_ci 1024 * 768 * 4, 13162306a36Sopenharmony_ci 1152 * 768 * 4, 13262306a36Sopenharmony_ci 1280 * 720 * 4, 13362306a36Sopenharmony_ci 1280 * 800 * 4, 13462306a36Sopenharmony_ci 1280 * 854 * 4, 13562306a36Sopenharmony_ci 1280 * 960 * 4, 13662306a36Sopenharmony_ci 1280 * 1024 * 4, 13762306a36Sopenharmony_ci 1440 * 900 * 4, 13862306a36Sopenharmony_ci 1400 * 1050 * 4, 13962306a36Sopenharmony_ci 1680 * 1050 * 4, 14062306a36Sopenharmony_ci 1600 * 1200 * 4, 14162306a36Sopenharmony_ci 1920 * 1080 * 4, 14262306a36Sopenharmony_ci 1920 * 1200 * 4 14362306a36Sopenharmony_ci }; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci mutex_lock(&adev->benchmark_mutex); 14662306a36Sopenharmony_ci switch (test_number) { 14762306a36Sopenharmony_ci case 1: 14862306a36Sopenharmony_ci dev_info(adev->dev, 14962306a36Sopenharmony_ci "benchmark test: %d (simple test, VRAM to GTT and GTT to VRAM)\n", 15062306a36Sopenharmony_ci test_number); 15162306a36Sopenharmony_ci /* simple test, VRAM to GTT and GTT to VRAM */ 15262306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_GTT, 15362306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM); 15462306a36Sopenharmony_ci if (r) 15562306a36Sopenharmony_ci goto done; 15662306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM, 15762306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_GTT); 15862306a36Sopenharmony_ci if (r) 15962306a36Sopenharmony_ci goto done; 16062306a36Sopenharmony_ci break; 16162306a36Sopenharmony_ci case 2: 16262306a36Sopenharmony_ci dev_info(adev->dev, 16362306a36Sopenharmony_ci "benchmark test: %d (simple test, VRAM to VRAM)\n", 16462306a36Sopenharmony_ci test_number); 16562306a36Sopenharmony_ci /* simple test, VRAM to VRAM */ 16662306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM, 16762306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM); 16862306a36Sopenharmony_ci if (r) 16962306a36Sopenharmony_ci goto done; 17062306a36Sopenharmony_ci break; 17162306a36Sopenharmony_ci case 3: 17262306a36Sopenharmony_ci dev_info(adev->dev, 17362306a36Sopenharmony_ci "benchmark test: %d (GTT to VRAM, buffer size sweep, powers of 2)\n", 17462306a36Sopenharmony_ci test_number); 17562306a36Sopenharmony_ci /* GTT to VRAM, buffer size sweep, powers of 2 */ 17662306a36Sopenharmony_ci for (i = 1; i <= 16384; i <<= 1) { 17762306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE, 17862306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_GTT, 17962306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM); 18062306a36Sopenharmony_ci if (r) 18162306a36Sopenharmony_ci goto done; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci break; 18462306a36Sopenharmony_ci case 4: 18562306a36Sopenharmony_ci dev_info(adev->dev, 18662306a36Sopenharmony_ci "benchmark test: %d (VRAM to GTT, buffer size sweep, powers of 2)\n", 18762306a36Sopenharmony_ci test_number); 18862306a36Sopenharmony_ci /* VRAM to GTT, buffer size sweep, powers of 2 */ 18962306a36Sopenharmony_ci for (i = 1; i <= 16384; i <<= 1) { 19062306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE, 19162306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM, 19262306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_GTT); 19362306a36Sopenharmony_ci if (r) 19462306a36Sopenharmony_ci goto done; 19562306a36Sopenharmony_ci } 19662306a36Sopenharmony_ci break; 19762306a36Sopenharmony_ci case 5: 19862306a36Sopenharmony_ci dev_info(adev->dev, 19962306a36Sopenharmony_ci "benchmark test: %d (VRAM to VRAM, buffer size sweep, powers of 2)\n", 20062306a36Sopenharmony_ci test_number); 20162306a36Sopenharmony_ci /* VRAM to VRAM, buffer size sweep, powers of 2 */ 20262306a36Sopenharmony_ci for (i = 1; i <= 16384; i <<= 1) { 20362306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE, 20462306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM, 20562306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM); 20662306a36Sopenharmony_ci if (r) 20762306a36Sopenharmony_ci goto done; 20862306a36Sopenharmony_ci } 20962306a36Sopenharmony_ci break; 21062306a36Sopenharmony_ci case 6: 21162306a36Sopenharmony_ci dev_info(adev->dev, 21262306a36Sopenharmony_ci "benchmark test: %d (GTT to VRAM, buffer size sweep, common modes)\n", 21362306a36Sopenharmony_ci test_number); 21462306a36Sopenharmony_ci /* GTT to VRAM, buffer size sweep, common modes */ 21562306a36Sopenharmony_ci for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++) { 21662306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, common_modes[i], 21762306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_GTT, 21862306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM); 21962306a36Sopenharmony_ci if (r) 22062306a36Sopenharmony_ci goto done; 22162306a36Sopenharmony_ci } 22262306a36Sopenharmony_ci break; 22362306a36Sopenharmony_ci case 7: 22462306a36Sopenharmony_ci dev_info(adev->dev, 22562306a36Sopenharmony_ci "benchmark test: %d (VRAM to GTT, buffer size sweep, common modes)\n", 22662306a36Sopenharmony_ci test_number); 22762306a36Sopenharmony_ci /* VRAM to GTT, buffer size sweep, common modes */ 22862306a36Sopenharmony_ci for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++) { 22962306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, common_modes[i], 23062306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM, 23162306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_GTT); 23262306a36Sopenharmony_ci if (r) 23362306a36Sopenharmony_ci goto done; 23462306a36Sopenharmony_ci } 23562306a36Sopenharmony_ci break; 23662306a36Sopenharmony_ci case 8: 23762306a36Sopenharmony_ci dev_info(adev->dev, 23862306a36Sopenharmony_ci "benchmark test: %d (VRAM to VRAM, buffer size sweep, common modes)\n", 23962306a36Sopenharmony_ci test_number); 24062306a36Sopenharmony_ci /* VRAM to VRAM, buffer size sweep, common modes */ 24162306a36Sopenharmony_ci for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++) { 24262306a36Sopenharmony_ci r = amdgpu_benchmark_move(adev, common_modes[i], 24362306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM, 24462306a36Sopenharmony_ci AMDGPU_GEM_DOMAIN_VRAM); 24562306a36Sopenharmony_ci if (r) 24662306a36Sopenharmony_ci goto done; 24762306a36Sopenharmony_ci } 24862306a36Sopenharmony_ci break; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci default: 25162306a36Sopenharmony_ci dev_info(adev->dev, "Unknown benchmark %d\n", test_number); 25262306a36Sopenharmony_ci r = -EINVAL; 25362306a36Sopenharmony_ci break; 25462306a36Sopenharmony_ci } 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_cidone: 25762306a36Sopenharmony_ci mutex_unlock(&adev->benchmark_mutex); 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci return r; 26062306a36Sopenharmony_ci} 261