100a23bdaSmrg/* 200a23bdaSmrg * Copyright 2017 Advanced Micro Devices, Inc. 300a23bdaSmrg * 400a23bdaSmrg * Permission is hereby granted, free of charge, to any person obtaining a 500a23bdaSmrg * copy of this software and associated documentation files (the "Software"), 600a23bdaSmrg * to deal in the Software without restriction, including without limitation 700a23bdaSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 800a23bdaSmrg * and/or sell copies of the Software, and to permit persons to whom the 900a23bdaSmrg * Software is furnished to do so, subject to the following conditions: 1000a23bdaSmrg * 1100a23bdaSmrg * The above copyright notice and this permission notice shall be included in 1200a23bdaSmrg * all copies or substantial portions of the Software. 1300a23bdaSmrg * 1400a23bdaSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1500a23bdaSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1600a23bdaSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1700a23bdaSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1800a23bdaSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1900a23bdaSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2000a23bdaSmrg * OTHER DEALINGS IN THE SOFTWARE. 2100a23bdaSmrg * 2200a23bdaSmrg*/ 2300a23bdaSmrg 2400a23bdaSmrg#include <stdio.h> 2500a23bdaSmrg#include <stdlib.h> 2600a23bdaSmrg#include <unistd.h> 279bd392adSmrg#if HAVE_ALLOCA_H 2800a23bdaSmrg# include <alloca.h> 2900a23bdaSmrg#endif 3000a23bdaSmrg 3100a23bdaSmrg#include "CUnit/Basic.h" 3200a23bdaSmrg 3300a23bdaSmrg#include "amdgpu_test.h" 3400a23bdaSmrg#include "amdgpu_drm.h" 3500a23bdaSmrg#include "amdgpu_internal.h" 3600a23bdaSmrg 3700a23bdaSmrg#include <pthread.h> 3800a23bdaSmrg 3900a23bdaSmrg 4000a23bdaSmrg/* 4100a23bdaSmrg * This defines the delay in MS after which memory location designated for 4200a23bdaSmrg * compression against reference value is written to, unblocking command 4300a23bdaSmrg * processor 4400a23bdaSmrg */ 4500a23bdaSmrg#define WRITE_MEM_ADDRESS_DELAY_MS 100 4600a23bdaSmrg 4700a23bdaSmrg#define PACKET_TYPE3 3 4800a23bdaSmrg 4900a23bdaSmrg#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ 5000a23bdaSmrg (((op) & 0xFF) << 8) | \ 5100a23bdaSmrg ((n) & 0x3FFF) << 16) 5200a23bdaSmrg 5300a23bdaSmrg#define PACKET3_WAIT_REG_MEM 0x3C 5400a23bdaSmrg#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) 5500a23bdaSmrg /* 0 - always 5600a23bdaSmrg * 1 - < 5700a23bdaSmrg * 2 - <= 5800a23bdaSmrg * 3 - == 5900a23bdaSmrg * 4 - != 6000a23bdaSmrg * 5 - >= 6100a23bdaSmrg * 6 - > 6200a23bdaSmrg */ 6300a23bdaSmrg#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) 6400a23bdaSmrg /* 0 - reg 6500a23bdaSmrg * 1 - mem 6600a23bdaSmrg */ 6700a23bdaSmrg#define WAIT_REG_MEM_OPERATION(x) ((x) << 6) 6800a23bdaSmrg /* 0 - wait_reg_mem 6900a23bdaSmrg * 1 - wr_wait_wr_reg 7000a23bdaSmrg */ 7100a23bdaSmrg#define WAIT_REG_MEM_ENGINE(x) ((x) << 8) 7200a23bdaSmrg /* 0 - me 7300a23bdaSmrg * 1 - pfp 7400a23bdaSmrg */ 7500a23bdaSmrg 766532f28eSmrg#define PACKET3_WRITE_DATA 0x37 776532f28eSmrg#define WRITE_DATA_DST_SEL(x) ((x) << 8) 786532f28eSmrg /* 0 - register 796532f28eSmrg * 1 - memory (sync - via GRBM) 806532f28eSmrg * 2 - gl2 816532f28eSmrg * 3 - gds 826532f28eSmrg * 4 - reserved 836532f28eSmrg * 5 - memory (async - direct) 846532f28eSmrg */ 856532f28eSmrg#define WR_ONE_ADDR (1 << 16) 866532f28eSmrg#define WR_CONFIRM (1 << 20) 876532f28eSmrg#define WRITE_DATA_CACHE_POLICY(x) ((x) << 25) 886532f28eSmrg /* 0 - LRU 896532f28eSmrg * 1 - Stream 906532f28eSmrg */ 916532f28eSmrg#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30) 926532f28eSmrg /* 0 - me 936532f28eSmrg * 1 - pfp 946532f28eSmrg * 2 - ce 956532f28eSmrg */ 966532f28eSmrg 976532f28eSmrg#define mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x54f 986532f28eSmrg 995324fb0dSmrg#define SDMA_PKT_HEADER_OP(x) (x & 0xff) 1005324fb0dSmrg#define SDMA_OP_POLL_REGMEM 8 1015324fb0dSmrg 10200a23bdaSmrgstatic amdgpu_device_handle device_handle; 10300a23bdaSmrgstatic uint32_t major_version; 10400a23bdaSmrgstatic uint32_t minor_version; 10500a23bdaSmrg 10600a23bdaSmrgstatic pthread_t stress_thread; 10700a23bdaSmrgstatic uint32_t *ptr; 10800a23bdaSmrg 1094babd585Smrgstatic uint32_t family_id; 1104babd585Smrgstatic uint32_t chip_rev; 1114babd585Smrgstatic uint32_t chip_id; 1124babd585Smrg 1137cdc0497Smrgint use_uc_mtype = 0; 1147cdc0497Smrg 11500a23bdaSmrgstatic void amdgpu_deadlock_helper(unsigned ip_type); 11600a23bdaSmrgstatic void amdgpu_deadlock_gfx(void); 11700a23bdaSmrgstatic void amdgpu_deadlock_compute(void); 1186532f28eSmrgstatic void amdgpu_illegal_reg_access(); 1196532f28eSmrgstatic void amdgpu_illegal_mem_access(); 1205324fb0dSmrgstatic void amdgpu_deadlock_sdma(void); 1219bd392adSmrgstatic void amdgpu_dispatch_hang_gfx(void); 1229bd392adSmrgstatic void amdgpu_dispatch_hang_compute(void); 1239bd392adSmrgstatic void amdgpu_dispatch_hang_slow_gfx(void); 1249bd392adSmrgstatic void amdgpu_dispatch_hang_slow_compute(void); 1259bd392adSmrgstatic void amdgpu_draw_hang_gfx(void); 1269bd392adSmrgstatic void amdgpu_draw_hang_slow_gfx(void); 127b0ab5608Smrgstatic void amdgpu_hang_sdma(void); 128b0ab5608Smrgstatic void amdgpu_hang_slow_sdma(void); 12900a23bdaSmrg 13000a23bdaSmrgCU_BOOL suite_deadlock_tests_enable(void) 13100a23bdaSmrg{ 13200a23bdaSmrg CU_BOOL enable = CU_TRUE; 13300a23bdaSmrg 13400a23bdaSmrg if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, 13500a23bdaSmrg &minor_version, &device_handle)) 13600a23bdaSmrg return CU_FALSE; 13700a23bdaSmrg 1384babd585Smrg family_id = device_handle->info.family_id; 1394babd585Smrg chip_id = device_handle->info.chip_external_rev; 1404babd585Smrg chip_rev = device_handle->info.chip_rev; 1414babd585Smrg 1426532f28eSmrg /* 1436532f28eSmrg * Only enable for ASICs supporting GPU reset and for which it's enabled 1440ed5401bSmrg * by default (currently GFX8+ dGPUS and gfx9+ APUs). Note that Raven1 1450ed5401bSmrg * did not support GPU reset, but newer variants do. 1466532f28eSmrg */ 1470ed5401bSmrg if (family_id == AMDGPU_FAMILY_SI || 1480ed5401bSmrg family_id == AMDGPU_FAMILY_KV || 1490ed5401bSmrg family_id == AMDGPU_FAMILY_CZ || 1500ed5401bSmrg family_id == AMDGPU_FAMILY_RV) { 1516532f28eSmrg printf("\n\nGPU reset is not enabled for the ASIC, deadlock suite disabled\n"); 15200a23bdaSmrg enable = CU_FALSE; 15300a23bdaSmrg } 15400a23bdaSmrg 1554babd585Smrg if (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) { 15641687f09Smrg if (amdgpu_set_test_active("Deadlock Tests", 15741687f09Smrg "gfx ring block test (set amdgpu.lockup_timeout=50)", 15841687f09Smrg CU_FALSE)) 15941687f09Smrg fprintf(stderr, "test deactivation failed - %s\n", 16041687f09Smrg CU_get_error_msg()); 16141687f09Smrg } 16241687f09Smrg 1637cdc0497Smrg if (device_handle->info.family_id >= AMDGPU_FAMILY_AI) 1647cdc0497Smrg use_uc_mtype = 1; 1657cdc0497Smrg 16600a23bdaSmrg if (amdgpu_device_deinitialize(device_handle)) 16700a23bdaSmrg return CU_FALSE; 16800a23bdaSmrg 16900a23bdaSmrg return enable; 17000a23bdaSmrg} 17100a23bdaSmrg 17200a23bdaSmrgint suite_deadlock_tests_init(void) 17300a23bdaSmrg{ 17400a23bdaSmrg int r; 17500a23bdaSmrg 17600a23bdaSmrg r = amdgpu_device_initialize(drm_amdgpu[0], &major_version, 17700a23bdaSmrg &minor_version, &device_handle); 17800a23bdaSmrg 17900a23bdaSmrg if (r) { 18000a23bdaSmrg if ((r == -EACCES) && (errno == EACCES)) 18100a23bdaSmrg printf("\n\nError:%s. " 18200a23bdaSmrg "Hint:Try to run this test program as root.", 18300a23bdaSmrg strerror(errno)); 18400a23bdaSmrg return CUE_SINIT_FAILED; 18500a23bdaSmrg } 18600a23bdaSmrg 18700a23bdaSmrg return CUE_SUCCESS; 18800a23bdaSmrg} 18900a23bdaSmrg 19000a23bdaSmrgint suite_deadlock_tests_clean(void) 19100a23bdaSmrg{ 19200a23bdaSmrg int r = amdgpu_device_deinitialize(device_handle); 19300a23bdaSmrg 19400a23bdaSmrg if (r == 0) 19500a23bdaSmrg return CUE_SUCCESS; 19600a23bdaSmrg else 19700a23bdaSmrg return CUE_SCLEAN_FAILED; 19800a23bdaSmrg} 19900a23bdaSmrg 20000a23bdaSmrg 20100a23bdaSmrgCU_TestInfo deadlock_tests[] = { 2026532f28eSmrg { "gfx ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_gfx }, 2036532f28eSmrg { "compute ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_compute }, 2045324fb0dSmrg { "sdma ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_sdma }, 2056532f28eSmrg { "illegal reg access test", amdgpu_illegal_reg_access }, 2066532f28eSmrg { "illegal mem access test (set amdgpu.vm_fault_stop=2)", amdgpu_illegal_mem_access }, 2079bd392adSmrg { "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_gfx }, 2089bd392adSmrg { "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_compute }, 2099bd392adSmrg { "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_slow_gfx }, 2109bd392adSmrg { "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_slow_compute }, 2119bd392adSmrg { "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_gfx }, 2129bd392adSmrg { "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_slow_gfx }, 213b0ab5608Smrg { "sdma ring corrupted header test (set amdgpu.lockup_timeout=50)", amdgpu_hang_sdma }, 214b0ab5608Smrg { "sdma ring slow linear copy test (set amdgpu.lockup_timeout=50)", amdgpu_hang_slow_sdma }, 21500a23bdaSmrg CU_TEST_INFO_NULL, 21600a23bdaSmrg}; 21700a23bdaSmrg 21800a23bdaSmrgstatic void *write_mem_address(void *data) 21900a23bdaSmrg{ 22000a23bdaSmrg int i; 22100a23bdaSmrg 22200a23bdaSmrg /* useconds_t range is [0, 1,000,000] so use loop for waits > 1s */ 22300a23bdaSmrg for (i = 0; i < WRITE_MEM_ADDRESS_DELAY_MS; i++) 22400a23bdaSmrg usleep(1000); 22500a23bdaSmrg 22600a23bdaSmrg ptr[256] = 0x1; 22700a23bdaSmrg 22800a23bdaSmrg return 0; 22900a23bdaSmrg} 23000a23bdaSmrg 23100a23bdaSmrgstatic void amdgpu_deadlock_gfx(void) 23200a23bdaSmrg{ 23300a23bdaSmrg amdgpu_deadlock_helper(AMDGPU_HW_IP_GFX); 23400a23bdaSmrg} 23500a23bdaSmrg 23600a23bdaSmrgstatic void amdgpu_deadlock_compute(void) 23700a23bdaSmrg{ 23800a23bdaSmrg amdgpu_deadlock_helper(AMDGPU_HW_IP_COMPUTE); 23900a23bdaSmrg} 24000a23bdaSmrg 24100a23bdaSmrgstatic void amdgpu_deadlock_helper(unsigned ip_type) 24200a23bdaSmrg{ 24300a23bdaSmrg amdgpu_context_handle context_handle; 24400a23bdaSmrg amdgpu_bo_handle ib_result_handle; 24500a23bdaSmrg void *ib_result_cpu; 24600a23bdaSmrg uint64_t ib_result_mc_address; 24700a23bdaSmrg struct amdgpu_cs_request ibs_request; 24800a23bdaSmrg struct amdgpu_cs_ib_info ib_info; 24900a23bdaSmrg struct amdgpu_cs_fence fence_status; 25000a23bdaSmrg uint32_t expired; 25100a23bdaSmrg int i, r; 25200a23bdaSmrg amdgpu_bo_list_handle bo_list; 25300a23bdaSmrg amdgpu_va_handle va_handle; 25400a23bdaSmrg 25500a23bdaSmrg r = pthread_create(&stress_thread, NULL, write_mem_address, NULL); 25600a23bdaSmrg CU_ASSERT_EQUAL(r, 0); 25700a23bdaSmrg 25800a23bdaSmrg r = amdgpu_cs_ctx_create(device_handle, &context_handle); 25900a23bdaSmrg CU_ASSERT_EQUAL(r, 0); 26000a23bdaSmrg 2617cdc0497Smrg r = amdgpu_bo_alloc_and_map_raw(device_handle, 4096, 4096, 2627cdc0497Smrg AMDGPU_GEM_DOMAIN_GTT, 0, use_uc_mtype ? AMDGPU_VM_MTYPE_UC : 0, 26300a23bdaSmrg &ib_result_handle, &ib_result_cpu, 26400a23bdaSmrg &ib_result_mc_address, &va_handle); 26500a23bdaSmrg CU_ASSERT_EQUAL(r, 0); 26600a23bdaSmrg 26700a23bdaSmrg r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, 26800a23bdaSmrg &bo_list); 26900a23bdaSmrg CU_ASSERT_EQUAL(r, 0); 27000a23bdaSmrg 27100a23bdaSmrg ptr = ib_result_cpu; 27200a23bdaSmrg 27300a23bdaSmrg ptr[0] = PACKET3(PACKET3_WAIT_REG_MEM, 5); 27400a23bdaSmrg ptr[1] = (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */ 27500a23bdaSmrg WAIT_REG_MEM_FUNCTION(4) | /* != */ 27600a23bdaSmrg WAIT_REG_MEM_ENGINE(0)); /* me */ 27700a23bdaSmrg ptr[2] = (ib_result_mc_address + 256*4) & 0xfffffffc; 27800a23bdaSmrg ptr[3] = ((ib_result_mc_address + 256*4) >> 32) & 0xffffffff; 27900a23bdaSmrg ptr[4] = 0x00000000; /* reference value */ 28000a23bdaSmrg ptr[5] = 0xffffffff; /* and mask */ 28100a23bdaSmrg ptr[6] = 0x00000004; /* poll interval */ 28200a23bdaSmrg 28300a23bdaSmrg for (i = 7; i < 16; ++i) 28400a23bdaSmrg ptr[i] = 0xffff1000; 28500a23bdaSmrg 28600a23bdaSmrg 28700a23bdaSmrg ptr[256] = 0x0; /* the memory we wait on to change */ 28800a23bdaSmrg 28900a23bdaSmrg 29000a23bdaSmrg 29100a23bdaSmrg memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info)); 29200a23bdaSmrg ib_info.ib_mc_address = ib_result_mc_address; 29300a23bdaSmrg ib_info.size = 16; 29400a23bdaSmrg 29500a23bdaSmrg memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request)); 29600a23bdaSmrg ibs_request.ip_type = ip_type; 29700a23bdaSmrg ibs_request.ring = 0; 29800a23bdaSmrg ibs_request.number_of_ibs = 1; 29900a23bdaSmrg ibs_request.ibs = &ib_info; 30000a23bdaSmrg ibs_request.resources = bo_list; 30100a23bdaSmrg ibs_request.fence_info.handle = NULL; 30200a23bdaSmrg for (i = 0; i < 200; i++) { 30300a23bdaSmrg r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1); 30400a23bdaSmrg CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); 30500a23bdaSmrg 30600a23bdaSmrg } 30700a23bdaSmrg 30800a23bdaSmrg memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence)); 30900a23bdaSmrg fence_status.context = context_handle; 31000a23bdaSmrg fence_status.ip_type = ip_type; 31100a23bdaSmrg fence_status.ip_instance = 0; 31200a23bdaSmrg fence_status.ring = 0; 31300a23bdaSmrg fence_status.fence = ibs_request.seq_no; 31400a23bdaSmrg 31500a23bdaSmrg r = amdgpu_cs_query_fence_status(&fence_status, 31600a23bdaSmrg AMDGPU_TIMEOUT_INFINITE,0, &expired); 31700a23bdaSmrg CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); 31800a23bdaSmrg 31900a23bdaSmrg pthread_join(stress_thread, NULL); 32000a23bdaSmrg 32100a23bdaSmrg r = amdgpu_bo_list_destroy(bo_list); 32200a23bdaSmrg CU_ASSERT_EQUAL(r, 0); 32300a23bdaSmrg 32400a23bdaSmrg r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle, 32500a23bdaSmrg ib_result_mc_address, 4096); 32600a23bdaSmrg CU_ASSERT_EQUAL(r, 0); 32700a23bdaSmrg 32800a23bdaSmrg r = amdgpu_cs_ctx_free(context_handle); 32900a23bdaSmrg CU_ASSERT_EQUAL(r, 0); 33000a23bdaSmrg} 3316532f28eSmrg 3325324fb0dSmrgstatic void amdgpu_deadlock_sdma(void) 3335324fb0dSmrg{ 3345324fb0dSmrg amdgpu_context_handle context_handle; 3355324fb0dSmrg amdgpu_bo_handle ib_result_handle; 3365324fb0dSmrg void *ib_result_cpu; 3375324fb0dSmrg uint64_t ib_result_mc_address; 3385324fb0dSmrg struct amdgpu_cs_request ibs_request; 3395324fb0dSmrg struct amdgpu_cs_ib_info ib_info; 3405324fb0dSmrg struct amdgpu_cs_fence fence_status; 3415324fb0dSmrg uint32_t expired; 3425324fb0dSmrg int i, r; 3435324fb0dSmrg amdgpu_bo_list_handle bo_list; 3445324fb0dSmrg amdgpu_va_handle va_handle; 3455324fb0dSmrg struct drm_amdgpu_info_hw_ip info; 3465324fb0dSmrg uint32_t ring_id; 3475324fb0dSmrg 3485324fb0dSmrg r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_DMA, 0, &info); 3495324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 3505324fb0dSmrg 3515324fb0dSmrg r = amdgpu_cs_ctx_create(device_handle, &context_handle); 3525324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 3535324fb0dSmrg 3545324fb0dSmrg for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { 3555324fb0dSmrg r = pthread_create(&stress_thread, NULL, write_mem_address, NULL); 3565324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 3575324fb0dSmrg 3585324fb0dSmrg r = amdgpu_bo_alloc_and_map_raw(device_handle, 4096, 4096, 3595324fb0dSmrg AMDGPU_GEM_DOMAIN_GTT, 0, use_uc_mtype ? AMDGPU_VM_MTYPE_UC : 0, 3605324fb0dSmrg &ib_result_handle, &ib_result_cpu, 3615324fb0dSmrg &ib_result_mc_address, &va_handle); 3625324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 3635324fb0dSmrg 3645324fb0dSmrg r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, 3655324fb0dSmrg &bo_list); 3665324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 3675324fb0dSmrg 3685324fb0dSmrg ptr = ib_result_cpu; 3695324fb0dSmrg i = 0; 3705324fb0dSmrg 3715324fb0dSmrg ptr[i++] = SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | 3725324fb0dSmrg (0 << 26) | /* WAIT_REG_MEM */ 3735324fb0dSmrg (4 << 28) | /* != */ 3745324fb0dSmrg (1 << 31); /* memory */ 3755324fb0dSmrg ptr[i++] = (ib_result_mc_address + 256*4) & 0xfffffffc; 3765324fb0dSmrg ptr[i++] = ((ib_result_mc_address + 256*4) >> 32) & 0xffffffff; 3775324fb0dSmrg ptr[i++] = 0x00000000; /* reference value */ 3785324fb0dSmrg ptr[i++] = 0xffffffff; /* and mask */ 3795324fb0dSmrg ptr[i++] = 4 | /* poll interval */ 3805324fb0dSmrg (0xfff << 16); /* retry count */ 3815324fb0dSmrg 3825324fb0dSmrg for (; i < 16; i++) 3835324fb0dSmrg ptr[i] = 0; 3845324fb0dSmrg 3855324fb0dSmrg ptr[256] = 0x0; /* the memory we wait on to change */ 3865324fb0dSmrg 3875324fb0dSmrg memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info)); 3885324fb0dSmrg ib_info.ib_mc_address = ib_result_mc_address; 3895324fb0dSmrg ib_info.size = 16; 3905324fb0dSmrg 3915324fb0dSmrg memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request)); 3925324fb0dSmrg ibs_request.ip_type = AMDGPU_HW_IP_DMA; 3935324fb0dSmrg ibs_request.ring = ring_id; 3945324fb0dSmrg ibs_request.number_of_ibs = 1; 3955324fb0dSmrg ibs_request.ibs = &ib_info; 3965324fb0dSmrg ibs_request.resources = bo_list; 3975324fb0dSmrg ibs_request.fence_info.handle = NULL; 3985324fb0dSmrg 3995324fb0dSmrg for (i = 0; i < 200; i++) { 4005324fb0dSmrg r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1); 4015324fb0dSmrg CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); 4025324fb0dSmrg 4035324fb0dSmrg } 4045324fb0dSmrg 4055324fb0dSmrg memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence)); 4065324fb0dSmrg fence_status.context = context_handle; 4075324fb0dSmrg fence_status.ip_type = AMDGPU_HW_IP_DMA; 4085324fb0dSmrg fence_status.ip_instance = 0; 4095324fb0dSmrg fence_status.ring = ring_id; 4105324fb0dSmrg fence_status.fence = ibs_request.seq_no; 4115324fb0dSmrg 4125324fb0dSmrg r = amdgpu_cs_query_fence_status(&fence_status, 4135324fb0dSmrg AMDGPU_TIMEOUT_INFINITE,0, &expired); 4145324fb0dSmrg CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); 4155324fb0dSmrg 4165324fb0dSmrg pthread_join(stress_thread, NULL); 4175324fb0dSmrg 4185324fb0dSmrg r = amdgpu_bo_list_destroy(bo_list); 4195324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 4205324fb0dSmrg 4215324fb0dSmrg r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle, 4225324fb0dSmrg ib_result_mc_address, 4096); 4235324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 4245324fb0dSmrg } 4255324fb0dSmrg r = amdgpu_cs_ctx_free(context_handle); 4265324fb0dSmrg CU_ASSERT_EQUAL(r, 0); 4275324fb0dSmrg} 4285324fb0dSmrg 4296532f28eSmrgstatic void bad_access_helper(int reg_access) 4306532f28eSmrg{ 4316532f28eSmrg amdgpu_context_handle context_handle; 4326532f28eSmrg amdgpu_bo_handle ib_result_handle; 4336532f28eSmrg void *ib_result_cpu; 4346532f28eSmrg uint64_t ib_result_mc_address; 4356532f28eSmrg struct amdgpu_cs_request ibs_request; 4366532f28eSmrg struct amdgpu_cs_ib_info ib_info; 4376532f28eSmrg struct amdgpu_cs_fence fence_status; 4386532f28eSmrg uint32_t expired; 4396532f28eSmrg int i, r; 4406532f28eSmrg amdgpu_bo_list_handle bo_list; 4416532f28eSmrg amdgpu_va_handle va_handle; 4426532f28eSmrg 4436532f28eSmrg r = amdgpu_cs_ctx_create(device_handle, &context_handle); 4446532f28eSmrg CU_ASSERT_EQUAL(r, 0); 4456532f28eSmrg 4466532f28eSmrg r = amdgpu_bo_alloc_and_map_raw(device_handle, 4096, 4096, 4476532f28eSmrg AMDGPU_GEM_DOMAIN_GTT, 0, 0, 4486532f28eSmrg &ib_result_handle, &ib_result_cpu, 4496532f28eSmrg &ib_result_mc_address, &va_handle); 4506532f28eSmrg CU_ASSERT_EQUAL(r, 0); 4516532f28eSmrg 4526532f28eSmrg r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, 4536532f28eSmrg &bo_list); 4546532f28eSmrg CU_ASSERT_EQUAL(r, 0); 4556532f28eSmrg 4566532f28eSmrg ptr = ib_result_cpu; 4576532f28eSmrg i = 0; 4586532f28eSmrg 4596532f28eSmrg ptr[i++] = PACKET3(PACKET3_WRITE_DATA, 3); 4606532f28eSmrg ptr[i++] = (reg_access ? WRITE_DATA_DST_SEL(0) : WRITE_DATA_DST_SEL(5))| WR_CONFIRM; 4616532f28eSmrg ptr[i++] = reg_access ? mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR : 0xdeadbee0; 4626532f28eSmrg ptr[i++] = 0; 4636532f28eSmrg ptr[i++] = 0xdeadbeef; 4646532f28eSmrg 4656532f28eSmrg for (; i < 16; ++i) 4666532f28eSmrg ptr[i] = 0xffff1000; 4676532f28eSmrg 4686532f28eSmrg memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info)); 4696532f28eSmrg ib_info.ib_mc_address = ib_result_mc_address; 4706532f28eSmrg ib_info.size = 16; 4716532f28eSmrg 4726532f28eSmrg memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request)); 4736532f28eSmrg ibs_request.ip_type = AMDGPU_HW_IP_GFX; 4746532f28eSmrg ibs_request.ring = 0; 4756532f28eSmrg ibs_request.number_of_ibs = 1; 4766532f28eSmrg ibs_request.ibs = &ib_info; 4776532f28eSmrg ibs_request.resources = bo_list; 4786532f28eSmrg ibs_request.fence_info.handle = NULL; 4796532f28eSmrg 4806532f28eSmrg r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1); 4816532f28eSmrg CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); 4826532f28eSmrg 4836532f28eSmrg 4846532f28eSmrg memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence)); 4856532f28eSmrg fence_status.context = context_handle; 4866532f28eSmrg fence_status.ip_type = AMDGPU_HW_IP_GFX; 4876532f28eSmrg fence_status.ip_instance = 0; 4886532f28eSmrg fence_status.ring = 0; 4896532f28eSmrg fence_status.fence = ibs_request.seq_no; 4906532f28eSmrg 4916532f28eSmrg r = amdgpu_cs_query_fence_status(&fence_status, 4926532f28eSmrg AMDGPU_TIMEOUT_INFINITE,0, &expired); 4936532f28eSmrg CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); 4946532f28eSmrg 4956532f28eSmrg r = amdgpu_bo_list_destroy(bo_list); 4966532f28eSmrg CU_ASSERT_EQUAL(r, 0); 4976532f28eSmrg 4986532f28eSmrg r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle, 4996532f28eSmrg ib_result_mc_address, 4096); 5006532f28eSmrg CU_ASSERT_EQUAL(r, 0); 5016532f28eSmrg 5026532f28eSmrg r = amdgpu_cs_ctx_free(context_handle); 5036532f28eSmrg CU_ASSERT_EQUAL(r, 0); 5046532f28eSmrg} 5056532f28eSmrg 5066532f28eSmrgstatic void amdgpu_illegal_reg_access() 5076532f28eSmrg{ 5086532f28eSmrg bad_access_helper(1); 5096532f28eSmrg} 5106532f28eSmrg 5116532f28eSmrgstatic void amdgpu_illegal_mem_access() 5126532f28eSmrg{ 5136532f28eSmrg bad_access_helper(0); 5146532f28eSmrg} 5159bd392adSmrg 5169bd392adSmrgstatic void amdgpu_dispatch_hang_gfx(void) 5179bd392adSmrg{ 518b0ab5608Smrg amdgpu_test_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_GFX); 5199bd392adSmrg} 5209bd392adSmrgstatic void amdgpu_dispatch_hang_compute(void) 5219bd392adSmrg{ 522b0ab5608Smrg amdgpu_test_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_COMPUTE); 5239bd392adSmrg} 5249bd392adSmrgstatic void amdgpu_dispatch_hang_slow_gfx(void) 5259bd392adSmrg{ 526b0ab5608Smrg amdgpu_test_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_GFX); 5279bd392adSmrg} 5289bd392adSmrgstatic void amdgpu_dispatch_hang_slow_compute(void) 5299bd392adSmrg{ 530b0ab5608Smrg amdgpu_test_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_COMPUTE); 5319bd392adSmrg} 5329bd392adSmrgstatic void amdgpu_draw_hang_gfx(void) 5339bd392adSmrg{ 534b0ab5608Smrg amdgpu_test_draw_hang_helper(device_handle); 535b0ab5608Smrg} 536b0ab5608Smrgstatic void amdgpu_draw_hang_slow_gfx(void) 537b0ab5608Smrg{ 538b0ab5608Smrg amdgpu_test_draw_hang_slow_helper(device_handle); 539b0ab5608Smrg} 540b0ab5608Smrg 541b0ab5608Smrg#define DMA_CORRUPTED_HEADER_HANG 1 542b0ab5608Smrg#define DMA_SLOW_LINEARCOPY_HANG 2 543b0ab5608Smrg 544b0ab5608Smrgstatic void amdgpu_hang_sdma_helper(unsigned hang_type) 545b0ab5608Smrg{ 546b0ab5608Smrg const int sdma_write_length = 1024; 547b0ab5608Smrg amdgpu_context_handle context_handle; 548b0ab5608Smrg amdgpu_bo_handle ib_result_handle; 549b0ab5608Smrg amdgpu_bo_handle bo1, bo2; 550b0ab5608Smrg amdgpu_bo_handle resources[3]; 551b0ab5608Smrg amdgpu_bo_list_handle bo_list; 552b0ab5608Smrg void *ib_result_cpu; 553b0ab5608Smrg struct amdgpu_cs_ib_info ib_info; 554b0ab5608Smrg struct amdgpu_cs_request ibs_request; 555b0ab5608Smrg struct amdgpu_cs_fence fence_status; 556b0ab5608Smrg uint64_t bo1_mc, bo2_mc; 557b0ab5608Smrg uint64_t ib_result_mc_address; 558b0ab5608Smrg volatile unsigned char *bo1_cpu, *bo2_cpu; 559b0ab5608Smrg amdgpu_va_handle bo1_va_handle, bo2_va_handle; 560b0ab5608Smrg amdgpu_va_handle va_handle; 561b0ab5608Smrg struct drm_amdgpu_info_hw_ip hw_ip_info; 562b0ab5608Smrg int i, j, r; 563b0ab5608Smrg uint32_t expired, ib_size; 5649bd392adSmrg 565b0ab5608Smrg r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_DMA, 0, &hw_ip_info); 5669bd392adSmrg CU_ASSERT_EQUAL(r, 0); 5679bd392adSmrg 568b0ab5608Smrg r = amdgpu_cs_ctx_create(device_handle, &context_handle); 569b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 5700ed5401bSmrg 571b0ab5608Smrg if (hang_type == DMA_CORRUPTED_HEADER_HANG) 572b0ab5608Smrg ib_size = 4096; 573b0ab5608Smrg else 574b0ab5608Smrg ib_size = 4096 * 0x20000; 5759bd392adSmrg 576b0ab5608Smrg r = amdgpu_bo_alloc_and_map(device_handle, ib_size, 4096, 577b0ab5608Smrg AMDGPU_GEM_DOMAIN_GTT, 0, 578b0ab5608Smrg &ib_result_handle, &ib_result_cpu, 579b0ab5608Smrg &ib_result_mc_address, &va_handle); 580b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 5819bd392adSmrg 582b0ab5608Smrg r = amdgpu_bo_alloc_and_map(device_handle, 583b0ab5608Smrg sdma_write_length, 4096, 584b0ab5608Smrg AMDGPU_GEM_DOMAIN_GTT, 585b0ab5608Smrg 0, &bo1, 586b0ab5608Smrg (void**)&bo1_cpu, &bo1_mc, 587b0ab5608Smrg &bo1_va_handle); 5889bd392adSmrg CU_ASSERT_EQUAL(r, 0); 5899bd392adSmrg 590b0ab5608Smrg /* set bo1 */ 591b0ab5608Smrg memset((void*)bo1_cpu, 0xaa, sdma_write_length); 5920ed5401bSmrg 593b0ab5608Smrg /* allocate UC bo2 for sDMA use */ 594b0ab5608Smrg r = amdgpu_bo_alloc_and_map(device_handle, 595b0ab5608Smrg sdma_write_length, 4096, 596b0ab5608Smrg AMDGPU_GEM_DOMAIN_GTT, 597b0ab5608Smrg 0, &bo2, 598b0ab5608Smrg (void**)&bo2_cpu, &bo2_mc, 599b0ab5608Smrg &bo2_va_handle); 600b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 601b0ab5608Smrg 602b0ab5608Smrg /* clear bo2 */ 603b0ab5608Smrg memset((void*)bo2_cpu, 0, sdma_write_length); 604b0ab5608Smrg 605b0ab5608Smrg resources[0] = bo1; 606b0ab5608Smrg resources[1] = bo2; 607b0ab5608Smrg resources[2] = ib_result_handle; 608b0ab5608Smrg r = amdgpu_bo_list_create(device_handle, 3, 609b0ab5608Smrg resources, NULL, &bo_list); 610b0ab5608Smrg 611b0ab5608Smrg /* fulfill PM4: with bad copy linear header */ 612b0ab5608Smrg ptr = ib_result_cpu; 613b0ab5608Smrg i = 0; 614b0ab5608Smrg if (hang_type == DMA_CORRUPTED_HEADER_HANG) { 615b0ab5608Smrg ptr[i++] = 0x23decd3d; 616b0ab5608Smrg ptr[i++] = sdma_write_length - 1; 617b0ab5608Smrg ptr[i++] = 0; 618b0ab5608Smrg ptr[i++] = 0xffffffff & bo1_mc; 619b0ab5608Smrg ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32; 620b0ab5608Smrg ptr[i++] = 0xffffffff & bo2_mc; 621b0ab5608Smrg ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32; 622b0ab5608Smrg } else { 623b0ab5608Smrg for (j = 1; j < 0x20000; j++) { 624b0ab5608Smrg ptr[i++] = 0x1; 625b0ab5608Smrg ptr[i++] = sdma_write_length - 1; 626b0ab5608Smrg ptr[i++] = 0; 627b0ab5608Smrg ptr[i++] = 0xffffffff & bo1_mc; 628b0ab5608Smrg ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32; 629b0ab5608Smrg ptr[i++] = 0xffffffff & bo2_mc; 630b0ab5608Smrg ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32; 631b0ab5608Smrg ptr[i++] = 0x1; 632b0ab5608Smrg ptr[i++] = sdma_write_length - 1; 633b0ab5608Smrg ptr[i++] = 0; 634b0ab5608Smrg ptr[i++] = 0xffffffff & bo2_mc; 635b0ab5608Smrg ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32; 636b0ab5608Smrg ptr[i++] = 0xffffffff & bo1_mc; 637b0ab5608Smrg ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32; 638b0ab5608Smrg } 6399bd392adSmrg } 640b0ab5608Smrg 641b0ab5608Smrg /* exec command */ 642b0ab5608Smrg memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info)); 643b0ab5608Smrg ib_info.ib_mc_address = ib_result_mc_address; 644b0ab5608Smrg ib_info.size = i; 645b0ab5608Smrg 646b0ab5608Smrg memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request)); 647b0ab5608Smrg ibs_request.ip_type = AMDGPU_HW_IP_DMA; 648b0ab5608Smrg ibs_request.ring = 0; 649b0ab5608Smrg ibs_request.number_of_ibs = 1; 650b0ab5608Smrg ibs_request.ibs = &ib_info; 651b0ab5608Smrg ibs_request.resources = bo_list; 652b0ab5608Smrg ibs_request.fence_info.handle = NULL; 653b0ab5608Smrg 654b0ab5608Smrg r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); 655b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 656b0ab5608Smrg 657b0ab5608Smrg memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence)); 658b0ab5608Smrg fence_status.context = context_handle; 659b0ab5608Smrg fence_status.ip_type = AMDGPU_HW_IP_DMA; 660b0ab5608Smrg fence_status.ip_instance = 0; 661b0ab5608Smrg fence_status.ring = 0; 662b0ab5608Smrg fence_status.fence = ibs_request.seq_no; 663b0ab5608Smrg 664b0ab5608Smrg r = amdgpu_cs_query_fence_status(&fence_status, 665b0ab5608Smrg AMDGPU_TIMEOUT_INFINITE, 666b0ab5608Smrg 0, &expired); 667b0ab5608Smrg CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); 668b0ab5608Smrg 669b0ab5608Smrg r = amdgpu_bo_list_destroy(bo_list); 670b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 671b0ab5608Smrg 672b0ab5608Smrg r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle, 673b0ab5608Smrg ib_result_mc_address, 4096); 674b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 675b0ab5608Smrg 676b0ab5608Smrg r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc, 677b0ab5608Smrg sdma_write_length); 678b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 679b0ab5608Smrg 680b0ab5608Smrg r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc, 681b0ab5608Smrg sdma_write_length); 682b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 683b0ab5608Smrg 684b0ab5608Smrg /* end of test */ 685b0ab5608Smrg r = amdgpu_cs_ctx_free(context_handle); 686b0ab5608Smrg CU_ASSERT_EQUAL(r, 0); 687b0ab5608Smrg} 688b0ab5608Smrg 689b0ab5608Smrgstatic void amdgpu_hang_sdma(void) 690b0ab5608Smrg{ 691b0ab5608Smrg amdgpu_hang_sdma_helper(DMA_CORRUPTED_HEADER_HANG); 692b0ab5608Smrg} 693b0ab5608Smrgstatic void amdgpu_hang_slow_sdma(void) 694b0ab5608Smrg{ 695b0ab5608Smrg amdgpu_hang_sdma_helper(DMA_SLOW_LINEARCOPY_HANG); 6969bd392adSmrg} 697