anv/sparse: leave the semaphore waits and signals to the vm_bind ioctl

We can now finally leave the semaphore waits and signals to the
vm_bind ioctl, making vm_bind operations truly asynchronous.

This was previously done for TR-TT in 18bd00c024 ("anv/trtt: don't
wait/signal syncobjs using the CPU anymore").

Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27926>
This commit is contained in:
Paulo Zanoni
2024-02-28 16:48:18 -08:00
committed by Marge Bot
parent aa07d8a04c
commit 8051919b3c
2 changed files with 49 additions and 25 deletions
-18
View File
@@ -609,32 +609,14 @@ anv_sparse_bind_vm_bind(struct anv_device *device,
struct anv_sparse_submission *submit)
{
struct anv_queue *queue = submit->queue;
VkResult result;
if (!queue)
assert(submit->wait_count == 0 && submit->signal_count == 0);
/* TODO: make both the syncs and signals be passed as part of the vm_bind
* ioctl so they can be waited asynchronously. For now this doesn't matter
* as we're doing synchronous vm_bind, but later when we make it async this
* will make a difference.
*/
result = vk_sync_wait_many(&device->vk, submit->wait_count, submit->waits,
VK_SYNC_WAIT_COMPLETE, INT64_MAX);
if (result != VK_SUCCESS)
return vk_queue_set_lost(&queue->vk, "vk_sync_wait failed");
int rc = device->kmd_backend->vm_bind(device, submit);
if (rc)
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
for (uint32_t i = 0; i < submit->signal_count; i++) {
struct vk_sync_signal *s = &submit->signals[i];
result = vk_sync_signal(&device->vk, s->sync, s->signal_value);
if (result != VK_SUCCESS)
return vk_queue_set_lost(&queue->vk, "vk_sync_signal failed");
}
return VK_SUCCESS;
}
+49 -7
View File
@@ -126,17 +126,54 @@ static inline int
xe_vm_bind_op(struct anv_device *device,
struct anv_sparse_submission *submit)
{
struct drm_xe_sync xe_sync = {
.handle = intel_bind_timeline_get_syncobj(&device->bind_timeline),
int num_syncs = submit->wait_count + submit->signal_count + 1;
STACK_ARRAY(struct drm_xe_sync, xe_syncs, num_syncs);
if (!xe_syncs)
return -ENOMEM;
int sync_idx = 0;
for (int s = 0; s < submit->wait_count; s++) {
const struct vk_drm_syncobj *syncobj =
vk_sync_as_drm_syncobj(submit->waits[s].sync);
assert(syncobj);
uint64_t val = submit->waits[s].wait_value;
xe_syncs[sync_idx++] = (struct drm_xe_sync) {
.type = val ? DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ :
DRM_XE_SYNC_TYPE_SYNCOBJ,
.flags = 0,
.handle = syncobj->syncobj,
.timeline_value = val,
};
}
for (int s = 0; s < submit->signal_count; s++) {
const struct vk_drm_syncobj *syncobj =
vk_sync_as_drm_syncobj(submit->signals[s].sync);
assert(syncobj);
uint64_t val = submit->signals[s].signal_value;
xe_syncs[sync_idx++] = (struct drm_xe_sync) {
.type = val ? DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ :
DRM_XE_SYNC_TYPE_SYNCOBJ,
.flags = DRM_XE_SYNC_FLAG_SIGNAL,
.handle = syncobj->syncobj,
.timeline_value = val,
};
}
xe_syncs[sync_idx++] = (struct drm_xe_sync) {
.type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ,
.flags = DRM_XE_SYNC_FLAG_SIGNAL,
.handle = intel_bind_timeline_get_syncobj(&device->bind_timeline),
/* .timeline_value will be set later. */
};
assert(sync_idx == num_syncs);
struct drm_xe_vm_bind args = {
.vm_id = device->vm_id,
.num_binds = submit->binds_len,
.bind = {},
.num_syncs = 1,
.syncs = (uintptr_t)&xe_sync,
.num_syncs = num_syncs,
.syncs = (uintptr_t)xe_syncs,
};
int ret;
@@ -144,8 +181,10 @@ xe_vm_bind_op(struct anv_device *device,
submit->binds_len);
struct drm_xe_vm_bind_op *xe_binds;
if (submit->binds_len > 1) {
if (!xe_binds_stackarray)
return -ENOMEM;
if (!xe_binds_stackarray) {
ret = -ENOMEM;
goto out_syncs;
}
xe_binds = xe_binds_stackarray;
args.vector_of_binds = (uintptr_t)xe_binds;
@@ -198,7 +237,8 @@ xe_vm_bind_op(struct anv_device *device,
xe_bind->userptr = (uintptr_t)bo->map;
}
xe_sync.timeline_value = intel_bind_timeline_bind_begin(&device->bind_timeline);
xe_syncs[num_syncs - 1].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);
@@ -209,6 +249,8 @@ xe_vm_bind_op(struct anv_device *device,
out_stackarray:
STACK_ARRAY_FINISH(xe_binds_stackarray);
out_syncs:
STACK_ARRAY_FINISH(xe_syncs);
return ret;
}