diff --git a/src/gallium/drivers/iris/xe/iris_kmd_backend.c b/src/gallium/drivers/iris/xe/iris_kmd_backend.c index 912a67b18c9..4ccf9c7f7b9 100644 --- a/src/gallium/drivers/iris/xe/iris_kmd_backend.c +++ b/src/gallium/drivers/iris/xe/iris_kmd_backend.c @@ -26,6 +26,7 @@ #include "common/intel_debug_identifier.h" #include "common/intel_gem.h" +#include "common/xe/intel_gem.h" #include "dev/intel_debug.h" #include "iris/iris_bufmgr.h" #include "iris/iris_batch.h" @@ -408,13 +409,12 @@ xe_batch_submit(struct iris_batch *batch) .syncs = (uintptr_t)syncs, .num_syncs = sync_len, }; - if (likely(!batch->screen->devinfo->no_hw)) { - ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_XE_EXEC, &exec); - if (ret) { - ret = -errno; - goto error_exec; - } + ret = xe_gem_exec_ioctl(iris_bufmgr_get_fd(bufmgr), batch->screen->devinfo, + &exec); + if (ret) { + ret = -errno; + goto error_exec; } if (!iris_implicit_sync_export(batch, &implicit_sync)) diff --git a/src/intel/common/xe/intel_gem.h b/src/intel/common/xe/intel_gem.h index d6796f0834f..3440fd5ee0b 100644 --- a/src/intel/common/xe/intel_gem.h +++ b/src/intel/common/xe/intel_gem.h @@ -27,7 +27,10 @@ #include #include +#include "common/intel_gem.h" #include "common/intel_engine.h" +#include "drm-uapi/xe_drm.h" +#include "util/os_time.h" bool xe_gem_read_render_timestamp(int fd, uint64_t *value); bool @@ -42,3 +45,28 @@ bool xe_gem_can_render_on_fd(int fd); bool xe_gem_supports_protected_exec_queue(int fd); void intel_xe_gem_add_ext(uint64_t *ptr, uint32_t ext_name, void *data); + +static inline int +xe_gem_exec_ioctl(int fd, const struct intel_device_info *info, + struct drm_xe_exec *exec) +{ + int ret, retries; + + if (unlikely(info->no_hw)) + return 0; + + /* After 80 retries, we spent more than 16s sleeping. */ + for (retries = 0; retries < 80; retries++) { + ret = intel_ioctl(fd, DRM_IOCTL_XE_EXEC, exec); + + if (likely(!(ret && errno == ENOMEM))) + break; + + if (unlikely(retries == 40)) + fprintf(stderr, "intel: the execbuf ioctl keeps returning ENOMEM\n"); + + os_time_sleep(100 * retries * retries); + } + + return ret; +} diff --git a/src/intel/vulkan/xe/anv_batch_chain.c b/src/intel/vulkan/xe/anv_batch_chain.c index f052b2d77df..4c9c5d294fc 100644 --- a/src/intel/vulkan/xe/anv_batch_chain.c +++ b/src/intel/vulkan/xe/anv_batch_chain.c @@ -26,6 +26,7 @@ #include "anv_private.h" #include "anv_measure.h" #include "common/intel_bind_timeline.h" +#include "common/xe/intel_gem.h" #include "perf/intel_perf.h" #include "drm-uapi/xe_drm.h" @@ -139,12 +140,8 @@ xe_exec_ioctl_impl(struct anv_queue *queue, struct drm_xe_exec *exec, const char *func, int line) { struct anv_device *device = queue->device; - int ret; - if (unlikely(device->info->no_hw)) - return VK_SUCCESS; - - ret = intel_ioctl(device->fd, DRM_IOCTL_XE_EXEC, exec); + int ret = xe_gem_exec_ioctl(device->fd, device->info, exec); if (ret) return vk_queue_set_lost(&queue->vk, "%s(%d) failed: %m", func, line);