<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Kamil,</p>
    <p>Yes, there is compilation error which looks like no include from 
      <amdgpu.h>.<br>
    </p>
    <p>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.)<br>
    </p>
    <p>Do you have any suggestions ? Should l i use  QEMO to emulate
      arm64?<br>
    </p>
    <p>The error is following  and these functions are regular methods
      for drmlib:<br>
    </p>
    <div class="js-line log-line"><span class="gl-white-space-pre-wrap">./tests/amdgpu/amd_syncobj.c:
        In function ‘amdgpu_syncobj_timeline’:</span></div>
    <div class="js-line log-line"></div>
    <code data-qa-selector="job_log_content" class="job-log d-block">
      <div class="js-line log-line"><span class="gl-white-space-pre-wrap">../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]</span></div>
      <div class="js-line log-line"></div>
    </code>
    <p><code data-qa-selector="job_log_content" class="job-log d-block"><span class="gl-white-space-pre-wrap"> r =
          amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,</span></code></p>
    <p><code data-qa-selector="job_log_content" class="job-log d-block"><span class="gl-white-space-pre-wrap"><br>
        </span></code></p>
    <p></p>
    <p>Thanks in advance</p>
    <p>Vitaly<br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 2023-06-28 17:10, Kamil Konieczny
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:20230628211037.b3xdenrwqg33mfwr@kamilkon-desk1">
      <pre class="moz-quote-pre" wrap="">Hi Vitaly,

On 2023-06-15 at 18:39:36 -0400, <a class="moz-txt-link-abbreviated" href="mailto:vitaly.prosyak@amd.com">vitaly.prosyak@amd.com</a> wrote:
</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">From: Vitaly Prosyak <a class="moz-txt-link-rfc2396E" href="mailto:vitaly.prosyak@amd.com"><vitaly.prosyak@amd.com></a>

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 <a class="moz-txt-link-rfc2396E" href="mailto:vitaly.prosyak@amd.com"><vitaly.prosyak@amd.com></a>
Acked-by Christian Koenig <a class="moz-txt-link-rfc2396E" href="mailto:christian.koenig@amd.com"><christian.koenig@amd.com></a>
Cc: Kamil Konieczny <a class="moz-txt-link-rfc2396E" href="mailto:kamil.konieczny@linux.intel.com"><kamil.konieczny@linux.intel.com></a>
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
Please look at GitLab warningm there were soem problems on other
archs like arm64:</pre>
    </blockquote>
    <br>
    <br>
    <code data-qa-selector="job_log_content" class="job-log d-block"><span class="gl-white-space-pre-wrap"></span></code>
    <blockquote type="cite" cite="mid:20230628211037.b3xdenrwqg33mfwr@kamilkon-desk1">
      <pre class="moz-quote-pre" wrap="">

<a class="moz-txt-link-freetext" href="https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/910520">https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/910520</a>

Regards,
Kamil

</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">---
 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

</pre>
      </blockquote>
    </blockquote>
  </body>
</html>