Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-15  2:12 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
@ 2023-06-15  2:12 ` vitaly.prosyak
  0 siblings, 0 replies; 12+ messages in thread
From: vitaly.prosyak @ 2023-06-15  2:12 UTC (permalink / raw)
  To: igt-dev; +Cc: alexander.deucher, michael.strawbridge, christian.koenig

From: Vitaly Prosyak <vitaly.prosyak@amd.com>

Using worker thread to wait on point and then signal point on other thread.
Another test uses a worker thread to signal point and wait on the main
thread using amdgpu_cs_syncobj_timeline_wait.

The command consists of two chunks :
1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
   or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
   point number .

v1->v2. Fixed style issues - Christian.
        Fixed formatting issues - Kamil.

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by Christian Koenig <christian.koenig@amd.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Change-Id: I766a36d4e9a416784960f0100683ce014f8bfa14
---
 tests/amdgpu/amd_syncobj.c | 266 +++++++++++++++++++++++++++++++++++++
 tests/amdgpu/meson.build   |   1 +
 2 files changed, 267 insertions(+)
 create mode 100644 tests/amdgpu/amd_syncobj.c

diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
new file mode 100644
index 000000000..df22eeee3
--- /dev/null
+++ b/tests/amdgpu/amd_syncobj.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: MIT
+
+#include <pthread.h>
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+
+#include "igt.h"
+#include "lib/amdgpu/amd_PM4.h"
+#include "lib/amdgpu/amd_sdma.h"
+#include "lib/amdgpu/amd_memory.h"
+
+struct syncobj_point {
+	amdgpu_device_handle device;
+	uint32_t syncobj_handle;
+	uint64_t point;
+};
+
+
+static bool
+syncobj_timeline_enable(int fd)
+{
+	int r;
+	bool ret = false;
+	uint64_t cap = 0;
+
+	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+	if (r || cap == 0)
+		return ret;
+	ret = true;
+
+	return ret;
+}
+
+static void
+syncobj_command_submission_helper(amdgpu_device_handle device_handle,
+		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
+{
+	amdgpu_context_handle context_handle;
+	amdgpu_bo_handle ib_result_handle;
+	void *ib_result_cpu;
+	uint64_t ib_result_mc_address;
+	struct drm_amdgpu_cs_chunk chunks[2];
+	struct drm_amdgpu_cs_chunk_data chunk_data;
+	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
+	struct amdgpu_cs_fence fence_status;
+	amdgpu_bo_list_handle bo_list;
+	amdgpu_va_handle va_handle;
+	uint32_t expired;
+	int i, r;
+	uint64_t seq_no;
+	uint32_t *ptr;
+
+	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+				    AMDGPU_GEM_DOMAIN_GTT, 0,
+				    &ib_result_handle, &ib_result_cpu,
+				    &ib_result_mc_address, &va_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
+	igt_assert_eq(r, 0);
+
+	ptr = ib_result_cpu;
+
+	for (i = 0; i < 16; ++i)
+		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
+
+	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
+	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
+	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
+	chunk_data.ib_data._pad = 0;
+	chunk_data.ib_data.va_start = ib_result_mc_address;
+	chunk_data.ib_data.ib_bytes = 16 * 4;
+	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	chunk_data.ib_data.ip_instance = 0;
+	chunk_data.ib_data.ring = 0;
+	chunk_data.ib_data.flags = 0;
+
+	chunks[1].chunk_id = wait_or_signal ?
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
+	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
+	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
+	syncobj_data.handle = syncobj_handle;
+	syncobj_data.point = point;
+	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+	r = amdgpu_cs_submit_raw(device_handle,
+				 context_handle,
+				 bo_list,
+				 2,
+				 chunks,
+				 &seq_no);
+	igt_assert_eq(r, 0);
+
+	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+	fence_status.context = context_handle;
+	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	fence_status.ip_instance = 0;
+	fence_status.ring = 0;
+	fence_status.fence = seq_no;
+
+	r = amdgpu_cs_query_fence_status(&fence_status,
+			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_list_destroy(bo_list);
+	igt_assert_eq(r, 0);
+
+	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+				     ib_result_mc_address, 4096);
+
+	r = amdgpu_cs_ctx_free(context_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void *
+syncobj_wait(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+	int r;
+
+	r = syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
+					      sp->point);
+	igt_assert_eq(r, 0);
+
+	return (void *)(long)r;
+}
+
+static void *
+syncobj_signal(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+	int r;
+
+	r = syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
+			sp->point);
+	igt_assert_eq(r, 0);
+
+	return (void *)(long)r;
+}
+
+static void
+amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
+{
+	static pthread_t wait_thread;
+	static pthread_t signal_thread;
+	static pthread_t c_thread;
+	struct syncobj_point sp1, sp2, sp3;
+	uint32_t syncobj_handle;
+	uint64_t payload;
+	uint64_t wait_point, signal_point;
+	uint64_t timeout;
+	struct timespec tp;
+	int r, sync_fd;
+	void *tmp, *tmp2;
+
+	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
+	igt_assert_eq(r, 0);
+
+	// wait on point 5
+	sp1.syncobj_handle = syncobj_handle;
+	sp1.device = device_handle;
+	sp1.point = 5;
+	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
+	igt_assert_eq(r, 0);
+
+	// signal on point 10
+	sp2.syncobj_handle = syncobj_handle;
+	sp2.device = device_handle;
+	sp2.point = 10;
+	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(signal_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(wait_thread, &tmp2);
+	igt_assert_eq(r, 0);
+
+	//query timeline payload
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 10);
+
+	//signal on point 16
+	sp3.syncobj_handle = syncobj_handle;
+	sp3.device = device_handle;
+	sp3.point = 16;
+	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
+	igt_assert_eq(r, 0);
+
+	//CPU wait on point 16
+	wait_point = 16;
+	timeout = 0;
+	clock_gettime(CLOCK_MONOTONIC, &tp);
+	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+	timeout += 10000000000; //10s
+	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
+					    &wait_point, 1, timeout,
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+					    NULL);
+
+	igt_assert_eq(r, 0);
+	r = pthread_join(c_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	// export point 16 and import to point 18
+	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
+						16,
+						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+						&sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
+						18, sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 18);
+
+	// CPU signal on point 20
+	signal_point = 20;
+	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
+					      &signal_point, 1);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 20);
+
+	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
+	igt_assert_eq(r, 0);
+
+}
+
+igt_main
+{
+	amdgpu_device_handle device;
+	int fd = -1;
+
+	igt_fixture {
+		uint32_t major, minor;
+		int err;
+
+		fd = drm_open_driver(DRIVER_AMDGPU);
+		err = amdgpu_device_initialize(fd, &major, &minor, &device);
+		igt_require(err == 0);
+		igt_require(syncobj_timeline_enable(fd));
+		igt_info("Initialized amdgpu, driver version %d.%d\n",
+			 major, minor);
+
+	}
+
+	igt_subtest("amdgpu_syncobj_timeline")
+	amdgpu_syncobj_timeline(device);
+
+	igt_fixture {
+		amdgpu_device_deinitialize(device);
+		close(fd);
+	}
+}
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 43326a7c4..576d242c5 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
 			  'amd_assr',
 			  'amd_basic',
 			  'amd_bo',
+			  'amd_syncobj',
 			  'amd_bypass',
 			  'amd_deadlock',
 			  'amd_pci_unplug',
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-15  2:14 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
@ 2023-06-15  2:14 ` vitaly.prosyak
  0 siblings, 0 replies; 12+ messages in thread
From: vitaly.prosyak @ 2023-06-15  2:14 UTC (permalink / raw)
  To: igt-dev; +Cc: alexander.deucher, michael.strawbridge, christian.koenig

From: Vitaly Prosyak <vitaly.prosyak@amd.com>

Using worker thread to wait on point and then signal point on other thread.
Another test uses a worker thread to signal point and wait on the main
thread using amdgpu_cs_syncobj_timeline_wait.

The command consists of two chunks :
1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
   or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
   point number .

v1->v2. Fixed style issues - Christian.
        Fixed formatting issues - Kamil.

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by Christian Koenig <christian.koenig@amd.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
---
 tests/amdgpu/amd_syncobj.c | 266 +++++++++++++++++++++++++++++++++++++
 tests/amdgpu/meson.build   |   1 +
 2 files changed, 267 insertions(+)
 create mode 100644 tests/amdgpu/amd_syncobj.c

diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
new file mode 100644
index 000000000..df22eeee3
--- /dev/null
+++ b/tests/amdgpu/amd_syncobj.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: MIT
+
+#include <pthread.h>
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+
+#include "igt.h"
+#include "lib/amdgpu/amd_PM4.h"
+#include "lib/amdgpu/amd_sdma.h"
+#include "lib/amdgpu/amd_memory.h"
+
+struct syncobj_point {
+	amdgpu_device_handle device;
+	uint32_t syncobj_handle;
+	uint64_t point;
+};
+
+
+static bool
+syncobj_timeline_enable(int fd)
+{
+	int r;
+	bool ret = false;
+	uint64_t cap = 0;
+
+	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+	if (r || cap == 0)
+		return ret;
+	ret = true;
+
+	return ret;
+}
+
+static void
+syncobj_command_submission_helper(amdgpu_device_handle device_handle,
+		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
+{
+	amdgpu_context_handle context_handle;
+	amdgpu_bo_handle ib_result_handle;
+	void *ib_result_cpu;
+	uint64_t ib_result_mc_address;
+	struct drm_amdgpu_cs_chunk chunks[2];
+	struct drm_amdgpu_cs_chunk_data chunk_data;
+	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
+	struct amdgpu_cs_fence fence_status;
+	amdgpu_bo_list_handle bo_list;
+	amdgpu_va_handle va_handle;
+	uint32_t expired;
+	int i, r;
+	uint64_t seq_no;
+	uint32_t *ptr;
+
+	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+				    AMDGPU_GEM_DOMAIN_GTT, 0,
+				    &ib_result_handle, &ib_result_cpu,
+				    &ib_result_mc_address, &va_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
+	igt_assert_eq(r, 0);
+
+	ptr = ib_result_cpu;
+
+	for (i = 0; i < 16; ++i)
+		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
+
+	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
+	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
+	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
+	chunk_data.ib_data._pad = 0;
+	chunk_data.ib_data.va_start = ib_result_mc_address;
+	chunk_data.ib_data.ib_bytes = 16 * 4;
+	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	chunk_data.ib_data.ip_instance = 0;
+	chunk_data.ib_data.ring = 0;
+	chunk_data.ib_data.flags = 0;
+
+	chunks[1].chunk_id = wait_or_signal ?
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
+	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
+	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
+	syncobj_data.handle = syncobj_handle;
+	syncobj_data.point = point;
+	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+	r = amdgpu_cs_submit_raw(device_handle,
+				 context_handle,
+				 bo_list,
+				 2,
+				 chunks,
+				 &seq_no);
+	igt_assert_eq(r, 0);
+
+	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+	fence_status.context = context_handle;
+	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	fence_status.ip_instance = 0;
+	fence_status.ring = 0;
+	fence_status.fence = seq_no;
+
+	r = amdgpu_cs_query_fence_status(&fence_status,
+			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_list_destroy(bo_list);
+	igt_assert_eq(r, 0);
+
+	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+				     ib_result_mc_address, 4096);
+
+	r = amdgpu_cs_ctx_free(context_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void *
+syncobj_wait(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+	int r;
+
+	r = syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
+					      sp->point);
+	igt_assert_eq(r, 0);
+
+	return (void *)(long)r;
+}
+
+static void *
+syncobj_signal(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+	int r;
+
+	r = syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
+			sp->point);
+	igt_assert_eq(r, 0);
+
+	return (void *)(long)r;
+}
+
+static void
+amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
+{
+	static pthread_t wait_thread;
+	static pthread_t signal_thread;
+	static pthread_t c_thread;
+	struct syncobj_point sp1, sp2, sp3;
+	uint32_t syncobj_handle;
+	uint64_t payload;
+	uint64_t wait_point, signal_point;
+	uint64_t timeout;
+	struct timespec tp;
+	int r, sync_fd;
+	void *tmp, *tmp2;
+
+	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
+	igt_assert_eq(r, 0);
+
+	// wait on point 5
+	sp1.syncobj_handle = syncobj_handle;
+	sp1.device = device_handle;
+	sp1.point = 5;
+	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
+	igt_assert_eq(r, 0);
+
+	// signal on point 10
+	sp2.syncobj_handle = syncobj_handle;
+	sp2.device = device_handle;
+	sp2.point = 10;
+	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(signal_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(wait_thread, &tmp2);
+	igt_assert_eq(r, 0);
+
+	//query timeline payload
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 10);
+
+	//signal on point 16
+	sp3.syncobj_handle = syncobj_handle;
+	sp3.device = device_handle;
+	sp3.point = 16;
+	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
+	igt_assert_eq(r, 0);
+
+	//CPU wait on point 16
+	wait_point = 16;
+	timeout = 0;
+	clock_gettime(CLOCK_MONOTONIC, &tp);
+	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+	timeout += 10000000000; //10s
+	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
+					    &wait_point, 1, timeout,
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+					    NULL);
+
+	igt_assert_eq(r, 0);
+	r = pthread_join(c_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	// export point 16 and import to point 18
+	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
+						16,
+						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+						&sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
+						18, sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 18);
+
+	// CPU signal on point 20
+	signal_point = 20;
+	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
+					      &signal_point, 1);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 20);
+
+	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
+	igt_assert_eq(r, 0);
+
+}
+
+igt_main
+{
+	amdgpu_device_handle device;
+	int fd = -1;
+
+	igt_fixture {
+		uint32_t major, minor;
+		int err;
+
+		fd = drm_open_driver(DRIVER_AMDGPU);
+		err = amdgpu_device_initialize(fd, &major, &minor, &device);
+		igt_require(err == 0);
+		igt_require(syncobj_timeline_enable(fd));
+		igt_info("Initialized amdgpu, driver version %d.%d\n",
+			 major, minor);
+
+	}
+
+	igt_subtest("amdgpu_syncobj_timeline")
+	amdgpu_syncobj_timeline(device);
+
+	igt_fixture {
+		amdgpu_device_deinitialize(device);
+		close(fd);
+	}
+}
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 43326a7c4..576d242c5 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
 			  'amd_assr',
 			  'amd_basic',
 			  'amd_bo',
