From 41f1e6c84b2de7e6214b2b25c8743eb8d6bddf5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Tue, 14 Feb 2023 11:43:44 -0800 Subject: [PATCH] iris: Implement batch_submit() in Xe kmd backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Roberto de Souza Reviewed-by: Lionel Landwerlin Part-of: --- src/gallium/drivers/iris/iris_batch.c | 19 ++++- .../drivers/iris/xe/iris_kmd_backend.c | 83 +++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c index aa121b09f95..28db1d7d90c 100644 --- a/src/gallium/drivers/iris/iris_batch.c +++ b/src/gallium/drivers/iris/iris_batch.c @@ -826,6 +826,21 @@ iris_batch_name_to_string(enum iris_batch_name name) return names[name]; } +static inline bool +context_or_engine_was_banned(struct iris_bufmgr *bufmgr, int ret) +{ + enum intel_kmd_type kmd_type = iris_bufmgr_get_device_info(bufmgr)->kmd_type; + + /* In i915 EIO means our context is banned, while on Xe ECANCELED means + * our engine was banned + */ + if ((kmd_type == INTEL_KMD_TYPE_I915 && ret == -EIO) || + (kmd_type == INTEL_KMD_TYPE_XE && ret == -ECANCELED)) + return true; + + return false; +} + /** * Flush the batch buffer, submitting it to the GPU and resetting it so * we're ready to emit the next batch. @@ -904,12 +919,12 @@ _iris_batch_flush(struct iris_batch *batch, const char *file, int line) /* Start a new batch buffer. */ iris_batch_reset(batch); - /* EIO means our context is banned. In this case, try and replace it + /* Check if context or engine was banned, if yes try to replace it * with a new logical context, and inform iris_context that all state * has been lost and needs to be re-initialized. If this succeeds, * dubiously claim success... */ - if (ret == -EIO) { + if (ret && context_or_engine_was_banned(bufmgr, ret)) { enum pipe_reset_status status = iris_batch_check_for_reset(batch); if (batch->reset->reset) { /* Tell gallium frontends the device is lost and it was our fault. */ diff --git a/src/gallium/drivers/iris/xe/iris_kmd_backend.c b/src/gallium/drivers/iris/xe/iris_kmd_backend.c index 801967f43f5..12ec74abe9c 100644 --- a/src/gallium/drivers/iris/xe/iris_kmd_backend.c +++ b/src/gallium/drivers/iris/xe/iris_kmd_backend.c @@ -193,6 +193,88 @@ xe_batch_check_for_reset(struct iris_batch *batch) return status; } +static int +xe_batch_submit(struct iris_batch *batch) +{ + struct iris_bufmgr *bufmgr = batch->screen->bufmgr; + simple_mtx_t *bo_deps_lock = iris_bufmgr_get_bo_deps_lock(bufmgr); + struct drm_xe_sync *syncs = NULL; + unsigned long sync_len; + int ret = 0; + + iris_bo_unmap(batch->bo); + + /* The decode operation may map and wait on the batch buffer, which could + * in theory try to grab bo_deps_lock. Let's keep it safe and decode + * outside the lock. + */ + if (INTEL_DEBUG(DEBUG_BATCH)) + iris_batch_decode_batch(batch); + + simple_mtx_lock(bo_deps_lock); + + iris_batch_update_syncobjs(batch); + + sync_len = iris_batch_num_fences(batch); + if (sync_len) { + unsigned long i = 0; + + syncs = calloc(sync_len, sizeof(*syncs)); + if (!syncs) { + ret = -ENOMEM; + goto error_no_sync_mem; + } + + util_dynarray_foreach(&batch->exec_fences, struct iris_batch_fence, + fence) { + uint32_t flags = DRM_XE_SYNC_SYNCOBJ; + + if (fence->flags & IRIS_BATCH_FENCE_SIGNAL) + flags |= DRM_XE_SYNC_SIGNAL; + + syncs[i].handle = fence->handle; + syncs[i].flags = flags; + i++; + } + } + + if (INTEL_DEBUG(DEBUG_BATCH | DEBUG_SUBMIT)) { + iris_dump_fence_list(batch); + iris_dump_bo_list(batch); + } + + struct drm_xe_exec exec = { + .engine_id = batch->xe.engine_id, + .num_batch_buffer = 1, + .address = batch->exec_bos[0]->address, + .syncs = (uintptr_t)syncs, + .num_syncs = sync_len, + }; + if (!batch->screen->devinfo->no_hw) + ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_XE_EXEC, &exec); + + simple_mtx_unlock(bo_deps_lock); + + free(syncs); + + for (int i = 0; i < batch->exec_count; i++) { + struct iris_bo *bo = batch->exec_bos[i]; + + bo->idle = false; + bo->index = -1; + + iris_get_backing_bo(bo)->idle = false; + + iris_bo_unreference(bo); + } + + return ret; + +error_no_sync_mem: + simple_mtx_unlock(bo_deps_lock); + return ret; +} + const struct iris_kmd_backend *xe_get_backend(void) { static const struct iris_kmd_backend xe_backend = { @@ -203,6 +285,7 @@ const struct iris_kmd_backend *xe_get_backend(void) .bo_madvise = xe_bo_madvise, .bo_set_caching = xe_bo_set_caching, .batch_check_for_reset = xe_batch_check_for_reset, + .batch_submit = xe_batch_submit, }; return &xe_backend; }