anv: Start to use intel_bind_timeline

With this patch, VM binds remain synchronous in relation to vm_bind()
KMD backend calls. However, the syscalls required for VM bind is
reduce in 2(in the optimal cases), the syncobj create and destroy
syscall are replaced by he usage a timeline syncobj.

Next step will be make this completely asynchronous.

Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26805>
This commit is contained in:
José Roberto de Souza 2023-12-22 10:29:34 -08:00 committed by Marge Bot
parent e905bfe81b
commit f23395e2b9
3 changed files with 23 additions and 15 deletions

View file

@ -41,6 +41,7 @@
#endif
#include "common/intel_aux_map.h"
#include "common/intel_bind_timeline.h"
#include "common/intel_decoder.h"
#include "common/intel_engine.h"
#include "common/intel_gem.h"
@ -1873,6 +1874,8 @@ struct anv_device {
bool using_sparse;
struct anv_device_astc_emu astc_emu;
struct intel_bind_timeline bind_timeline; /* Xe only */
};
static inline uint32_t

View file

@ -33,6 +33,9 @@ bool anv_xe_device_destroy_vm(struct anv_device *device)
struct drm_xe_vm_destroy destroy = {
.vm_id = device->vm_id,
};
intel_bind_timeline_finish(&device->bind_timeline, device->fd);
return intel_ioctl(device->fd, DRM_IOCTL_XE_VM_DESTROY, &destroy) == 0;
}
@ -46,6 +49,13 @@ VkResult anv_xe_device_setup_vm(struct anv_device *device)
"vm creation failed");
device->vm_id = create.vm_id;
if (!intel_bind_timeline_init(&device->bind_timeline, device->fd)) {
anv_xe_device_destroy_vm(device);
return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED,
"intel_bind_timeline_init failed");
}
return VK_SUCCESS;
}

View file

@ -116,7 +116,8 @@ xe_vm_bind_op(struct anv_device *device,
struct anv_sparse_submission *submit)
{
struct drm_xe_sync xe_sync = {
.type = DRM_XE_SYNC_TYPE_SYNCOBJ,
.handle = intel_bind_timeline_get_syncobj(&device->bind_timeline),
.type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ,
.flags = DRM_XE_SYNC_FLAG_SIGNAL,
};
struct drm_xe_vm_bind args = {
@ -126,10 +127,9 @@ xe_vm_bind_op(struct anv_device *device,
.num_syncs = 1,
.syncs = (uintptr_t)&xe_sync,
};
struct drm_syncobj_create syncobj_create = {};
struct drm_syncobj_destroy syncobj_destroy = {};
struct drm_syncobj_wait syncobj_wait = {
struct drm_syncobj_timeline_wait syncobj_wait = {
.timeout_nsec = INT64_MAX,
.handles = (uintptr_t)&xe_sync.handle,
.count_handles = 1,
};
int ret;
@ -183,23 +183,18 @@ xe_vm_bind_op(struct anv_device *device,
xe_bind->userptr = (uintptr_t)bo->map;
}
ret = intel_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create);
xe_sync.timeline_value = intel_bind_timeline_bind_begin(&device->bind_timeline);
ret = intel_ioctl(device->fd, DRM_IOCTL_XE_VM_BIND, &args);
intel_bind_timeline_bind_end(&device->bind_timeline);
if (ret)
goto out_stackarray;
xe_sync.handle = syncobj_create.handle;
ret = intel_ioctl(device->fd, DRM_IOCTL_XE_VM_BIND, &args);
if (ret)
goto out_destroy_syncobj;
ANV_RMV(vm_binds, device, submit->binds, submit->binds_len);
syncobj_wait.handles = (uintptr_t)&xe_sync.handle;
ret = intel_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_WAIT, &syncobj_wait);
syncobj_wait.points = (uintptr_t)&xe_sync.timeline_value;
ret = intel_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &syncobj_wait);
out_destroy_syncobj:
syncobj_destroy.handle = xe_sync.handle;
intel_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy);
out_stackarray:
STACK_ARRAY_FINISH(xe_binds_stackarray);