[PATCH libdrm] amdgpu: Add explicit dependency test.

Christian König ckoenig.leichtzumerken at gmail.com
Thu Nov 30 13:06:00 UTC 2017


Am 28.11.2017 um 16:32 schrieb Andrey Grodzovsky:
> The test is as following:
>
> 1) Create context A & B
> 2) Send a command submission using context A which fires up a compute shader.
> 3) The shader wait a bit and then write a value to a memory location.
> 4) Send a command submission using context B which writes another value to the same memory location, but having an explicit dependency on the first command submission.
> 5) Wait with the CPU for both submissions to finish and inspect the written value.
>
> Test passes if the value seen in the memory location after both submissions is from command B.
>
> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky at amd.com>

Would probably be nice to add this to the deadlock.c tests instead of 
the basic_tests.c, but I think that won't work because of the PM4 
defines needed.

Anyway patch is Acked-by: Christian König <christian.koenig at amd.com>

Regards,
Christian.

> ---
>   tests/amdgpu/amdgpu_test.c |  18 ++++
>   tests/amdgpu/basic_tests.c | 264 +++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 282 insertions(+)
>
> diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
> index 50da17c..8fa3399 100644
> --- a/tests/amdgpu/amdgpu_test.c
> +++ b/tests/amdgpu/amdgpu_test.c
> @@ -49,6 +49,7 @@
>   #include "CUnit/Basic.h"
>   
>   #include "amdgpu_test.h"
> +#include "amdgpu_internal.h"
>   
>   /* Test suit names */
>   #define BASIC_TESTS_STR "Basic Tests"
> @@ -401,9 +402,20 @@ static int amdgpu_find_device(uint8_t bus, uint16_t dev)
>   
>   static void amdgpu_disable_suits()
>   {
> +	amdgpu_device_handle device_handle;
> +	uint32_t major_version, minor_version, family_id;
>   	int i;
>   	int size = sizeof(suites_active_stat) / sizeof(suites_active_stat[0]);
>   
> +	if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
> +				   &minor_version, &device_handle))
> +		return;
> +
> +	family_id = device_handle->info.family_id;
> +
> +	if (amdgpu_device_deinitialize(device_handle))
> +		return;
> +
>   	/* Set active status for suits based on their policies */
>   	for (i = 0; i < size; ++i)
>   		if (amdgpu_set_suite_active(suites_active_stat[i].pName,
> @@ -420,6 +432,12 @@ static void amdgpu_disable_suits()
>   
>   	if (amdgpu_set_test_active(BO_TESTS_STR, "Metadata", CU_FALSE))
>   		fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
> +
> +
> +	/* This test was ran on GFX8 and GFX9 only */
> +	if (family_id < AMDGPU_FAMILY_VI || family_id > AMDGPU_FAMILY_RV)
> +		if (amdgpu_set_test_active(BASIC_TESTS_STR, "Sync dependency Test", CU_FALSE))
> +			fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
>   }
>   
>   /* The main() function for setting up and running the tests.
> diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c
> index e7f48e3..a78cf52 100644
> --- a/tests/amdgpu/basic_tests.c
> +++ b/tests/amdgpu/basic_tests.c
> @@ -50,6 +50,7 @@ static void amdgpu_command_submission_multi_fence(void);
>   static void amdgpu_command_submission_sdma(void);
>   static void amdgpu_userptr_test(void);
>   static void amdgpu_semaphore_test(void);
> +static void amdgpu_sync_dependency_test(void);
>   
>   static void amdgpu_command_submission_write_linear_helper(unsigned ip_type);
>   static void amdgpu_command_submission_const_fill_helper(unsigned ip_type);
> @@ -63,6 +64,7 @@ CU_TestInfo basic_tests[] = {
>   	{ "Command submission Test (Multi-Fence)", amdgpu_command_submission_multi_fence },
>   	{ "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
>   	{ "SW semaphore Test",  amdgpu_semaphore_test },
> +	{ "Sync dependency Test",  amdgpu_sync_dependency_test },
>   	CU_TEST_INFO_NULL,
>   };
>   #define BUFFER_SIZE (8 * 1024)
> @@ -226,6 +228,60 @@ CU_TestInfo basic_tests[] = {
>   		 */
>   #              define PACKET3_DMA_DATA_SI_CP_SYNC     (1 << 31)
>   
> +
> +#define PKT3_CONTEXT_CONTROL                   0x28
> +#define     CONTEXT_CONTROL_LOAD_ENABLE(x)     (((unsigned)(x) & 0x1) << 31)
> +#define     CONTEXT_CONTROL_LOAD_CE_RAM(x)     (((unsigned)(x) & 0x1) << 28)
> +#define     CONTEXT_CONTROL_SHADOW_ENABLE(x)   (((unsigned)(x) & 0x1) << 31)
> +
> +#define PKT3_CLEAR_STATE                       0x12
> +
> +#define PKT3_SET_SH_REG                        0x76
> +#define		PACKET3_SET_SH_REG_START			0x00002c00
> +
> +#define	PACKET3_DISPATCH_DIRECT				0x15
> +
> +
> +/* gfx 8 */
> +#define mmCOMPUTE_PGM_LO                                                        0x2e0c
> +#define mmCOMPUTE_PGM_RSRC1                                                     0x2e12
> +#define mmCOMPUTE_TMPRING_SIZE                                                  0x2e18
> +#define mmCOMPUTE_USER_DATA_0                                                   0x2e40
> +#define mmCOMPUTE_USER_DATA_1                                                   0x2e41
> +#define mmCOMPUTE_RESOURCE_LIMITS                                               0x2e15
> +#define mmCOMPUTE_NUM_THREAD_X                                                  0x2e07
> +
> +
> +
> +#define SWAP_32(num) ((num>>24)&0xff) | \
> +			((num<<8)&0xff0000) | \
> +			((num>>8)&0xff00) | \
> +			((num<<24)&0xff000000)
> +
> +
> +/* Shader code
> + * void main()
> +{
> +
> +	float x = some_input;
> +		for (unsigned i = 0; i < 1000000; i++)
> +  	x = sin(x);
> +
> +	u[0] = 42u;
> +}
> +*/
> +
> +static  uint32_t shader_bin[] = {
> +	SWAP_32(0x800082be), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0x040085bf),
> +	SWAP_32(0x02810281), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0xfcff84bf),
> +	SWAP_32(0xff0083be), SWAP_32(0x00f00000), SWAP_32(0xc10082be), SWAP_32(0xaa02007e),
> +	SWAP_32(0x000070e0), SWAP_32(0x00000080), SWAP_32(0x000081bf)
> +};
> +
> +#define CODE_OFFSET 512
> +#define DATA_OFFSET 1024
> +
> +
>   int suite_basic_tests_init(void)
>   {
>   	struct amdgpu_gpu_info gpu_info = {0};
> @@ -1386,3 +1442,211 @@ static void amdgpu_userptr_test(void)
>   
>   	wait(NULL);
>   }
> +
> +static void amdgpu_sync_dependency_test(void)
> +{
> +	amdgpu_context_handle context_handle[2];
> +	amdgpu_bo_handle ib_result_handle;
> +	void *ib_result_cpu;
> +	uint64_t ib_result_mc_address;
> +	struct amdgpu_cs_request ibs_request;
> +	struct amdgpu_cs_ib_info ib_info;
> +	struct amdgpu_cs_fence fence_status;
> +	uint32_t expired;
> +	int i, j, r, instance;
> +	amdgpu_bo_list_handle bo_list;
> +	amdgpu_va_handle va_handle;
> +	static uint32_t *ptr;
> +	uint64_t seq_no;
> +
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	r = amdgpu_cs_ctx_create(device_handle, &context_handle[0]);
> +	CU_ASSERT_EQUAL(r, 0);
> +	r = amdgpu_cs_ctx_create(device_handle, &context_handle[1]);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	r = amdgpu_bo_alloc_and_map(device_handle, 8192, 4096,
> +			AMDGPU_GEM_DOMAIN_GTT, 0,
> +						    &ib_result_handle, &ib_result_cpu,
> +						    &ib_result_mc_address, &va_handle);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
> +			       &bo_list);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	ptr = ib_result_cpu;
> +	i = 0;
> +
> +	memcpy(ptr + CODE_OFFSET , shader_bin, sizeof(shader_bin));
> +
> +	/* Dispatch minimal init config and verify it's executed */
> +	ptr[i++] = PACKET3(PKT3_CONTEXT_CONTROL, 1);
> +	ptr[i++] = 0x80000000;
> +	ptr[i++] = 0x80000000;
> +
> +	ptr[i++] = PACKET3(PKT3_CLEAR_STATE, 0);
> +	ptr[i++] = 0x80000000;
> +
> +
> +	/* Program compute regs */
> +	ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
> +	ptr[i++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START;
> +	ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 8;
> +	ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 40;
> +
> +
> +	ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
> +	ptr[i++] = mmCOMPUTE_PGM_RSRC1 - PACKET3_SET_SH_REG_START;
> +	/*
> +	 * 002c0040         COMPUTE_PGM_RSRC1 <- VGPRS = 0
> +	                                      SGPRS = 1
> +	                                      PRIORITY = 0
> +	                                      FLOAT_MODE = 192 (0xc0)
> +	                                      PRIV = 0
> +	                                      DX10_CLAMP = 1
> +	                                      DEBUG_MODE = 0
> +	                                      IEEE_MODE = 0
> +	                                      BULKY = 0
> +	                                      CDBG_USER = 0
> +	 *
> +	 */
> +	ptr[i++] = 0x002c0040;
> +
> +
> +	/*
> +	 * 00000010         COMPUTE_PGM_RSRC2 <- SCRATCH_EN = 0
> +	                                      USER_SGPR = 8
> +	                                      TRAP_PRESENT = 0
> +	                                      TGID_X_EN = 0
> +	                                      TGID_Y_EN = 0
> +	                                      TGID_Z_EN = 0
> +	                                      TG_SIZE_EN = 0
> +	                                      TIDIG_COMP_CNT = 0
> +	                                      EXCP_EN_MSB = 0
> +	                                      LDS_SIZE = 0
> +	                                      EXCP_EN = 0
> +	 *
> +	 */
> +	ptr[i++] = 0x00000010;
> +
> +
> +/*
> + * 00000100         COMPUTE_TMPRING_SIZE <- WAVES = 256 (0x100)
> +                                         WAVESIZE = 0
> + *
> + */
> +	ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
> +	ptr[i++] = mmCOMPUTE_TMPRING_SIZE - PACKET3_SET_SH_REG_START;
> +	ptr[i++] = 0x00000100;
> +
> +	ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
> +	ptr[i++] = mmCOMPUTE_USER_DATA_0 - PACKET3_SET_SH_REG_START;
> +	ptr[i++] = 0xffffffff & (ib_result_mc_address + DATA_OFFSET * 4);
> +	ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
> +
> +	ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
> +	ptr[i++] = mmCOMPUTE_RESOURCE_LIMITS - PACKET3_SET_SH_REG_START;
> +	ptr[i++] = 0;
> +
> +	ptr[i++] = PACKET3(PKT3_SET_SH_REG, 3);
> +	ptr[i++] = mmCOMPUTE_NUM_THREAD_X - PACKET3_SET_SH_REG_START;
> +	ptr[i++] = 1;
> +	ptr[i++] = 1;
> +	ptr[i++] = 1;
> +
> +
> +	/* Dispatch */
> +	ptr[i++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
> +	ptr[i++] = 1;
> +	ptr[i++] = 1;
> +	ptr[i++] = 1;
> +	ptr[i++] = 0x00000045; /* DISPATCH DIRECT field */
> +
> +
> +	while (i & 7)
> +		ptr[i++] =  0xffff1000; /* type3 nop packet */
> +
> +	memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
> +	ib_info.ib_mc_address = ib_result_mc_address;
> +	ib_info.size = i;
> +
> +	memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
> +	ibs_request.ip_type = AMDGPU_HW_IP_GFX;
> +	ibs_request.ring = 0;
> +	ibs_request.number_of_ibs = 1;
> +	ibs_request.ibs = &ib_info;
> +	ibs_request.resources = bo_list;
> +	ibs_request.fence_info.handle = NULL;
> +
> +	r = amdgpu_cs_submit(context_handle[1], 0,&ibs_request, 1);
> +	CU_ASSERT_EQUAL(r, 0);
> +	seq_no = ibs_request.seq_no;
> +
> +
> +
> +	/* Prepare second command with dependency on the first */
> +	j = i;
> +	ptr[i++] = PACKET3(PACKET3_WRITE_DATA, 3);
> +	ptr[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
> +	ptr[i++] = 0xfffffffc & ib_result_mc_address + DATA_OFFSET * 4;
> +	ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
> +	ptr[i++] = 99;
> +
> +	while (i & 7)
> +		ptr[i++] =  0xffff1000; /* type3 nop packet */
> +
> +	memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
> +	ib_info.ib_mc_address = ib_result_mc_address + j * 4;
> +	ib_info.size = i - j;
> +
> +	memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
> +	ibs_request.ip_type = AMDGPU_HW_IP_GFX;
> +	ibs_request.ring = 0;
> +	ibs_request.number_of_ibs = 1;
> +	ibs_request.ibs = &ib_info;
> +	ibs_request.resources = bo_list;
> +	ibs_request.fence_info.handle = NULL;
> +
> +	ibs_request.number_of_dependencies = 1;
> +
> +	ibs_request.dependencies = calloc(1, sizeof(*ibs_request.dependencies));
> +	ibs_request.dependencies[0].context = context_handle[1];
> +	ibs_request.dependencies[0].ip_instance = 0;
> +	ibs_request.dependencies[0].ring = 0;
> +	ibs_request.dependencies[0].fence = seq_no;
> +
> +
> +	r = amdgpu_cs_submit(context_handle[0], 0,&ibs_request, 1);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +
> +	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
> +	fence_status.context = context_handle[0];
> +	fence_status.ip_type = AMDGPU_HW_IP_GFX;
> +	fence_status.ip_instance = 0;
> +	fence_status.ring = 0;
> +	fence_status.fence = ibs_request.seq_no;
> +
> +	r = amdgpu_cs_query_fence_status(&fence_status,
> +		       AMDGPU_TIMEOUT_INFINITE,0, &expired);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	/* Expect the second command to wait for shader to complete */
> +	CU_ASSERT_EQUAL(ptr[DATA_OFFSET], 99);
> +
> +	r = amdgpu_bo_list_destroy(bo_list);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
> +				     ib_result_mc_address, 4096);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	r = amdgpu_cs_ctx_free(context_handle[0]);
> +	CU_ASSERT_EQUAL(r, 0);
> +	r = amdgpu_cs_ctx_free(context_handle[1]);
> +	CU_ASSERT_EQUAL(r, 0);
> +
> +	free(ibs_request.dependencies);
> +}



More information about the amd-gfx mailing list