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); }