+			  'amd_syncobj',
 			  'amd_bypass',
 			  'amd_deadlock',
 			  'amd_pci_unplug',
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests
@ 2023-06-15 22:39 vitaly.prosyak
  2023-06-15 22:39 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: vitaly.prosyak @ 2023-06-15 22:39 UTC (permalink / raw)
  To: igt-dev; +Cc: alexander.deucher, michael.strawbridge, christian.koenig

From: Vitaly Prosyak <vitaly.prosyak@amd.com>

The tests do the validation the following bo features:
 - export/import
 - write/read metadata and then compare with original
 - map/unmap
 - alloc/free
 - find bo mapping

v1-v2 Fix formatting errors, drop debug (it was added by mistake)
      and fix return code - Kamil

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by Kamil Konieczny <kamil.konieczny@linux.intel.com>
---
 tests/amdgpu/amd_bo.c    | 292 +++++++++++++++++++++++++++++++++++++++
 tests/amdgpu/meson.build |   1 +
 2 files changed, 293 insertions(+)
 create mode 100644 tests/amdgpu/amd_bo.c

diff --git a/tests/amdgpu/amd_bo.c b/tests/amdgpu/amd_bo.c
new file mode 100644
index 000000000..01af2ba93
--- /dev/null
+++ b/tests/amdgpu/amd_bo.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: MIT
+// Copyright 2023 Advanced Micro Devices, Inc.
+
+#include <stdio.h>
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+
+#include "igt.h"
+#include "lib/amdgpu/amd_memory.h"
+
+
+#define BUFFER_SIZE (4*1024)
+#define BUFFER_ALIGN (4*1024)
+
+struct bo_data {
+	amdgpu_bo_handle buffer_handle;
+	uint64_t virtual_mc_base_address;
+	amdgpu_va_handle va_handle;
+};
+
+static int
+amdgpu_bo_init(amdgpu_device_handle device_handle, struct bo_data *bo)
+{
+	struct amdgpu_bo_alloc_request req = {0};
+	int r;
+
+	req.alloc_size = BUFFER_SIZE;
+	req.phys_alignment = BUFFER_ALIGN;
+	req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
+
+	r = amdgpu_bo_alloc(device_handle, &req, &bo->buffer_handle);
+	if (r)
+		return r;
+
+	r = amdgpu_va_range_alloc(device_handle,
+				  amdgpu_gpu_va_range_general,
+				  BUFFER_SIZE, BUFFER_ALIGN, 0,
+				  &bo->virtual_mc_base_address, &bo->va_handle, 0);
+	if (r)
+		goto error_va_alloc;
+
+	r = amdgpu_bo_va_op(bo->buffer_handle, 0, BUFFER_SIZE,
+			bo->virtual_mc_base_address, 0, AMDGPU_VA_OP_MAP);
+	if (r)
+		goto error_va_map;
+
+	return r;
+
+error_va_map:
+	amdgpu_va_range_free(bo->va_handle);
+
+error_va_alloc:
+	amdgpu_bo_free(bo->buffer_handle);
+	return r;
+}
+
+static void
+amdgpu_bo_clean(amdgpu_device_handle device_handle, struct bo_data *bo)
+{
+	int r;
+
+	r = amdgpu_bo_va_op(bo->buffer_handle, 0, BUFFER_SIZE,
+			    bo->virtual_mc_base_address, 0,
+			    AMDGPU_VA_OP_UNMAP);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_va_range_free(bo->va_handle);
+	igt_assert_eq(r, 0);
+	r = amdgpu_bo_free(bo->buffer_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void
+amdgpu_bo_export_import_do_type(amdgpu_device_handle device_handle,
+		struct bo_data *bo, enum amdgpu_bo_handle_type type)
+{
+	struct amdgpu_bo_import_result res = {0};
+	uint32_t shared_handle;
+	int r;
+
+	r = amdgpu_bo_export(bo->buffer_handle, type, &shared_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_import(device_handle, type, shared_handle, &res);
+	igt_assert_eq(r, 0);
+
+	igt_assert(res.buf_handle == bo->buffer_handle);
+	igt_assert_eq(res.alloc_size, BUFFER_SIZE);
+
+	r = amdgpu_bo_free(res.buf_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void
+amdgpu_bo_export_import(amdgpu_device_handle device, struct bo_data *bo)
+{
+	amdgpu_bo_export_import_do_type(device, bo,
+			amdgpu_bo_handle_type_gem_flink_name);
+	amdgpu_bo_export_import_do_type(device, bo,
+			amdgpu_bo_handle_type_dma_buf_fd);
+}
+
+static void
+amdgpu_bo_metadata(amdgpu_device_handle device, struct bo_data *bo)
+{
+	struct amdgpu_bo_metadata meta = {0};
+	struct amdgpu_bo_info info = {0};
+	int r;
+
+	meta.size_metadata = 4;
+	meta.umd_metadata[0] = 0xdeadbeef;
+
+	r = amdgpu_bo_set_metadata(bo->buffer_handle, &meta);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_query_info(bo->buffer_handle, &info);
+	igt_assert_eq(r, 0);
+
+	igt_assert_eq(info.metadata.size_metadata, 4);
+	igt_assert_eq(info.metadata.umd_metadata[0], 0xdeadbeef);
+}
+
+static void
+amdgpu_bo_map_unmap(amdgpu_device_handle device, struct bo_data *bo)
+{
+	uint32_t *ptr;
+	int i, r;
+
+	r = amdgpu_bo_cpu_map(bo->buffer_handle, (void **)&ptr);
+	igt_assert_eq(r, 0);
+
+	for (i = 0; i < (BUFFER_SIZE / 4); ++i)
+		ptr[i] = 0xdeadbeef;
+
+	r = amdgpu_bo_cpu_unmap(bo->buffer_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void
+amdgpu_memory_alloc(amdgpu_device_handle device_handle)
+{
+	amdgpu_bo_handle bo;
+	amdgpu_va_handle va_handle;
+	uint64_t bo_mc;
+
+	/* Test visible VRAM */
+	bo = gpu_mem_alloc(device_handle,
+			4096, 4096,
+			AMDGPU_GEM_DOMAIN_VRAM,
+			AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+			&bo_mc, &va_handle);
+
+	gpu_mem_free(bo, va_handle, bo_mc, 4096);
+
+	/* Test invisible VRAM */
+	bo = gpu_mem_alloc(device_handle,
+			4096, 4096,
+			AMDGPU_GEM_DOMAIN_VRAM,
+			AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
+			&bo_mc, &va_handle);
+
+	gpu_mem_free(bo, va_handle, bo_mc, 4096);
+
+	/* Test GART cacheable */
+	bo = gpu_mem_alloc(device_handle,
+			4096, 4096,
+			AMDGPU_GEM_DOMAIN_GTT,
+			0, &bo_mc, &va_handle);
+
+	gpu_mem_free(bo, va_handle, bo_mc, 4096);
+
+	/* Test GART USWC */
+	bo = gpu_mem_alloc(device_handle,
+			4096, 4096,
+			AMDGPU_GEM_DOMAIN_GTT,
+			AMDGPU_GEM_CREATE_CPU_GTT_USWC,
+			&bo_mc, &va_handle);
+
+	gpu_mem_free(bo, va_handle, bo_mc, 4096);
+
+	/* Test GDS */
+	bo = gpu_mem_alloc(device_handle, 1024, 0,
+			AMDGPU_GEM_DOMAIN_GDS, 0,
+			&bo_mc, &va_handle);
+
+	gpu_mem_free(bo, va_handle, bo_mc, 4096);
+	/* Test GWS */
+	bo = gpu_mem_alloc(device_handle, 1, 0,
+			AMDGPU_GEM_DOMAIN_GWS, 0,
+			&bo_mc, &va_handle);
+	gpu_mem_free(bo, va_handle, bo_mc, 4096);
+	/* Test OA */
+	bo = gpu_mem_alloc(device_handle, 1, 0,
+			AMDGPU_GEM_DOMAIN_OA, 0,
+			&bo_mc, &va_handle);
+	gpu_mem_free(bo, va_handle, bo_mc, 4096);
+}
+
+static void
+amdgpu_mem_fail_alloc(amdgpu_device_handle device_handle)
+{
+	int r;
+	struct amdgpu_bo_alloc_request req = {0};
+	amdgpu_bo_handle buf_handle;
+
+	/* Test impossible mem allocation, 1TB */
+	req.alloc_size = 0xE8D4A51000;
+	req.phys_alignment = 4096;
+	req.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;
+	req.flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+
+	r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+	igt_assert_eq(r, -ENOMEM);
+
+	if (!r) {
+		r = amdgpu_bo_free(buf_handle);
+		igt_assert_eq(r, 0);
+	}
+}
+
+static void
+amdgpu_bo_find_by_cpu_mapping(amdgpu_device_handle device_handle)
+{
+	amdgpu_bo_handle bo_handle, find_bo_handle;
+	amdgpu_va_handle va_handle;
+	void *bo_cpu;
+	uint64_t bo_mc_address;
+	uint64_t offset;
+	int r;
+
+	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+				    AMDGPU_GEM_DOMAIN_GTT, 0,
+				    &bo_handle, &bo_cpu,
+				    &bo_mc_address, &va_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_find_bo_by_cpu_mapping(device_handle,
+					  bo_cpu,
+					  4096,
+					  &find_bo_handle,
+					  &offset);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(offset, 0);
+
+	amdgpu_bo_unmap_and_free(bo_handle, va_handle,
+				     bo_mc_address, 4096);
+}
+
+igt_main
+{
+	amdgpu_device_handle device;
+	struct bo_data bo;
+	int fd = -1;
+
+	igt_fixture {
+		uint32_t major, minor;
+		int err;
+
+		fd = drm_open_driver(DRIVER_AMDGPU);
+		err = amdgpu_device_initialize(fd, &major, &minor, &device);
+		igt_require(err == 0);
+		igt_info("Initialized amdgpu, driver version %d.%d\n",
+			 major, minor);
+		err = amdgpu_bo_init(device, &bo);
+		igt_require(err == 0);
+	}
+
+	igt_subtest("amdgpu_bo_export_import")
+	amdgpu_bo_export_import(device, &bo);
+
+	igt_subtest("amdgpu_bo_metadata")
+	amdgpu_bo_metadata(device, &bo);
+
+	igt_subtest("amdgpu_bo_map_unmap")
+	amdgpu_bo_map_unmap(device, &bo);
+
+	igt_subtest("amdgpu_memory_alloc")
+	amdgpu_memory_alloc(device);
+
+	igt_subtest("amdgpu_mem_fail_alloc")
+	amdgpu_mem_fail_alloc(device);
+
+	igt_subtest("amdgpu_bo_find_by_cpu_mapping")
+	amdgpu_bo_find_by_cpu_mapping(device);
+
+	igt_fixture {
+		amdgpu_bo_clean(device, &bo);
+		amdgpu_device_deinitialize(device);
+		close(fd);
+	}
+}
+
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 7fff7602f..43326a7c4 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -5,6 +5,7 @@ if libdrm_amdgpu.found()
 	amdgpu_progs += [ 'amd_abm',
 			  'amd_assr',
 			  'amd_basic',
+			  'amd_bo',
 			  'amd_bypass',
 			  'amd_deadlock',
 			  'amd_pci_unplug',
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-15 22:39 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
@ 2023-06-15 22:39 ` vitaly.prosyak
  2023-06-28 21:10   ` Kamil Konieczny
  2023-06-30 16:28   ` Kamil Konieczny
  2023-06-16  0:27 ` [igt-dev] ✗ GitLab.Pipeline: warning for series starting with [1/2] tests/amdgpu: add bo tests Patchwork
  2023-06-16  0:49 ` [igt-dev] ✗ Fi.CI.BAT: failure " Patchwork
  2 siblings, 2 replies; 12+ messages in thread
From: vitaly.prosyak @ 2023-06-15 22:39 UTC (permalink / raw)
  To: igt-dev; +Cc: alexander.deucher, michael.strawbridge, christian.koenig

From: Vitaly Prosyak <vitaly.prosyak@amd.com>

Using worker thread to wait on point and then signal point on other thread.
Another test uses a worker thread to signal point and wait on the main
thread using amdgpu_cs_syncobj_timeline_wait.

The command consists of two chunks :
1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
   or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
   point number .

v1->v2. Fixed style issues - Christian.
        Fixed formatting issues - Kamil.

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by Christian Koenig <christian.koenig@amd.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
---
 tests/amdgpu/amd_syncobj.c | 263 +++++++++++++++++++++++++++++++++++++
 tests/amdgpu/meson.build   |   1 +
 2 files changed, 264 insertions(+)
 create mode 100644 tests/amdgpu/amd_syncobj.c

diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
new file mode 100644
index 000000000..5fae8fd3e
--- /dev/null
+++ b/tests/amdgpu/amd_syncobj.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: MIT
+// Copyright 2023 Advanced Micro Devices, Inc.
+
+#include <pthread.h>
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+
+#include "igt.h"
+#include "lib/amdgpu/amd_PM4.h"
+#include "lib/amdgpu/amd_sdma.h"
+#include "lib/amdgpu/amd_memory.h"
+
+struct syncobj_point {
+	amdgpu_device_handle device;
+	uint32_t syncobj_handle;
+	uint64_t point;
+};
+
+
+static bool
+syncobj_timeline_enable(int fd)
+{
+	int r;
+	bool ret = false;
+	uint64_t cap = 0;
+
+	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+	if (r || cap == 0)
+		return ret;
+	ret = true;
+
+	return ret;
+}
+
+static void
+syncobj_command_submission_helper(amdgpu_device_handle device_handle,
+		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
+{
+	amdgpu_context_handle context_handle;
+	amdgpu_bo_handle ib_result_handle;
+	void *ib_result_cpu;
+	uint64_t ib_result_mc_address;
+	struct drm_amdgpu_cs_chunk chunks[2];
+	struct drm_amdgpu_cs_chunk_data chunk_data;
+	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
+	struct amdgpu_cs_fence fence_status;
+	amdgpu_bo_list_handle bo_list;
+	amdgpu_va_handle va_handle;
+	uint32_t expired;
+	int i, r;
+	uint64_t seq_no;
+	uint32_t *ptr;
+
+	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+				    AMDGPU_GEM_DOMAIN_GTT, 0,
+				    &ib_result_handle, &ib_result_cpu,
+				    &ib_result_mc_address, &va_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
+	igt_assert_eq(r, 0);
+
+	ptr = ib_result_cpu;
+
+	for (i = 0; i < 16; ++i)
+		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
+
+	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
+	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
+	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
+	chunk_data.ib_data._pad = 0;
+	chunk_data.ib_data.va_start = ib_result_mc_address;
+	chunk_data.ib_data.ib_bytes = 16 * 4;
+	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	chunk_data.ib_data.ip_instance = 0;
+	chunk_data.ib_data.ring = 0;
+	chunk_data.ib_data.flags = 0;
+
+	chunks[1].chunk_id = wait_or_signal ?
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
+	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
+	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
+	syncobj_data.handle = syncobj_handle;
+	syncobj_data.point = point;
+	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+	r = amdgpu_cs_submit_raw(device_handle,
+				 context_handle,
+				 bo_list,
+				 2,
+				 chunks,
+				 &seq_no);
+	igt_assert_eq(r, 0);
+
+	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+	fence_status.context = context_handle;
+	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	fence_status.ip_instance = 0;
+	fence_status.ring = 0;
+	fence_status.fence = seq_no;
+
+	r = amdgpu_cs_query_fence_status(&fence_status,
+			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_list_destroy(bo_list);
+	igt_assert_eq(r, 0);
+
+	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+				     ib_result_mc_address, 4096);
+
+	r = amdgpu_cs_ctx_free(context_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void *
+syncobj_wait(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+
+	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
+			sp->point);
+
+	return (void *)0;
+}
+
+static void *
+syncobj_signal(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+
+	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
+			sp->point);
+
+	return (void *)0;
+}
+
+static void
+amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
+{
+	static pthread_t wait_thread;
+	static pthread_t signal_thread;
+	static pthread_t c_thread;
+	struct syncobj_point sp1, sp2, sp3;
+	uint32_t syncobj_handle;
+	uint64_t payload;
+	uint64_t wait_point, signal_point;
+	uint64_t timeout;
+	struct timespec tp;
+	int r, sync_fd;
+	void *tmp, *tmp2;
+
+	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
+	igt_assert_eq(r, 0);
+
+	// wait on point 5
+	sp1.syncobj_handle = syncobj_handle;
+	sp1.device = device_handle;
+	sp1.point = 5;
+	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
+	igt_assert_eq(r, 0);
+
+	// signal on point 10
+	sp2.syncobj_handle = syncobj_handle;
+	sp2.device = device_handle;
+	sp2.point = 10;
+	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(signal_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(wait_thread, &tmp2);
+	igt_assert_eq(r, 0);
+
+	//query timeline payload
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 10);
+
+	//signal on point 16
+	sp3.syncobj_handle = syncobj_handle;
+	sp3.device = device_handle;
+	sp3.point = 16;
+	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
+	igt_assert_eq(r, 0);
+
+	//CPU wait on point 16
+	wait_point = 16;
+	timeout = 0;
+	clock_gettime(CLOCK_MONOTONIC, &tp);
+	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+	timeout += 10000000000; //10s
+	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
+					    &wait_point, 1, timeout,
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+					    NULL);
+
+	igt_assert_eq(r, 0);
+	r = pthread_join(c_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	// export point 16 and import to point 18
+	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
+						16,
+						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+						&sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
+						18, sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 18);
+
+	// CPU signal on point 20
+	signal_point = 20;
+	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
+					      &signal_point, 1);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 20);
+
+	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
+	igt_assert_eq(r, 0);
+
+}
+
+igt_main
+{
+	amdgpu_device_handle device;
+	int fd = -1;
+
+	igt_fixture {
+		uint32_t major, minor;
+		int err;
+
+		fd = drm_open_driver(DRIVER_AMDGPU);
+		err = amdgpu_device_initialize(fd, &major, &minor, &device);
+		igt_require(err == 0);
+		igt_require(syncobj_timeline_enable(fd));
+		igt_info("Initialized amdgpu, driver version %d.%d\n",
+			 major, minor);
+
+	}
+
+	igt_subtest("amdgpu_syncobj_timeline")
+	amdgpu_syncobj_timeline(device);
+
+	igt_fixture {
+		amdgpu_device_deinitialize(device);
+		close(fd);
+	}
+}
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 43326a7c4..576d242c5 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
 			  'amd_assr',
 			  'amd_basic',
 			  'amd_bo',
+			  'amd_syncobj',
 			  'amd_bypass',
 			  'amd_deadlock',
 			  'amd_pci_unplug',
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] ✗ GitLab.Pipeline: warning for series starting with [1/2] tests/amdgpu: add bo tests
  2023-06-15 22:39 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
  2023-06-15 22:39 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
@ 2023-06-16  0:27 ` Patchwork
  2023-06-16  0:49 ` [igt-dev] ✗ Fi.CI.BAT: failure " Patchwork
  2 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2023-06-16  0:27 UTC (permalink / raw)
  To: vitaly.prosyak; +Cc: igt-dev

== Series Details ==

Series: series starting with [1/2] tests/amdgpu: add bo tests
URL   : https://patchwork.freedesktop.org/series/119417/
State : warning

== Summary ==

Pipeline status: FAILED.

see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/910520 for the overview.

build:tests-debian-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/43872297):
        amdgpu_cs_syncobj_export_sync_file
  ../tests/amdgpu/amd_syncobj.c:210:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_export_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:215:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_import_sync_file2’; did you mean ‘amdgpu_cs_syncobj_import_sync_file’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_import_sync_file
  ../tests/amdgpu/amd_syncobj.c:215:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_import_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:225:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_timeline_signal’; did you mean ‘amdgpu_cs_syncobj_signal’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_signal
  ../tests/amdgpu/amd_syncobj.c:225:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_timeline_signal’ [-Wnested-externs]
  cc1: some warnings being treated as errors
  ninja: build stopped: subcommand failed.
  section_end:1686874809:step_script
  section_start:1686874809:cleanup_file_variables
  Cleaning up project directory and file based variables
  section_end:1686874810:cleanup_file_variables
  ERROR: Job failed: exit code 1
  

build:tests-debian-meson-arm64 has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/43872300):
        amdgpu_cs_syncobj_export_sync_file
  ../tests/amdgpu/amd_syncobj.c:210:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_export_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:215:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_import_sync_file2’; did you mean ‘amdgpu_cs_syncobj_import_sync_file’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_import_sync_file
  ../tests/amdgpu/amd_syncobj.c:215:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_import_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:225:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_timeline_signal’; did you mean ‘amdgpu_cs_syncobj_signal’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_signal
  ../tests/amdgpu/amd_syncobj.c:225:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_timeline_signal’ [-Wnested-externs]
  cc1: some warnings being treated as errors
  ninja: build stopped: subcommand failed.
  section_end:1686874842:step_script
  section_start:1686874842:cleanup_file_variables
  Cleaning up project directory and file based variables
  section_end:1686874844:cleanup_file_variables
  ERROR: Job failed: exit code 1
  

build:tests-debian-meson-armhf has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/43872299):
        amdgpu_cs_syncobj_export_sync_file
  ../tests/amdgpu/amd_syncobj.c:210:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_export_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:215:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_import_sync_file2’; did you mean ‘amdgpu_cs_syncobj_import_sync_file’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_import_sync_file
  ../tests/amdgpu/amd_syncobj.c:215:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_import_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:225:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_timeline_signal’; did you mean ‘amdgpu_cs_syncobj_signal’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_signal
  ../tests/amdgpu/amd_syncobj.c:225:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_timeline_signal’ [-Wnested-externs]
  cc1: some warnings being treated as errors
  ninja: build stopped: subcommand failed.
  section_end:1686874887:step_script
  section_start:1686874887:cleanup_file_variables
  Cleaning up project directory and file based variables
  section_end:1686874887:cleanup_file_variables
  ERROR: Job failed: exit code 1
  

build:tests-debian-meson-mips has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/43872301):
        amdgpu_cs_syncobj_export_sync_file
  ../tests/amdgpu/amd_syncobj.c:210:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_export_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:215:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_import_sync_file2’; did you mean ‘amdgpu_cs_syncobj_import_sync_file’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_import_sync_file
  ../tests/amdgpu/amd_syncobj.c:215:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_import_sync_file2’ [-Wnested-externs]
  ../tests/amdgpu/amd_syncobj.c:225:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_timeline_signal’; did you mean ‘amdgpu_cs_syncobj_signal’? [-Werror=implicit-function-declaration]
    r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        amdgpu_cs_syncobj_signal
  ../tests/amdgpu/amd_syncobj.c:225:6: warning: nested extern declaration of ‘amdgpu_cs_syncobj_timeline_signal’ [-Wnested-externs]
  cc1: some warnings being treated as errors
  ninja: build stopped: subcommand failed.
  section_end:1686874853:step_script
  section_start:1686874853:cleanup_file_variables
  Cleaning up project directory and file based variables
  section_end:1686874854:cleanup_file_variables
  ERROR: Job failed: exit code 1

== Logs ==

For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/910520

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [igt-dev] ✗ Fi.CI.BAT: failure for series starting with [1/2] tests/amdgpu: add bo tests
  2023-06-15 22:39 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
  2023-06-15 22:39 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
  2023-06-16  0:27 ` [igt-dev] ✗ GitLab.Pipeline: warning for series starting with [1/2] tests/amdgpu: add bo tests Patchwork
@ 2023-06-16  0:49 ` Patchwork
  2 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2023-06-16  0:49 UTC (permalink / raw)
  To: vitaly.prosyak; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 7749 bytes --]

== Series Details ==

Series: series starting with [1/2] tests/amdgpu: add bo tests
URL   : https://patchwork.freedesktop.org/series/119417/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_13276 -> IGTPW_9191
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_9191 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_9191, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/index.html

Participating hosts (38 -> 41)
------------------------------

  Additional (4): fi-blb-e6850 bat-dg1-8 fi-bsw-nick fi-bsw-n3050 
  Missing    (1): fi-snb-2520m 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_9191:

### IGT changes ###

#### Possible regressions ####

  * igt@i915_pm_rpm@module-reload:
    - bat-dg2-8:          [PASS][1] -> [FAIL][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/bat-dg2-8/igt@i915_pm_rpm@module-reload.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-dg2-8/igt@i915_pm_rpm@module-reload.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@kms_pipe_crc_basic@hang-read-crc:
    - {bat-dg1-8}:        NOTRUN -> [SKIP][3] +73 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-dg1-8/igt@kms_pipe_crc_basic@hang-read-crc.html

  * igt@xe_guc_pc@freq_fixed_idle:
    - {bat-dg1-8}:        NOTRUN -> [FAIL][4] +1 similar issue
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-dg1-8/igt@xe_guc_pc@freq_fixed_idle.html

  * {igt@xe_live_ktest@bo}:
    - {bat-dg1-8}:        NOTRUN -> [DMESG-WARN][5] +1 similar issue
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-dg1-8/igt@xe_live_ktest@bo.html

  
Known issues
------------

  Here are the changes found in IGTPW_9191 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_lmem_swapping@parallel-random-engines:
    - fi-bsw-nick:        NOTRUN -> [SKIP][6] ([fdo#109271]) +51 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/fi-bsw-nick/igt@gem_lmem_swapping@parallel-random-engines.html

  * igt@i915_pm_backlight@basic-brightness@edp-1:
    - bat-rplp-1:         NOTRUN -> [ABORT][7] ([i915#7077])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-rplp-1/igt@i915_pm_backlight@basic-brightness@edp-1.html

  * igt@i915_pm_rpm@module-reload:
    - fi-blb-e6850:       NOTRUN -> [SKIP][8] ([fdo#109271]) +37 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/fi-blb-e6850/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@gt_heartbeat:
    - fi-apl-guc:         [PASS][9] -> [DMESG-FAIL][10] ([i915#5334])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/fi-apl-guc/igt@i915_selftest@live@gt_heartbeat.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/fi-apl-guc/igt@i915_selftest@live@gt_heartbeat.html

  * igt@i915_selftest@live@gt_mocs:
    - bat-mtlp-8:         [PASS][11] -> [DMESG-FAIL][12] ([i915#7059])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html

  * igt@i915_selftest@live@requests:
    - bat-mtlp-6:         [PASS][13] -> [DMESG-FAIL][14] ([i915#8497])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/bat-mtlp-6/igt@i915_selftest@live@requests.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-mtlp-6/igt@i915_selftest@live@requests.html

  * igt@i915_selftest@live@slpc:
    - bat-rpls-1:         [PASS][15] -> [DMESG-WARN][16] ([i915#6367])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/bat-rpls-1/igt@i915_selftest@live@slpc.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-rpls-1/igt@i915_selftest@live@slpc.html

  * igt@kms_chamelium_edid@dp-edid-read:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][17] ([fdo#109271]) +25 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/fi-bsw-n3050/igt@kms_chamelium_edid@dp-edid-read.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12@pipe-c-hdmi-a-2:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][18] ([fdo#109271] / [i915#4579]) +1 similar issue
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/fi-bsw-n3050/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12@pipe-c-hdmi-a-2.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-blb-e6850:       NOTRUN -> [SKIP][19] ([fdo#109271] / [i915#4579])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/fi-blb-e6850/igt@kms_setmode@basic-clone-single-crtc.html
    - fi-bsw-nick:        NOTRUN -> [SKIP][20] ([fdo#109271] / [i915#4579])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/fi-bsw-nick/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@gt_pm:
    - bat-rpls-2:         [DMESG-FAIL][21] ([i915#4258] / [i915#7913]) -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/bat-rpls-2/igt@i915_selftest@live@gt_pm.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-rpls-2/igt@i915_selftest@live@gt_pm.html

  * igt@i915_selftest@live@slpc:
    - bat-mtlp-8:         [DMESG-WARN][23] ([i915#6367]) -> [PASS][24]
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/bat-mtlp-8/igt@i915_selftest@live@slpc.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-mtlp-8/igt@i915_selftest@live@slpc.html

  
#### Warnings ####

  * igt@kms_setmode@basic-clone-single-crtc:
    - bat-rplp-1:         [ABORT][25] ([i915#4579] / [i915#8260]) -> [SKIP][26] ([i915#3555] / [i915#4579])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13276/bat-rplp-1/igt@kms_setmode@basic-clone-single-crtc.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/bat-rplp-1/igt@kms_setmode@basic-clone-single-crtc.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#4258]: https://gitlab.freedesktop.org/drm/intel/issues/4258
  [i915#4579]: https://gitlab.freedesktop.org/drm/intel/issues/4579
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#6367]: https://gitlab.freedesktop.org/drm/intel/issues/6367
  [i915#7059]: https://gitlab.freedesktop.org/drm/intel/issues/7059
  [i915#7077]: https://gitlab.freedesktop.org/drm/intel/issues/7077
  [i915#7913]: https://gitlab.freedesktop.org/drm/intel/issues/7913
  [i915#8260]: https://gitlab.freedesktop.org/drm/intel/issues/8260
  [i915#8497]: https://gitlab.freedesktop.org/drm/intel/issues/8497


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_7332 -> IGTPW_9191

  CI-20190529: 20190529
  CI_DRM_13276: afe49e3c604f9690c9d499185149f83bd259601c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_9191: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/index.html
  IGT_7332: 2a25a6109e8af4b0a69a717cc8710dcafed4bb4c @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9191/index.html

[-- Attachment #2: Type: text/html, Size: 9496 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-19 20:37 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
@ 2023-06-19 20:38 ` vitaly.prosyak
  0 siblings, 0 replies; 12+ messages in thread
From: vitaly.prosyak @ 2023-06-19 20:38 UTC (permalink / raw)
  To: igt-dev

From: Vitaly Prosyak <vitaly.prosyak@amd.com>

Using worker thread to wait on point and then signal point on other thread.
Another test uses a worker thread to signal point and wait on the main
thread using amdgpu_cs_syncobj_timeline_wait.

The command consists of two chunks :
1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
   or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
   point number .

v1->v2. Fixed style issues - Christian.
        Fixed formatting issues - Kamil.

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by Christian Koenig <christian.koenig@amd.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
---
 tests/amdgpu/amd_syncobj.c | 263 +++++++++++++++++++++++++++++++++++++
 tests/amdgpu/meson.build   |   1 +
 2 files changed, 264 insertions(+)
 create mode 100644 tests/amdgpu/amd_syncobj.c

diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
new file mode 100644
index 000000000..5fae8fd3e
--- /dev/null
+++ b/tests/amdgpu/amd_syncobj.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: MIT
+// Copyright 2023 Advanced Micro Devices, Inc.
+
+#include <pthread.h>
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+
+#include "igt.h"
+#include "lib/amdgpu/amd_PM4.h"
+#include "lib/amdgpu/amd_sdma.h"
+#include "lib/amdgpu/amd_memory.h"
+
+struct syncobj_point {
+	amdgpu_device_handle device;
+	uint32_t syncobj_handle;
+	uint64_t point;
+};
+
+
+static bool
+syncobj_timeline_enable(int fd)
+{
+	int r;
+	bool ret = false;
+	uint64_t cap = 0;
+
+	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+	if (r || cap == 0)
+		return ret;
+	ret = true;
+
+	return ret;
+}
+
+static void
+syncobj_command_submission_helper(amdgpu_device_handle device_handle,
+		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
+{
+	amdgpu_context_handle context_handle;
+	amdgpu_bo_handle ib_result_handle;
+	void *ib_result_cpu;
+	uint64_t ib_result_mc_address;
+	struct drm_amdgpu_cs_chunk chunks[2];
+	struct drm_amdgpu_cs_chunk_data chunk_data;
+	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
+	struct amdgpu_cs_fence fence_status;
+	amdgpu_bo_list_handle bo_list;
+	amdgpu_va_handle va_handle;
+	uint32_t expired;
+	int i, r;
+	uint64_t seq_no;
+	uint32_t *ptr;
+
+	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+				    AMDGPU_GEM_DOMAIN_GTT, 0,
+				    &ib_result_handle, &ib_result_cpu,
+				    &ib_result_mc_address, &va_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
+	igt_assert_eq(r, 0);
+
+	ptr = ib_result_cpu;
+
+	for (i = 0; i < 16; ++i)
+		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
+
+	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
+	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
+	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
+	chunk_data.ib_data._pad = 0;
+	chunk_data.ib_data.va_start = ib_result_mc_address;
+	chunk_data.ib_data.ib_bytes = 16 * 4;
+	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	chunk_data.ib_data.ip_instance = 0;
+	chunk_data.ib_data.ring = 0;
+	chunk_data.ib_data.flags = 0;
+
+	chunks[1].chunk_id = wait_or_signal ?
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
+	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
+	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
+	syncobj_data.handle = syncobj_handle;
+	syncobj_data.point = point;
+	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+	r = amdgpu_cs_submit_raw(device_handle,
+				 context_handle,
+				 bo_list,
+				 2,
+				 chunks,
+				 &seq_no);
+	igt_assert_eq(r, 0);
+
+	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+	fence_status.context = context_handle;
+	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	fence_status.ip_instance = 0;
+	fence_status.ring = 0;
+	fence_status.fence = seq_no;
+
+	r = amdgpu_cs_query_fence_status(&fence_status,
+			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_list_destroy(bo_list);
+	igt_assert_eq(r, 0);
+
+	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+				     ib_result_mc_address, 4096);
+
+	r = amdgpu_cs_ctx_free(context_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void *
+syncobj_wait(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+
+	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
+			sp->point);
+
+	return (void *)0;
+}
+
+static void *
+syncobj_signal(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+
+	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
+			sp->point);
+
+	return (void *)0;
+}
+
+static void
+amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
+{
+	static pthread_t wait_thread;
+	static pthread_t signal_thread;
+	static pthread_t c_thread;
+	struct syncobj_point sp1, sp2, sp3;
+	uint32_t syncobj_handle;
+	uint64_t payload;
+	uint64_t wait_point, signal_point;
+	uint64_t timeout;
+	struct timespec tp;
+	int r, sync_fd;
+	void *tmp, *tmp2;
+
+	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
+	igt_assert_eq(r, 0);
+
+	// wait on point 5
+	sp1.syncobj_handle = syncobj_handle;
+	sp1.device = device_handle;
+	sp1.point = 5;
+	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
+	igt_assert_eq(r, 0);
+
+	// signal on point 10
+	sp2.syncobj_handle = syncobj_handle;
+	sp2.device = device_handle;
+	sp2.point = 10;
+	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(signal_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(wait_thread, &tmp2);
+	igt_assert_eq(r, 0);
+
+	//query timeline payload
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 10);
+
+	//signal on point 16
+	sp3.syncobj_handle = syncobj_handle;
+	sp3.device = device_handle;
+	sp3.point = 16;
+	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
+	igt_assert_eq(r, 0);
+
+	//CPU wait on point 16
+	wait_point = 16;
+	timeout = 0;
+	clock_gettime(CLOCK_MONOTONIC, &tp);
+	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+	timeout += 10000000000; //10s
+	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
+					    &wait_point, 1, timeout,
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+					    NULL);
+
+	igt_assert_eq(r, 0);
+	r = pthread_join(c_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	// export point 16 and import to point 18
+	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
+						16,
+						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+						&sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
+						18, sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 18);
+
+	// CPU signal on point 20
+	signal_point = 20;
+	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
+					      &signal_point, 1);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 20);
+
+	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
+	igt_assert_eq(r, 0);
+
+}
+
+igt_main
+{
+	amdgpu_device_handle device;
+	int fd = -1;
+
+	igt_fixture {
+		uint32_t major, minor;
+		int err;
+
+		fd = drm_open_driver(DRIVER_AMDGPU);
+		err = amdgpu_device_initialize(fd, &major, &minor, &device);
+		igt_require(err == 0);
+		igt_require(syncobj_timeline_enable(fd));
+		igt_info("Initialized amdgpu, driver version %d.%d\n",
+			 major, minor);
+
+	}
+
+	igt_subtest("amdgpu_syncobj_timeline")
+	amdgpu_syncobj_timeline(device);
+
+	igt_fixture {
+		amdgpu_device_deinitialize(device);
+		close(fd);
+	}
+}
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 43326a7c4..576d242c5 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
 			  'amd_assr',
 			  'amd_basic',
 			  'amd_bo',
+			  'amd_syncobj',
 			  'amd_bypass',
 			  'amd_deadlock',
 			  'amd_pci_unplug',
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-21  0:39 [igt-dev] [PATCH 1/2] " vitaly.prosyak
@ 2023-06-21  0:39 ` vitaly.prosyak
  0 siblings, 0 replies; 12+ messages in thread
From: vitaly.prosyak @ 2023-06-21  0:39 UTC (permalink / raw)
  To: igt-dev

From: Vitaly Prosyak <vitaly.prosyak@amd.com>

Using worker thread to wait on point and then signal point on other thread.
Another test uses a worker thread to signal point and wait on the main
thread using amdgpu_cs_syncobj_timeline_wait.

The command consists of two chunks :
1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
   or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
   point number .

v1->v2. Fixed style issues - Christian.
        Fixed formatting issues - Kamil.

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by Christian Koenig <christian.koenig@amd.com>
Acked-by Kamil Konieczny <kamil.konieczny@linux.intel.com>
---
 tests/amdgpu/amd_syncobj.c | 263 +++++++++++++++++++++++++++++++++++++
 tests/amdgpu/meson.build   |   1 +
 2 files changed, 264 insertions(+)
 create mode 100644 tests/amdgpu/amd_syncobj.c

diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
new file mode 100644
index 000000000..5fae8fd3e
--- /dev/null
+++ b/tests/amdgpu/amd_syncobj.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: MIT
+// Copyright 2023 Advanced Micro Devices, Inc.
+
+#include <pthread.h>
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+
+#include "igt.h"
+#include "lib/amdgpu/amd_PM4.h"
+#include "lib/amdgpu/amd_sdma.h"
+#include "lib/amdgpu/amd_memory.h"
+
+struct syncobj_point {
+	amdgpu_device_handle device;
+	uint32_t syncobj_handle;
+	uint64_t point;
+};
+
+
+static bool
+syncobj_timeline_enable(int fd)
+{
+	int r;
+	bool ret = false;
+	uint64_t cap = 0;
+
+	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+	if (r || cap == 0)
+		return ret;
+	ret = true;
+
+	return ret;
+}
+
+static void
+syncobj_command_submission_helper(amdgpu_device_handle device_handle,
+		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
+{
+	amdgpu_context_handle context_handle;
+	amdgpu_bo_handle ib_result_handle;
+	void *ib_result_cpu;
+	uint64_t ib_result_mc_address;
+	struct drm_amdgpu_cs_chunk chunks[2];
+	struct drm_amdgpu_cs_chunk_data chunk_data;
+	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
+	struct amdgpu_cs_fence fence_status;
+	amdgpu_bo_list_handle bo_list;
+	amdgpu_va_handle va_handle;
+	uint32_t expired;
+	int i, r;
+	uint64_t seq_no;
+	uint32_t *ptr;
+
+	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+				    AMDGPU_GEM_DOMAIN_GTT, 0,
+				    &ib_result_handle, &ib_result_cpu,
+				    &ib_result_mc_address, &va_handle);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
+	igt_assert_eq(r, 0);
+
+	ptr = ib_result_cpu;
+
+	for (i = 0; i < 16; ++i)
+		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
+
+	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
+	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
+	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
+	chunk_data.ib_data._pad = 0;
+	chunk_data.ib_data.va_start = ib_result_mc_address;
+	chunk_data.ib_data.ib_bytes = 16 * 4;
+	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	chunk_data.ib_data.ip_instance = 0;
+	chunk_data.ib_data.ring = 0;
+	chunk_data.ib_data.flags = 0;
+
+	chunks[1].chunk_id = wait_or_signal ?
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
+		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
+	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
+	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
+	syncobj_data.handle = syncobj_handle;
+	syncobj_data.point = point;
+	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+	r = amdgpu_cs_submit_raw(device_handle,
+				 context_handle,
+				 bo_list,
+				 2,
+				 chunks,
+				 &seq_no);
+	igt_assert_eq(r, 0);
+
+	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+	fence_status.context = context_handle;
+	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
+	fence_status.ip_instance = 0;
+	fence_status.ring = 0;
+	fence_status.fence = seq_no;
+
+	r = amdgpu_cs_query_fence_status(&fence_status,
+			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
+	igt_assert_eq(r, 0);
+
+	r = amdgpu_bo_list_destroy(bo_list);
+	igt_assert_eq(r, 0);
+
+	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+				     ib_result_mc_address, 4096);
+
+	r = amdgpu_cs_ctx_free(context_handle);
+	igt_assert_eq(r, 0);
+}
+
+static void *
+syncobj_wait(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+
+	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
+			sp->point);
+
+	return (void *)0;
+}
+
+static void *
+syncobj_signal(void *data)
+{
+	struct syncobj_point *sp = (struct syncobj_point *)data;
+
+	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
+			sp->point);
+
+	return (void *)0;
+}
+
+static void
+amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
+{
+	static pthread_t wait_thread;
+	static pthread_t signal_thread;
+	static pthread_t c_thread;
+	struct syncobj_point sp1, sp2, sp3;
+	uint32_t syncobj_handle;
+	uint64_t payload;
+	uint64_t wait_point, signal_point;
+	uint64_t timeout;
+	struct timespec tp;
+	int r, sync_fd;
+	void *tmp, *tmp2;
+
+	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
+	igt_assert_eq(r, 0);
+
+	// wait on point 5
+	sp1.syncobj_handle = syncobj_handle;
+	sp1.device = device_handle;
+	sp1.point = 5;
+	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
+	igt_assert_eq(r, 0);
+
+	// signal on point 10
+	sp2.syncobj_handle = syncobj_handle;
+	sp2.device = device_handle;
+	sp2.point = 10;
+	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(signal_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	r = pthread_join(wait_thread, &tmp2);
+	igt_assert_eq(r, 0);
+
+	//query timeline payload
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 10);
+
+	//signal on point 16
+	sp3.syncobj_handle = syncobj_handle;
+	sp3.device = device_handle;
+	sp3.point = 16;
+	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
+	igt_assert_eq(r, 0);
+
+	//CPU wait on point 16
+	wait_point = 16;
+	timeout = 0;
+	clock_gettime(CLOCK_MONOTONIC, &tp);
+	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+	timeout += 10000000000; //10s
+	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
+					    &wait_point, 1, timeout,
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+					    NULL);
+
+	igt_assert_eq(r, 0);
+	r = pthread_join(c_thread, &tmp);
+	igt_assert_eq(r, 0);
+
+	// export point 16 and import to point 18
+	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
+						16,
+						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+						&sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
+						18, sync_fd);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 18);
+
+	// CPU signal on point 20
+	signal_point = 20;
+	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
+					      &signal_point, 1);
+	igt_assert_eq(r, 0);
+	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+				    &payload, 1);
+	igt_assert_eq(r, 0);
+	igt_assert_eq(payload, 20);
+
+	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
+	igt_assert_eq(r, 0);
+
+}
+
+igt_main
+{
+	amdgpu_device_handle device;
+	int fd = -1;
+
+	igt_fixture {
+		uint32_t major, minor;
+		int err;
+
+		fd = drm_open_driver(DRIVER_AMDGPU);
+		err = amdgpu_device_initialize(fd, &major, &minor, &device);
+		igt_require(err == 0);
+		igt_require(syncobj_timeline_enable(fd));
+		igt_info("Initialized amdgpu, driver version %d.%d\n",
+			 major, minor);
+
+	}
+
+	igt_subtest("amdgpu_syncobj_timeline")
+	amdgpu_syncobj_timeline(device);
+
+	igt_fixture {
+		amdgpu_device_deinitialize(device);
+		close(fd);
+	}
+}
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 43326a7c4..576d242c5 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
 			  'amd_assr',
 			  'amd_basic',
 			  'amd_bo',
+			  'amd_syncobj',
 			  'amd_bypass',
 			  'amd_deadlock',
 			  'amd_pci_unplug',
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-15 22:39 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
@ 2023-06-28 21:10   ` Kamil Konieczny
  2023-06-28 21:30     ` vitaly prosyak
  2023-06-30 16:28   ` Kamil Konieczny
  1 sibling, 1 reply; 12+ messages in thread
From: Kamil Konieczny @ 2023-06-28 21:10 UTC (permalink / raw)
  To: igt-dev; +Cc: alexander.deucher, michael.strawbridge, christian.koenig

Hi Vitaly,

On 2023-06-15 at 18:39:36 -0400, vitaly.prosyak@amd.com wrote:
> From: Vitaly Prosyak <vitaly.prosyak@amd.com>
> 
> Using worker thread to wait on point and then signal point on other thread.
> Another test uses a worker thread to signal point and wait on the main
> thread using amdgpu_cs_syncobj_timeline_wait.
> 
> The command consists of two chunks :
> 1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
> 2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
>    or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
>    point number .
> 
> v1->v2. Fixed style issues - Christian.
>         Fixed formatting issues - Kamil.
> 
> Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
> Acked-by Christian Koenig <christian.koenig@amd.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>

Please look at GitLab warningm there were soem problems on other
archs like arm64:

https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/910520

Regards,
Kamil

> ---
>  tests/amdgpu/amd_syncobj.c | 263 +++++++++++++++++++++++++++++++++++++
>  tests/amdgpu/meson.build   |   1 +
>  2 files changed, 264 insertions(+)
>  create mode 100644 tests/amdgpu/amd_syncobj.c
> 
> diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
> new file mode 100644
> index 000000000..5fae8fd3e
> --- /dev/null
> +++ b/tests/amdgpu/amd_syncobj.c
> @@ -0,0 +1,263 @@
> +// SPDX-License-Identifier: MIT
> +// Copyright 2023 Advanced Micro Devices, Inc.
> +
> +#include <pthread.h>
> +#include <amdgpu.h>
> +#include <amdgpu_drm.h>
> +
> +#include "igt.h"
> +#include "lib/amdgpu/amd_PM4.h"
> +#include "lib/amdgpu/amd_sdma.h"
> +#include "lib/amdgpu/amd_memory.h"
> +
> +struct syncobj_point {
> +	amdgpu_device_handle device;
> +	uint32_t syncobj_handle;
> +	uint64_t point;
> +};
> +
> +
> +static bool
> +syncobj_timeline_enable(int fd)
> +{
> +	int r;
> +	bool ret = false;
> +	uint64_t cap = 0;
> +
> +	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
> +	if (r || cap == 0)
> +		return ret;
> +	ret = true;
> +
> +	return ret;
> +}
> +
> +static void
> +syncobj_command_submission_helper(amdgpu_device_handle device_handle,
> +		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
> +{
> +	amdgpu_context_handle context_handle;
> +	amdgpu_bo_handle ib_result_handle;
> +	void *ib_result_cpu;
> +	uint64_t ib_result_mc_address;
> +	struct drm_amdgpu_cs_chunk chunks[2];
> +	struct drm_amdgpu_cs_chunk_data chunk_data;
> +	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
> +	struct amdgpu_cs_fence fence_status;
> +	amdgpu_bo_list_handle bo_list;
> +	amdgpu_va_handle va_handle;
> +	uint32_t expired;
> +	int i, r;
> +	uint64_t seq_no;
> +	uint32_t *ptr;
> +
> +	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
> +	igt_assert_eq(r, 0);
> +
> +	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
> +				    AMDGPU_GEM_DOMAIN_GTT, 0,
> +				    &ib_result_handle, &ib_result_cpu,
> +				    &ib_result_mc_address, &va_handle);
> +	igt_assert_eq(r, 0);
> +
> +	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
> +	igt_assert_eq(r, 0);
> +
> +	ptr = ib_result_cpu;
> +
> +	for (i = 0; i < 16; ++i)
> +		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
> +
> +	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
> +	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
> +	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
> +	chunk_data.ib_data._pad = 0;
> +	chunk_data.ib_data.va_start = ib_result_mc_address;
> +	chunk_data.ib_data.ib_bytes = 16 * 4;
> +	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
> +	chunk_data.ib_data.ip_instance = 0;
> +	chunk_data.ib_data.ring = 0;
> +	chunk_data.ib_data.flags = 0;
> +
> +	chunks[1].chunk_id = wait_or_signal ?
> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
> +	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
> +	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
> +	syncobj_data.handle = syncobj_handle;
> +	syncobj_data.point = point;
> +	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
> +
> +	r = amdgpu_cs_submit_raw(device_handle,
> +				 context_handle,
> +				 bo_list,
> +				 2,
> +				 chunks,
> +				 &seq_no);
> +	igt_assert_eq(r, 0);
> +
> +	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
> +	fence_status.context = context_handle;
> +	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
> +	fence_status.ip_instance = 0;
> +	fence_status.ring = 0;
> +	fence_status.fence = seq_no;
> +
> +	r = amdgpu_cs_query_fence_status(&fence_status,
> +			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
> +	igt_assert_eq(r, 0);
> +
> +	r = amdgpu_bo_list_destroy(bo_list);
> +	igt_assert_eq(r, 0);
> +
> +	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
> +				     ib_result_mc_address, 4096);
> +
> +	r = amdgpu_cs_ctx_free(context_handle);
> +	igt_assert_eq(r, 0);
> +}
> +
> +static void *
> +syncobj_wait(void *data)
> +{
> +	struct syncobj_point *sp = (struct syncobj_point *)data;
> +
> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
> +			sp->point);
> +
> +	return (void *)0;
> +}
> +
> +static void *
> +syncobj_signal(void *data)
> +{
> +	struct syncobj_point *sp = (struct syncobj_point *)data;
> +
> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
> +			sp->point);
> +
> +	return (void *)0;
> +}
> +
> +static void
> +amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
> +{
> +	static pthread_t wait_thread;
> +	static pthread_t signal_thread;
> +	static pthread_t c_thread;
> +	struct syncobj_point sp1, sp2, sp3;
> +	uint32_t syncobj_handle;
> +	uint64_t payload;
> +	uint64_t wait_point, signal_point;
> +	uint64_t timeout;
> +	struct timespec tp;
> +	int r, sync_fd;
> +	void *tmp, *tmp2;
> +
> +	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
> +	igt_assert_eq(r, 0);
> +
> +	// wait on point 5
> +	sp1.syncobj_handle = syncobj_handle;
> +	sp1.device = device_handle;
> +	sp1.point = 5;
> +	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
> +	igt_assert_eq(r, 0);
> +
> +	// signal on point 10
> +	sp2.syncobj_handle = syncobj_handle;
> +	sp2.device = device_handle;
> +	sp2.point = 10;
> +	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
> +	igt_assert_eq(r, 0);
> +
> +	r = pthread_join(signal_thread, &tmp);
> +	igt_assert_eq(r, 0);
> +
> +	r = pthread_join(wait_thread, &tmp2);
> +	igt_assert_eq(r, 0);
> +
> +	//query timeline payload
> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> +				    &payload, 1);
> +	igt_assert_eq(r, 0);
> +	igt_assert_eq(payload, 10);
> +
> +	//signal on point 16
> +	sp3.syncobj_handle = syncobj_handle;
> +	sp3.device = device_handle;
> +	sp3.point = 16;
> +	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
> +	igt_assert_eq(r, 0);
> +
> +	//CPU wait on point 16
> +	wait_point = 16;
> +	timeout = 0;
> +	clock_gettime(CLOCK_MONOTONIC, &tp);
> +	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
> +	timeout += 10000000000; //10s
> +	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
> +					    &wait_point, 1, timeout,
> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +					    NULL);
> +
> +	igt_assert_eq(r, 0);
> +	r = pthread_join(c_thread, &tmp);
> +	igt_assert_eq(r, 0);
> +
> +	// export point 16 and import to point 18
> +	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
> +						16,
> +						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +						&sync_fd);
> +	igt_assert_eq(r, 0);
> +	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
> +						18, sync_fd);
> +	igt_assert_eq(r, 0);
> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> +				    &payload, 1);
> +	igt_assert_eq(r, 0);
> +	igt_assert_eq(payload, 18);
> +
> +	// CPU signal on point 20
> +	signal_point = 20;
> +	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
> +					      &signal_point, 1);
> +	igt_assert_eq(r, 0);
> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> +				    &payload, 1);
> +	igt_assert_eq(r, 0);
> +	igt_assert_eq(payload, 20);
> +
> +	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
> +	igt_assert_eq(r, 0);
> +
> +}
> +
> +igt_main
> +{
> +	amdgpu_device_handle device;
> +	int fd = -1;
> +
> +	igt_fixture {
> +		uint32_t major, minor;
> +		int err;
> +
> +		fd = drm_open_driver(DRIVER_AMDGPU);
> +		err = amdgpu_device_initialize(fd, &major, &minor, &device);
> +		igt_require(err == 0);
> +		igt_require(syncobj_timeline_enable(fd));
> +		igt_info("Initialized amdgpu, driver version %d.%d\n",
> +			 major, minor);
> +
> +	}
> +
> +	igt_subtest("amdgpu_syncobj_timeline")
> +	amdgpu_syncobj_timeline(device);
> +
> +	igt_fixture {
> +		amdgpu_device_deinitialize(device);
> +		close(fd);
> +	}
> +}
> diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
> index 43326a7c4..576d242c5 100644
> --- a/tests/amdgpu/meson.build
> +++ b/tests/amdgpu/meson.build
> @@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
>  			  'amd_assr',
>  			  'amd_basic',
>  			  'amd_bo',
> +			  'amd_syncobj',
>  			  'amd_bypass',
>  			  'amd_deadlock',
>  			  'amd_pci_unplug',
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-28 21:10   ` Kamil Konieczny
@ 2023-06-28 21:30     ` vitaly prosyak
  2023-06-30 16:14       ` Kamil Konieczny
  0 siblings, 1 reply; 12+ messages in thread
From: vitaly prosyak @ 2023-06-28 21:30 UTC (permalink / raw)
  To: Kamil Konieczny, igt-dev, vitaly.prosyak, christian.koenig,
	alexander.deucher, michael.strawbridge

[-- Attachment #1: Type: text/plain, Size: 10482 bytes --]

Hi Kamil,

Yes, there is compilation error which looks like no include from  <amdgpu.h>.

I am not sure how i can reproduce the issue locally because it is just fine for my local Ubuntu machine and other systems on AMD CI ( Fedora, etc.)

Do you have any suggestions ? Should l i use  QEMO to emulate arm64?

The error is following  and these functions are regular methods for drmlib:

./tests/amdgpu/amd_syncobj.c: In function ‘amdgpu_syncobj_timeline’:
|
../tests/amdgpu/amd_syncobj.c:181:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_query’; did you mean ‘amdgpu_cs_syncobj_wait’? [-Werror=implicit-function-declaration]
|

|r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,|

|
|

Thanks in advance

Vitaly


On 2023-06-28 17:10, Kamil Konieczny wrote:
> Hi Vitaly,
>
> On 2023-06-15 at 18:39:36 -0400, vitaly.prosyak@amd.com wrote:
>> From: Vitaly Prosyak <vitaly.prosyak@amd.com>
>>
>> Using worker thread to wait on point and then signal point on other thread.
>> Another test uses a worker thread to signal point and wait on the main
>> thread using amdgpu_cs_syncobj_timeline_wait.
>>
>> The command consists of two chunks :
>> 1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
>> 2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
>>    or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
>>    point number .
>>
>> v1->v2. Fixed style issues - Christian.
>>         Fixed formatting issues - Kamil.
>>
>> Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
>> Acked-by Christian Koenig <christian.koenig@amd.com>
>> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Please look at GitLab warningm there were soem problems on other
> archs like arm64:


||
>
> https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/910520
>
> Regards,
> Kamil
>
>> ---
>>  tests/amdgpu/amd_syncobj.c | 263 +++++++++++++++++++++++++++++++++++++
>>  tests/amdgpu/meson.build   |   1 +
>>  2 files changed, 264 insertions(+)
>>  create mode 100644 tests/amdgpu/amd_syncobj.c
>>
>> diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
>> new file mode 100644
>> index 000000000..5fae8fd3e
>> --- /dev/null
>> +++ b/tests/amdgpu/amd_syncobj.c
>> @@ -0,0 +1,263 @@
>> +// SPDX-License-Identifier: MIT
>> +// Copyright 2023 Advanced Micro Devices, Inc.
>> +
>> +#include <pthread.h>
>> +#include <amdgpu.h>
>> +#include <amdgpu_drm.h>
>> +
>> +#include "igt.h"
>> +#include "lib/amdgpu/amd_PM4.h"
>> +#include "lib/amdgpu/amd_sdma.h"
>> +#include "lib/amdgpu/amd_memory.h"
>> +
>> +struct syncobj_point {
>> +	amdgpu_device_handle device;
>> +	uint32_t syncobj_handle;
>> +	uint64_t point;
>> +};
>> +
>> +
>> +static bool
>> +syncobj_timeline_enable(int fd)
>> +{
>> +	int r;
>> +	bool ret = false;
>> +	uint64_t cap = 0;
>> +
>> +	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
>> +	if (r || cap == 0)
>> +		return ret;
>> +	ret = true;
>> +
>> +	return ret;
>> +}
>> +
>> +static void
>> +syncobj_command_submission_helper(amdgpu_device_handle device_handle,
>> +		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
>> +{
>> +	amdgpu_context_handle context_handle;
>> +	amdgpu_bo_handle ib_result_handle;
>> +	void *ib_result_cpu;
>> +	uint64_t ib_result_mc_address;
>> +	struct drm_amdgpu_cs_chunk chunks[2];
>> +	struct drm_amdgpu_cs_chunk_data chunk_data;
>> +	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
>> +	struct amdgpu_cs_fence fence_status;
>> +	amdgpu_bo_list_handle bo_list;
>> +	amdgpu_va_handle va_handle;
>> +	uint32_t expired;
>> +	int i, r;
>> +	uint64_t seq_no;
>> +	uint32_t *ptr;
>> +
>> +	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
>> +	igt_assert_eq(r, 0);
>> +
>> +	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
>> +				    AMDGPU_GEM_DOMAIN_GTT, 0,
>> +				    &ib_result_handle, &ib_result_cpu,
>> +				    &ib_result_mc_address, &va_handle);
>> +	igt_assert_eq(r, 0);
>> +
>> +	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
>> +	igt_assert_eq(r, 0);
>> +
>> +	ptr = ib_result_cpu;
>> +
>> +	for (i = 0; i < 16; ++i)
>> +		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
>> +
>> +	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
>> +	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
>> +	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
>> +	chunk_data.ib_data._pad = 0;
>> +	chunk_data.ib_data.va_start = ib_result_mc_address;
>> +	chunk_data.ib_data.ib_bytes = 16 * 4;
>> +	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
>> +	chunk_data.ib_data.ip_instance = 0;
>> +	chunk_data.ib_data.ring = 0;
>> +	chunk_data.ib_data.flags = 0;
>> +
>> +	chunks[1].chunk_id = wait_or_signal ?
>> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
>> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
>> +	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
>> +	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
>> +	syncobj_data.handle = syncobj_handle;
>> +	syncobj_data.point = point;
>> +	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
>> +
>> +	r = amdgpu_cs_submit_raw(device_handle,
>> +				 context_handle,
>> +				 bo_list,
>> +				 2,
>> +				 chunks,
>> +				 &seq_no);
>> +	igt_assert_eq(r, 0);
>> +
>> +	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
>> +	fence_status.context = context_handle;
>> +	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
>> +	fence_status.ip_instance = 0;
>> +	fence_status.ring = 0;
>> +	fence_status.fence = seq_no;
>> +
>> +	r = amdgpu_cs_query_fence_status(&fence_status,
>> +			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
>> +	igt_assert_eq(r, 0);
>> +
>> +	r = amdgpu_bo_list_destroy(bo_list);
>> +	igt_assert_eq(r, 0);
>> +
>> +	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
>> +				     ib_result_mc_address, 4096);
>> +
>> +	r = amdgpu_cs_ctx_free(context_handle);
>> +	igt_assert_eq(r, 0);
>> +}
>> +
>> +static void *
>> +syncobj_wait(void *data)
>> +{
>> +	struct syncobj_point *sp = (struct syncobj_point *)data;
>> +
>> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
>> +			sp->point);
>> +
>> +	return (void *)0;
>> +}
>> +
>> +static void *
>> +syncobj_signal(void *data)
>> +{
>> +	struct syncobj_point *sp = (struct syncobj_point *)data;
>> +
>> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
>> +			sp->point);
>> +
>> +	return (void *)0;
>> +}
>> +
>> +static void
>> +amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
>> +{
>> +	static pthread_t wait_thread;
>> +	static pthread_t signal_thread;
>> +	static pthread_t c_thread;
>> +	struct syncobj_point sp1, sp2, sp3;
>> +	uint32_t syncobj_handle;
>> +	uint64_t payload;
>> +	uint64_t wait_point, signal_point;
>> +	uint64_t timeout;
>> +	struct timespec tp;
>> +	int r, sync_fd;
>> +	void *tmp, *tmp2;
>> +
>> +	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
>> +	igt_assert_eq(r, 0);
>> +
>> +	// wait on point 5
>> +	sp1.syncobj_handle = syncobj_handle;
>> +	sp1.device = device_handle;
>> +	sp1.point = 5;
>> +	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
>> +	igt_assert_eq(r, 0);
>> +
>> +	// signal on point 10
>> +	sp2.syncobj_handle = syncobj_handle;
>> +	sp2.device = device_handle;
>> +	sp2.point = 10;
>> +	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
>> +	igt_assert_eq(r, 0);
>> +
>> +	r = pthread_join(signal_thread, &tmp);
>> +	igt_assert_eq(r, 0);
>> +
>> +	r = pthread_join(wait_thread, &tmp2);
>> +	igt_assert_eq(r, 0);
>> +
>> +	//query timeline payload
>> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
>> +				    &payload, 1);
>> +	igt_assert_eq(r, 0);
>> +	igt_assert_eq(payload, 10);
>> +
>> +	//signal on point 16
>> +	sp3.syncobj_handle = syncobj_handle;
>> +	sp3.device = device_handle;
>> +	sp3.point = 16;
>> +	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
>> +	igt_assert_eq(r, 0);
>> +
>> +	//CPU wait on point 16
>> +	wait_point = 16;
>> +	timeout = 0;
>> +	clock_gettime(CLOCK_MONOTONIC, &tp);
>> +	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
>> +	timeout += 10000000000; //10s
>> +	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
>> +					    &wait_point, 1, timeout,
>> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
>> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
>> +					    NULL);
>> +
>> +	igt_assert_eq(r, 0);
>> +	r = pthread_join(c_thread, &tmp);
>> +	igt_assert_eq(r, 0);
>> +
>> +	// export point 16 and import to point 18
>> +	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
>> +						16,
>> +						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
>> +						&sync_fd);
>> +	igt_assert_eq(r, 0);
>> +	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
>> +						18, sync_fd);
>> +	igt_assert_eq(r, 0);
>> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
>> +				    &payload, 1);
>> +	igt_assert_eq(r, 0);
>> +	igt_assert_eq(payload, 18);
>> +
>> +	// CPU signal on point 20
>> +	signal_point = 20;
>> +	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
>> +					      &signal_point, 1);
>> +	igt_assert_eq(r, 0);
>> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
>> +				    &payload, 1);
>> +	igt_assert_eq(r, 0);
>> +	igt_assert_eq(payload, 20);
>> +
>> +	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
>> +	igt_assert_eq(r, 0);
>> +
>> +}
>> +
>> +igt_main
>> +{
>> +	amdgpu_device_handle device;
>> +	int fd = -1;
>> +
>> +	igt_fixture {
>> +		uint32_t major, minor;
>> +		int err;
>> +
>> +		fd = drm_open_driver(DRIVER_AMDGPU);
>> +		err = amdgpu_device_initialize(fd, &major, &minor, &device);
>> +		igt_require(err == 0);
>> +		igt_require(syncobj_timeline_enable(fd));
>> +		igt_info("Initialized amdgpu, driver version %d.%d\n",
>> +			 major, minor);
>> +
>> +	}
>> +
>> +	igt_subtest("amdgpu_syncobj_timeline")
>> +	amdgpu_syncobj_timeline(device);
>> +
>> +	igt_fixture {
>> +		amdgpu_device_deinitialize(device);
>> +		close(fd);
>> +	}
>> +}
>> diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
>> index 43326a7c4..576d242c5 100644
>> --- a/tests/amdgpu/meson.build
>> +++ b/tests/amdgpu/meson.build
>> @@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
>>  			  'amd_assr',
>>  			  'amd_basic',
>>  			  'amd_bo',
>> +			  'amd_syncobj',
>>  			  'amd_bypass',
>>  			  'amd_deadlock',
>>  			  'amd_pci_unplug',
>> -- 
>> 2.25.1
>>

[-- Attachment #2: Type: text/html, Size: 12039 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-28 21:30     ` vitaly prosyak
@ 2023-06-30 16:14       ` Kamil Konieczny
  0 siblings, 0 replies; 12+ messages in thread
From: Kamil Konieczny @ 2023-06-30 16:14 UTC (permalink / raw)
  To: igt-dev
  Cc: alexander.deucher, michael.strawbridge, Vitaly Prosyak,
	christian.koenig

Hi Vitaly,

On 2023-06-28 at 17:30:28 -0400, vitaly prosyak wrote:
> Hi Kamil,
> 
> Yes, there is compilation error which looks like no include from  <amdgpu.h>.
> 
> I am not sure how i can reproduce the issue locally because it is just fine for my local Ubuntu machine and other systems on AMD CI ( Fedora, etc.)
> 
> Do you have any suggestions ? Should l i use  QEMO to emulate arm64?
> 
> The error is following  and these functions are regular methods for drmlib:
> 
> ./tests/amdgpu/amd_syncobj.c: In function ‘amdgpu_syncobj_timeline’:
> |
> ../tests/amdgpu/amd_syncobj.c:181:6: error: implicit declaration of function ‘amdgpu_cs_syncobj_query’; did you mean ‘amdgpu_cs_syncobj_wait’? [-Werror=implicit-function-declaration]
> |
> 
> |r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,|
> 
> |
> |
> 
> Thanks in advance
> 
> Vitaly
> 

You can use doker/podman image, go to CI link in error
(you can find it also on patchwork page with your patch),
mount path (I advise a copy) with your sources and try to
compile locally on your machine.

Regards,
Kamil

> 
> On 2023-06-28 17:10, Kamil Konieczny wrote:
> > Hi Vitaly,
> >
> > On 2023-06-15 at 18:39:36 -0400, vitaly.prosyak@amd.com wrote:
> >> From: Vitaly Prosyak <vitaly.prosyak@amd.com>
> >>
> >> Using worker thread to wait on point and then signal point on other thread.
> >> Another test uses a worker thread to signal point and wait on the main
> >> thread using amdgpu_cs_syncobj_timeline_wait.
> >>
> >> The command consists of two chunks :
> >> 1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
> >> 2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
> >>    or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
> >>    point number .
> >>
> >> v1->v2. Fixed style issues - Christian.
> >>         Fixed formatting issues - Kamil.
> >>
> >> Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
> >> Acked-by Christian Koenig <christian.koenig@amd.com>
> >> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> > Please look at GitLab warningm there were soem problems on other
> > archs like arm64:
> 
> 
> ||
> >
> > https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/910520
> >
> > Regards,
> > Kamil
> >
> >> ---
> >>  tests/amdgpu/amd_syncobj.c | 263 +++++++++++++++++++++++++++++++++++++
> >>  tests/amdgpu/meson.build   |   1 +
> >>  2 files changed, 264 insertions(+)
> >>  create mode 100644 tests/amdgpu/amd_syncobj.c
> >>
> >> diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
> >> new file mode 100644
> >> index 000000000..5fae8fd3e
> >> --- /dev/null
> >> +++ b/tests/amdgpu/amd_syncobj.c
> >> @@ -0,0 +1,263 @@
> >> +// SPDX-License-Identifier: MIT
> >> +// Copyright 2023 Advanced Micro Devices, Inc.
> >> +
> >> +#include <pthread.h>
> >> +#include <amdgpu.h>
> >> +#include <amdgpu_drm.h>
> >> +
> >> +#include "igt.h"
> >> +#include "lib/amdgpu/amd_PM4.h"
> >> +#include "lib/amdgpu/amd_sdma.h"
> >> +#include "lib/amdgpu/amd_memory.h"
> >> +
> >> +struct syncobj_point {
> >> +	amdgpu_device_handle device;
> >> +	uint32_t syncobj_handle;
> >> +	uint64_t point;
> >> +};
> >> +
> >> +
> >> +static bool
> >> +syncobj_timeline_enable(int fd)
> >> +{
> >> +	int r;
> >> +	bool ret = false;
> >> +	uint64_t cap = 0;
> >> +
> >> +	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
> >> +	if (r || cap == 0)
> >> +		return ret;
> >> +	ret = true;
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +static void
> >> +syncobj_command_submission_helper(amdgpu_device_handle device_handle,
> >> +		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
> >> +{
> >> +	amdgpu_context_handle context_handle;
> >> +	amdgpu_bo_handle ib_result_handle;
> >> +	void *ib_result_cpu;
> >> +	uint64_t ib_result_mc_address;
> >> +	struct drm_amdgpu_cs_chunk chunks[2];
> >> +	struct drm_amdgpu_cs_chunk_data chunk_data;
> >> +	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
> >> +	struct amdgpu_cs_fence fence_status;
> >> +	amdgpu_bo_list_handle bo_list;
> >> +	amdgpu_va_handle va_handle;
> >> +	uint32_t expired;
> >> +	int i, r;
> >> +	uint64_t seq_no;
> >> +	uint32_t *ptr;
> >> +
> >> +	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
> >> +				    AMDGPU_GEM_DOMAIN_GTT, 0,
> >> +				    &ib_result_handle, &ib_result_cpu,
> >> +				    &ib_result_mc_address, &va_handle);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	ptr = ib_result_cpu;
> >> +
> >> +	for (i = 0; i < 16; ++i)
> >> +		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
> >> +
> >> +	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
> >> +	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
> >> +	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
> >> +	chunk_data.ib_data._pad = 0;
> >> +	chunk_data.ib_data.va_start = ib_result_mc_address;
> >> +	chunk_data.ib_data.ib_bytes = 16 * 4;
> >> +	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
> >> +	chunk_data.ib_data.ip_instance = 0;
> >> +	chunk_data.ib_data.ring = 0;
> >> +	chunk_data.ib_data.flags = 0;
> >> +
> >> +	chunks[1].chunk_id = wait_or_signal ?
> >> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
> >> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
> >> +	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
> >> +	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
> >> +	syncobj_data.handle = syncobj_handle;
> >> +	syncobj_data.point = point;
> >> +	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
> >> +
> >> +	r = amdgpu_cs_submit_raw(device_handle,
> >> +				 context_handle,
> >> +				 bo_list,
> >> +				 2,
> >> +				 chunks,
> >> +				 &seq_no);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
> >> +	fence_status.context = context_handle;
> >> +	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
> >> +	fence_status.ip_instance = 0;
> >> +	fence_status.ring = 0;
> >> +	fence_status.fence = seq_no;
> >> +
> >> +	r = amdgpu_cs_query_fence_status(&fence_status,
> >> +			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	r = amdgpu_bo_list_destroy(bo_list);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
> >> +				     ib_result_mc_address, 4096);
> >> +
> >> +	r = amdgpu_cs_ctx_free(context_handle);
> >> +	igt_assert_eq(r, 0);
> >> +}
> >> +
> >> +static void *
> >> +syncobj_wait(void *data)
> >> +{
> >> +	struct syncobj_point *sp = (struct syncobj_point *)data;
> >> +
> >> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
> >> +			sp->point);
> >> +
> >> +	return (void *)0;
> >> +}
> >> +
> >> +static void *
> >> +syncobj_signal(void *data)
> >> +{
> >> +	struct syncobj_point *sp = (struct syncobj_point *)data;
> >> +
> >> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
> >> +			sp->point);
> >> +
> >> +	return (void *)0;
> >> +}
> >> +
> >> +static void
> >> +amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
> >> +{
> >> +	static pthread_t wait_thread;
> >> +	static pthread_t signal_thread;
> >> +	static pthread_t c_thread;
> >> +	struct syncobj_point sp1, sp2, sp3;
> >> +	uint32_t syncobj_handle;
> >> +	uint64_t payload;
> >> +	uint64_t wait_point, signal_point;
> >> +	uint64_t timeout;
> >> +	struct timespec tp;
> >> +	int r, sync_fd;
> >> +	void *tmp, *tmp2;
> >> +
> >> +	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	// wait on point 5
> >> +	sp1.syncobj_handle = syncobj_handle;
> >> +	sp1.device = device_handle;
> >> +	sp1.point = 5;
> >> +	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	// signal on point 10
> >> +	sp2.syncobj_handle = syncobj_handle;
> >> +	sp2.device = device_handle;
> >> +	sp2.point = 10;
> >> +	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	r = pthread_join(signal_thread, &tmp);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	r = pthread_join(wait_thread, &tmp2);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	//query timeline payload
> >> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> >> +				    &payload, 1);
> >> +	igt_assert_eq(r, 0);
> >> +	igt_assert_eq(payload, 10);
> >> +
> >> +	//signal on point 16
> >> +	sp3.syncobj_handle = syncobj_handle;
> >> +	sp3.device = device_handle;
> >> +	sp3.point = 16;
> >> +	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	//CPU wait on point 16
> >> +	wait_point = 16;
> >> +	timeout = 0;
> >> +	clock_gettime(CLOCK_MONOTONIC, &tp);
> >> +	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
> >> +	timeout += 10000000000; //10s
> >> +	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
> >> +					    &wait_point, 1, timeout,
> >> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
> >> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> >> +					    NULL);
> >> +
> >> +	igt_assert_eq(r, 0);
> >> +	r = pthread_join(c_thread, &tmp);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +	// export point 16 and import to point 18
> >> +	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
> >> +						16,
> >> +						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> >> +						&sync_fd);
> >> +	igt_assert_eq(r, 0);
> >> +	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
> >> +						18, sync_fd);
> >> +	igt_assert_eq(r, 0);
> >> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> >> +				    &payload, 1);
> >> +	igt_assert_eq(r, 0);
> >> +	igt_assert_eq(payload, 18);
> >> +
> >> +	// CPU signal on point 20
> >> +	signal_point = 20;
> >> +	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
> >> +					      &signal_point, 1);
> >> +	igt_assert_eq(r, 0);
> >> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> >> +				    &payload, 1);
> >> +	igt_assert_eq(r, 0);
> >> +	igt_assert_eq(payload, 20);
> >> +
> >> +	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
> >> +	igt_assert_eq(r, 0);
> >> +
> >> +}
> >> +
> >> +igt_main
> >> +{
> >> +	amdgpu_device_handle device;
> >> +	int fd = -1;
> >> +
> >> +	igt_fixture {
> >> +		uint32_t major, minor;
> >> +		int err;
> >> +
> >> +		fd = drm_open_driver(DRIVER_AMDGPU);
> >> +		err = amdgpu_device_initialize(fd, &major, &minor, &device);
> >> +		igt_require(err == 0);
> >> +		igt_require(syncobj_timeline_enable(fd));
> >> +		igt_info("Initialized amdgpu, driver version %d.%d\n",
> >> +			 major, minor);
> >> +
> >> +	}
> >> +
> >> +	igt_subtest("amdgpu_syncobj_timeline")
> >> +	amdgpu_syncobj_timeline(device);
> >> +
> >> +	igt_fixture {
> >> +		amdgpu_device_deinitialize(device);
> >> +		close(fd);
> >> +	}
> >> +}
> >> diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
> >> index 43326a7c4..576d242c5 100644
> >> --- a/tests/amdgpu/meson.build
> >> +++ b/tests/amdgpu/meson.build
> >> @@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
> >>  			  'amd_assr',
> >>  			  'amd_basic',
> >>  			  'amd_bo',
> >> +			  'amd_syncobj',
> >>  			  'amd_bypass',
> >>  			  'amd_deadlock',
> >>  			  'amd_pci_unplug',
> >> -- 
> >> 2.25.1
> >>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests
  2023-06-15 22:39 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
  2023-06-28 21:10   ` Kamil Konieczny
