* [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