intel: Split anv_xe_wait_exec_queue_idle() and move part of it to common/
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 <paulo.r.zanoni@intel.com> Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30958>
This commit is contained in:
committed by
Marge Bot
parent
b01d76027d
commit
2f7c9f906d
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2024 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int xe_queue_get_syncobj_for_idle(int fd, uint32_t exec_queue_id, uint32_t *syncobj);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user