@ 2023-06-30 16:28   ` Kamil Konieczny
  1 sibling, 0 replies; 12+ messages in thread
From: Kamil Konieczny @ 2023-06-30 16:28 UTC (permalink / raw)
  Cc: igt-dev, alexander.deucher, michael.strawbridge, christian.koenig

Hi Vitaly,

small nits, see below.

On 2023-06-15 at 18:39:36 -0400, vitaly.prosyak@amd.com wrote:
> From: Vitaly Prosyak <vitaly.prosyak@amd.com>
> 
> Using worker thread to wait on point and then signal point on other thread.
> Another test uses a worker thread to signal point and wait on the main
> thread using amdgpu_cs_syncobj_timeline_wait.
> 
> The command consists of two chunks :
> 1. AMDGPU_CHUNK_ID_IB uses GFX_COMPUTE_NOP  or SDMA_NOP.
> 2. The second chunk is AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT
>    or AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL which has the
>    point number .
> 
> v1->v2. Fixed style issues - Christian.
>         Fixed formatting issues - Kamil.
> 
> Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
> Acked-by Christian Koenig <christian.koenig@amd.com>
--------- ^
Missed ':', should be

Acked-by: Christian Koenig <christian.koenig@amd.com>

> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> ---
>  tests/amdgpu/amd_syncobj.c | 263 +++++++++++++++++++++++++++++++++++++
>  tests/amdgpu/meson.build   |   1 +
>  2 files changed, 264 insertions(+)
>  create mode 100644 tests/amdgpu/amd_syncobj.c
> 
> diff --git a/tests/amdgpu/amd_syncobj.c b/tests/amdgpu/amd_syncobj.c
> new file mode 100644
> index 000000000..5fae8fd3e
> --- /dev/null
> +++ b/tests/amdgpu/amd_syncobj.c
> @@ -0,0 +1,263 @@
> +// SPDX-License-Identifier: MIT
> +// Copyright 2023 Advanced Micro Devices, Inc.

Use checkpatch.pl for verify. It is better to have:
/*
 * Copyright 2023 Advanced Micro Devices, Inc.
 */

because you can later easily extend this.

> +
> +#include <pthread.h>

Add newline here if you want to have system libs before amdgpu.

> +#include <amdgpu.h>
> +#include <amdgpu_drm.h>
> +
> +#include "igt.h"
> +#include "lib/amdgpu/amd_PM4.h"
> +#include "lib/amdgpu/amd_sdma.h"
> +#include "lib/amdgpu/amd_memory.h"
> +
> +struct syncobj_point {
> +	amdgpu_device_handle device;
> +	uint32_t syncobj_handle;
> +	uint64_t point;
> +};
> +
> +
> +static bool
> +syncobj_timeline_enable(int fd)
> +{
> +	int r;
> +	bool ret = false;
> +	uint64_t cap = 0;
> +
> +	r = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
> +	if (r || cap == 0)
> +		return ret;
> +	ret = true;
> +
> +	return ret;
> +}
> +
> +static void
> +syncobj_command_submission_helper(amdgpu_device_handle device_handle,
> +		uint32_t syncobj_handle, bool wait_or_signal, uint64_t point)
> +{
> +	amdgpu_context_handle context_handle;
> +	amdgpu_bo_handle ib_result_handle;
> +	void *ib_result_cpu;
> +	uint64_t ib_result_mc_address;
> +	struct drm_amdgpu_cs_chunk chunks[2];
> +	struct drm_amdgpu_cs_chunk_data chunk_data;
> +	struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
> +	struct amdgpu_cs_fence fence_status;
> +	amdgpu_bo_list_handle bo_list;
> +	amdgpu_va_handle va_handle;
> +	uint32_t expired;
> +	int i, r;
> +	uint64_t seq_no;
> +	uint32_t *ptr;
> +
> +	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
> +	igt_assert_eq(r, 0);
> +
> +	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
> +				    AMDGPU_GEM_DOMAIN_GTT, 0,
> +				    &ib_result_handle, &ib_result_cpu,
> +				    &ib_result_mc_address, &va_handle);
> +	igt_assert_eq(r, 0);
> +
> +	r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL, &bo_list);
> +	igt_assert_eq(r, 0);
> +
> +	ptr = ib_result_cpu;
> +
> +	for (i = 0; i < 16; ++i)
> +		ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP : SDMA_NOP;
> +
> +	chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
> +	chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
> +	chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
> +	chunk_data.ib_data._pad = 0;
> +	chunk_data.ib_data.va_start = ib_result_mc_address;
> +	chunk_data.ib_data.ib_bytes = 16 * 4;
> +	chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
> +	chunk_data.ib_data.ip_instance = 0;
> +	chunk_data.ib_data.ring = 0;
> +	chunk_data.ib_data.flags = 0;
> +
> +	chunks[1].chunk_id = wait_or_signal ?
> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
> +		AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
> +	chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
> +	chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
> +	syncobj_data.handle = syncobj_handle;
> +	syncobj_data.point = point;
> +	syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
> +
> +	r = amdgpu_cs_submit_raw(device_handle,
> +				 context_handle,
> +				 bo_list,
> +				 2,
> +				 chunks,
> +				 &seq_no);
> +	igt_assert_eq(r, 0);
> +
> +	memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
> +	fence_status.context = context_handle;
> +	fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX : AMDGPU_HW_IP_DMA;
> +	fence_status.ip_instance = 0;
> +	fence_status.ring = 0;
> +	fence_status.fence = seq_no;
> +
> +	r = amdgpu_cs_query_fence_status(&fence_status,
> +			AMDGPU_TIMEOUT_INFINITE, 0, &expired);
> +	igt_assert_eq(r, 0);
> +
> +	r = amdgpu_bo_list_destroy(bo_list);
> +	igt_assert_eq(r, 0);
> +
> +	amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
> +				     ib_result_mc_address, 4096);
> +
> +	r = amdgpu_cs_ctx_free(context_handle);
> +	igt_assert_eq(r, 0);
> +}
> +
> +static void *
> +syncobj_wait(void *data)
> +{
> +	struct syncobj_point *sp = (struct syncobj_point *)data;
> +
> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, true,
> +			sp->point);
> +
> +	return (void *)0;
> +}
> +
> +static void *
> +syncobj_signal(void *data)
> +{
> +	struct syncobj_point *sp = (struct syncobj_point *)data;
> +
> +	syncobj_command_submission_helper(sp->device, sp->syncobj_handle, false,
> +			sp->point);
> +
> +	return (void *)0;
> +}
> +
> +static void
> +amdgpu_syncobj_timeline(amdgpu_device_handle device_handle)
> +{
> +	static pthread_t wait_thread;
> +	static pthread_t signal_thread;
> +	static pthread_t c_thread;
> +	struct syncobj_point sp1, sp2, sp3;
> +	uint32_t syncobj_handle;
> +	uint64_t payload;
> +	uint64_t wait_point, signal_point;
> +	uint64_t timeout;
> +	struct timespec tp;
> +	int r, sync_fd;
> +	void *tmp, *tmp2;
> +
> +	r =  amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
> +	igt_assert_eq(r, 0);
> +
> +	// wait on point 5
> +	sp1.syncobj_handle = syncobj_handle;
> +	sp1.device = device_handle;
> +	sp1.point = 5;
> +	r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
> +	igt_assert_eq(r, 0);
> +
> +	// signal on point 10
> +	sp2.syncobj_handle = syncobj_handle;
> +	sp2.device = device_handle;
> +	sp2.point = 10;
> +	r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
> +	igt_assert_eq(r, 0);
> +
> +	r = pthread_join(signal_thread, &tmp);
> +	igt_assert_eq(r, 0);
> +
> +	r = pthread_join(wait_thread, &tmp2);
> +	igt_assert_eq(r, 0);
> +
> +	//query timeline payload
> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> +				    &payload, 1);
> +	igt_assert_eq(r, 0);
> +	igt_assert_eq(payload, 10);
> +
> +	//signal on point 16
> +	sp3.syncobj_handle = syncobj_handle;
> +	sp3.device = device_handle;
> +	sp3.point = 16;
> +	r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
> +	igt_assert_eq(r, 0);
> +
> +	//CPU wait on point 16
> +	wait_point = 16;
> +	timeout = 0;
> +	clock_gettime(CLOCK_MONOTONIC, &tp);
> +	timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
> +	timeout += 10000000000; //10s
> +	r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
> +					    &wait_point, 1, timeout,
> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
> +					    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +					    NULL);
> +
> +	igt_assert_eq(r, 0);
> +	r = pthread_join(c_thread, &tmp);
> +	igt_assert_eq(r, 0);
> +
> +	// export point 16 and import to point 18
> +	r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
> +						16,
> +						DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +						&sync_fd);
> +	igt_assert_eq(r, 0);
> +	r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
> +						18, sync_fd);
> +	igt_assert_eq(r, 0);
> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> +				    &payload, 1);
> +	igt_assert_eq(r, 0);
> +	igt_assert_eq(payload, 18);
> +
> +	// CPU signal on point 20
> +	signal_point = 20;
> +	r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
> +					      &signal_point, 1);
> +	igt_assert_eq(r, 0);
> +	r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
> +				    &payload, 1);
> +	igt_assert_eq(r, 0);
> +	igt_assert_eq(payload, 20);
> +
> +	r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
> +	igt_assert_eq(r, 0);
> +
> +}
> +
> +igt_main
> +{
> +	amdgpu_device_handle device;
> +	int fd = -1;
> +
> +	igt_fixture {
> +		uint32_t major, minor;
> +		int err;
> +
> +		fd = drm_open_driver(DRIVER_AMDGPU);
> +		err = amdgpu_device_initialize(fd, &major, &minor, &device);
> +		igt_require(err == 0);
> +		igt_require(syncobj_timeline_enable(fd));
> +		igt_info("Initialized amdgpu, driver version %d.%d\n",
> +			 major, minor);
> +
> +	}
> +
> +	igt_subtest("amdgpu_syncobj_timeline")
> +	amdgpu_syncobj_timeline(device);
> +
> +	igt_fixture {
> +		amdgpu_device_deinitialize(device);
> +		close(fd);
> +	}
> +}
> diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
> index 43326a7c4..576d242c5 100644
> --- a/tests/amdgpu/meson.build
> +++ b/tests/amdgpu/meson.build
> @@ -6,6 +6,7 @@ if libdrm_amdgpu.found()
>  			  'amd_assr',
>  			  'amd_basic',
>  			  'amd_bo',
> +			  'amd_syncobj',

Consider sending separate patch which will sort this alphabetically.

Regards,
Kamil

>  			  'amd_bypass',
>  			  'amd_deadlock',
>  			  'amd_pci_unplug',
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-06-30 16:28 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-15 22:39 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
2023-06-15 22:39 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
2023-06-28 21:10   ` Kamil Konieczny
2023-06-28 21:30     ` vitaly prosyak
2023-06-30 16:14       ` Kamil Konieczny
2023-06-30 16:28   ` Kamil Konieczny
2023-06-16  0:27 ` [igt-dev] ✗ GitLab.Pipeline: warning for series starting with [1/2] tests/amdgpu: add bo tests Patchwork
2023-06-16  0:49 ` [igt-dev] ✗ Fi.CI.BAT: failure " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2023-06-21  0:39 [igt-dev] [PATCH 1/2] " vitaly.prosyak
2023-06-21  0:39 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
2023-06-19 20:37 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
2023-06-19 20:38 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
2023-06-15  2:14 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
2023-06-15  2:14 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak
2023-06-15  2:12 [igt-dev] [PATCH 1/2] tests/amdgpu: add bo tests vitaly.prosyak
2023-06-15  2:12 ` [igt-dev] [PATCH 2/2] tests/amdgpu: add sync object tests vitaly.prosyak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox