From 2f7c9f906d7205e0fe8a725a90891c2ebfcc9a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Thu, 15 Aug 2024 14:02:32 -0700 Subject: [PATCH] intel: Split anv_xe_wait_exec_queue_idle() and move part of it to common/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split anv_xe_wait_exec_queue_idle() into 2 functions, the first function creates the syncobj and prepares it to be signaled when the last workload in queue is completed. And the second one that calls the first function, then waits for the syncobj to be signaled and destroy the syncobj. The main reason for that is that the first function can be reused in Iris and a future patch will add another user, so lets share it. No changes in behavior are expected here. Reviewed-by: Paulo Zanoni Signed-off-by: José Roberto de Souza Part-of: --- src/intel/common/meson.build | 2 ++ src/intel/common/xe/intel_queue.c | 57 +++++++++++++++++++++++++++++++ src/intel/common/xe/intel_queue.h | 10 ++++++ src/intel/vulkan/xe/anv_queue.c | 44 ++++++------------------ 4 files changed, 80 insertions(+), 33 deletions(-) create mode 100644 src/intel/common/xe/intel_queue.c create mode 100644 src/intel/common/xe/intel_queue.h diff --git a/src/intel/common/meson.build b/src/intel/common/meson.build index 3e92d9d2864..4050c527df6 100644 --- a/src/intel/common/meson.build +++ b/src/intel/common/meson.build @@ -14,6 +14,8 @@ files_libintel_common = files( 'xe/intel_engine.h', 'xe/intel_gem.c', 'xe/intel_gem.h', + 'xe/intel_queue.c', + 'xe/intel_queue.h', 'intel_aux_map.c', 'intel_aux_map.h', 'intel_bind_timeline.c', diff --git a/src/intel/common/xe/intel_queue.c b/src/intel/common/xe/intel_queue.c new file mode 100644 index 00000000000..b535f75da12 --- /dev/null +++ b/src/intel/common/xe/intel_queue.c @@ -0,0 +1,57 @@ +/* + * Copyright 2024 Intel Corporation + * SPDX-License-Identifier: MIT + */ + +#include "xe/intel_queue.h" + +#include "common/intel_gem.h" + +#include "drm-uapi/xe_drm.h" + +/* Creates a syncobj that will be signaled when all the workloads in given + * exec_queue_id are completed. + * Syncobj set must be destroyed by caller. + */ +int +xe_queue_get_syncobj_for_idle(int fd, uint32_t exec_queue_id, uint32_t *syncobj) +{ + struct drm_syncobj_create syncobj_create = {}; + struct drm_xe_sync xe_sync = { + .type = DRM_XE_SYNC_TYPE_SYNCOBJ, + .flags = DRM_XE_SYNC_FLAG_SIGNAL, + }; + struct drm_xe_exec exec = { + .exec_queue_id = exec_queue_id, + .num_syncs = 1, + .syncs = (uintptr_t)&xe_sync, + .num_batch_buffer = 0, + }; + struct drm_syncobj_destroy syncobj_destroy = {}; + int ret = intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create); + + if (ret) + return -errno; + + xe_sync.handle = syncobj_create.handle; + /* Using the special exec.num_batch_buffer == 0 handling to get syncobj + * signaled when the last DRM_IOCTL_XE_EXEC is completed. + */ + ret = intel_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec); + if (ret) { + /* exec_queue could have been banned, that is why it is being destroyed + * so no assert() here + */ + ret = -errno; + goto error_exec; + } + + *syncobj = syncobj_create.handle; + return 0; + +error_exec: + syncobj_destroy.handle = syncobj_create.handle, + intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy); + + return ret; +} diff --git a/src/intel/common/xe/intel_queue.h b/src/intel/common/xe/intel_queue.h new file mode 100644 index 00000000000..42d128db446 --- /dev/null +++ b/src/intel/common/xe/intel_queue.h @@ -0,0 +1,10 @@ +/* + * Copyright 2024 Intel Corporation + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include + +int xe_queue_get_syncobj_for_idle(int fd, uint32_t exec_queue_id, uint32_t *syncobj); diff --git a/src/intel/vulkan/xe/anv_queue.c b/src/intel/vulkan/xe/anv_queue.c index fc6a6dc8bf7..63e4a4d7f3f 100644 --- a/src/intel/vulkan/xe/anv_queue.c +++ b/src/intel/vulkan/xe/anv_queue.c @@ -25,6 +25,7 @@ #include "anv_private.h" #include "common/xe/intel_engine.h" +#include "common/xe/intel_queue.h" #include "common/intel_gem.h" #include "xe/anv_device.h" @@ -152,49 +153,26 @@ anv_xe_create_engine(struct anv_device *device, static void anv_xe_wait_exec_queue_idle(struct anv_device *device, uint32_t exec_queue_id) { - struct drm_syncobj_create syncobj_create = {}; - struct drm_xe_sync xe_sync = { - .type = DRM_XE_SYNC_TYPE_SYNCOBJ, - .flags = DRM_XE_SYNC_FLAG_SIGNAL, - }; - struct drm_xe_exec exec = { - .exec_queue_id = exec_queue_id, - .num_syncs = 1, - .syncs = (uintptr_t)&xe_sync, - .num_batch_buffer = 0, - }; - struct drm_syncobj_destroy syncobj_destroy = {}; struct drm_syncobj_wait syncobj_wait = { .count_handles = 1, .timeout_nsec = INT64_MAX, }; - int fd = device->fd; - int ret; + uint32_t syncobj; + int ret = xe_queue_get_syncobj_for_idle(device->fd, exec_queue_id, &syncobj); - ret = intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create); - assert(ret == 0); - if (ret) - return; - - xe_sync.handle = syncobj_create.handle; - /* Using the special exec.num_batch_buffer == 0 handling to get syncobj - * signaled when the last DRM_IOCTL_XE_EXEC is completed. - */ - ret = intel_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec); if (ret) { - /* exec_queue could have been banned, that is why it is being destroyed - * so no assert() here - */ - goto error_exec; + assert(ret == -ECANCELED); + return; } - syncobj_wait.handles = (uintptr_t)&syncobj_create.handle; - ret = intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &syncobj_wait); + syncobj_wait.handles = (uintptr_t)&syncobj; + ret = intel_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_WAIT, &syncobj_wait); assert(ret == 0); -error_exec: - syncobj_destroy.handle = syncobj_create.handle; - ret = intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy); + struct drm_syncobj_destroy syncobj_destroy = { + .handle = syncobj, + }; + ret = intel_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy); assert(ret == 0); }