Mesa (master): anv: prepare driver to report submission error through queues

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Nov 11 22:11:43 UTC 2019


Module: Mesa
Branch: master
Commit: 3da798c9f1b463f514cf058577fe38561810ba74
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3da798c9f1b463f514cf058577fe38561810ba74

Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date:   Fri Aug 23 13:48:28 2019 +0200

anv: prepare driver to report submission error through queues

When we will submit to i915 from a submission thread, we won't be able
to directly report the error to the user (in particular through the
debug report callbacks). So prepare 2 paths to report errors device ->
notifying the user immediately, queue -> notifying the user the next
time an entry point is called.

In this change we still report directly for both paths, this will
change in the next commit.

v2: Split NULL batch parameter handling in
    anv_queue_submit_simple_batch() in a different commit

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

---

 src/intel/vulkan/anv_batch_chain.c |  5 +++--
 src/intel/vulkan/anv_device.c      | 26 ++++++++++++++++++++++++--
 src/intel/vulkan/anv_private.h     | 24 ++++++++++++++++--------
 src/intel/vulkan/anv_queue.c       | 27 ++++++++++++++++-----------
 src/intel/vulkan/genX_state.c      |  2 +-
 5 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
index b16fd818fd2..5720859a674 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -1614,7 +1614,7 @@ setup_empty_execbuf(struct anv_execbuf *execbuf, struct anv_device *device)
 }
 
 VkResult
-anv_cmd_buffer_execbuf(struct anv_device *device,
+anv_cmd_buffer_execbuf(struct anv_queue *queue,
                        struct anv_cmd_buffer *cmd_buffer,
                        const VkSemaphore *in_semaphores,
                        uint32_t num_in_semaphores,
@@ -1623,6 +1623,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
                        VkFence _fence)
 {
    ANV_FROM_HANDLE(anv_fence, fence, _fence);
+   struct anv_device *device = queue->device;
    UNUSED struct anv_physical_device *pdevice = &device->instance->physicalDevice;
 
    struct anv_execbuf execbuf;
@@ -1792,7 +1793,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
    if (need_out_fence)
       execbuf.execbuf.flags |= I915_EXEC_FENCE_OUT;
 
-   result = anv_device_execbuf(device, &execbuf.execbuf, execbuf.bos);
+   result = anv_queue_execbuf(queue, &execbuf.execbuf, execbuf.bos);
 
    /* Execbuf does not consume the in_fence.  It's our job to close it. */
    if (in_fence != -1)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 3e1e6e1c804..61448d8dbdd 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -2871,7 +2871,7 @@ _anv_device_set_lost(struct anv_device *device,
    VkResult err;
    va_list ap;
 
-   device->_lost = true;
+   p_atomic_inc(&device->_lost);
 
    va_start(ap, msg);
    err = __vk_errorv(device->instance, device,
@@ -2886,6 +2886,28 @@ _anv_device_set_lost(struct anv_device *device,
 }
 
 VkResult
+_anv_queue_set_lost(struct anv_queue *queue,
+                    const char *file, int line,
+                    const char *msg, ...)
+{
+   VkResult err;
+   va_list ap;
+
+   p_atomic_inc(&queue->device->_lost);
+
+   va_start(ap, msg);
+   err = __vk_errorv(queue->device->instance, queue->device,
+                     VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+                     VK_ERROR_DEVICE_LOST, file, line, msg, ap);
+   va_end(ap);
+
+   if (env_var_as_boolean("ANV_ABORT_ON_DEVICE_LOSS", false))
+      abort();
+
+   return err;
+}
+
+VkResult
 anv_device_query_status(struct anv_device *device)
 {
    /* This isn't likely as most of the callers of this function already check
@@ -2963,7 +2985,7 @@ VkResult anv_DeviceWaitIdle(
    if (anv_device_is_lost(device))
       return VK_ERROR_DEVICE_LOST;
 
-   return anv_device_submit_simple_batch(device, NULL);
+   return anv_queue_submit_simple_batch(&device->queue, NULL);
 }
 
 bool
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 5dc0af64d37..ff28d897a21 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -69,6 +69,7 @@ typedef struct xcb_connection_t xcb_connection_t;
 typedef uint32_t xcb_visualid_t;
 typedef uint32_t xcb_window_t;
 
+struct anv_batch;
 struct anv_buffer;
 struct anv_buffer_view;
 struct anv_image_view;
@@ -1181,7 +1182,7 @@ struct anv_device {
 
     pthread_mutex_t                             mutex;
     pthread_cond_t                              queue_submit;
-    bool                                        _lost;
+    int                                         _lost;
 
     struct gen_batch_decode_ctx                 decoder_ctx;
     /*
@@ -1231,22 +1232,26 @@ anv_mocs_for_bo(const struct anv_device *device, const struct anv_bo *bo)
 void anv_device_init_blorp(struct anv_device *device);
 void anv_device_finish_blorp(struct anv_device *device);
 
+void _anv_device_set_all_queue_lost(struct anv_device *device);
 VkResult _anv_device_set_lost(struct anv_device *device,
                               const char *file, int line,
                               const char *msg, ...)
    anv_printflike(4, 5);
+VkResult _anv_queue_set_lost(struct anv_queue *queue,
+                              const char *file, int line,
+                              const char *msg, ...)
+   anv_printflike(4, 5);
 #define anv_device_set_lost(dev, ...) \
    _anv_device_set_lost(dev, __FILE__, __LINE__, __VA_ARGS__)
+#define anv_queue_set_lost(queue, ...) \
+   _anv_queue_set_lost(queue, __FILE__, __LINE__, __VA_ARGS__)
 
 static inline bool
 anv_device_is_lost(struct anv_device *device)
 {
-   return unlikely(device->_lost);
+   return unlikely(p_atomic_read(&device->_lost));
 }
 
-VkResult anv_device_execbuf(struct anv_device *device,
-                            struct drm_i915_gem_execbuffer2 *execbuf,
-                            struct anv_bo **execbuf_bos);
 VkResult anv_device_query_status(struct anv_device *device);
 
 
@@ -1313,6 +1318,11 @@ VkResult anv_device_wait(struct anv_device *device, struct anv_bo *bo,
 VkResult anv_queue_init(struct anv_device *device, struct anv_queue *queue);
 void anv_queue_finish(struct anv_queue *queue);
 
+VkResult anv_queue_execbuf(struct anv_queue *queue,
+                           struct drm_i915_gem_execbuffer2 *execbuf,
+                           struct anv_bo **execbuf_bos);
+VkResult anv_queue_submit_simple_batch(struct anv_queue *queue,
+                                       struct anv_batch *batch);
 
 uint64_t anv_gettime_ns(void);
 uint64_t anv_get_absolute_timeout(uint64_t timeout);
@@ -1427,8 +1437,6 @@ void *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords);
 void anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other);
 uint64_t anv_batch_emit_reloc(struct anv_batch *batch,
                               void *location, struct anv_bo *bo, uint32_t offset);
-VkResult anv_device_submit_simple_batch(struct anv_device *device,
-                                        struct anv_batch *batch);
 
 static inline VkResult
 anv_batch_set_error(struct anv_batch *batch, VkResult error)
@@ -2636,7 +2644,7 @@ void anv_cmd_buffer_end_batch_buffer(struct anv_cmd_buffer *cmd_buffer);
 void anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary,
                                   struct anv_cmd_buffer *secondary);
 void anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer);
-VkResult anv_cmd_buffer_execbuf(struct anv_device *device,
+VkResult anv_cmd_buffer_execbuf(struct anv_queue *queue,
                                 struct anv_cmd_buffer *cmd_buffer,
                                 const VkSemaphore *in_semaphores,
                                 uint32_t num_in_semaphores,
diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c
index dbe2febaef7..8bf58e3214a 100644
--- a/src/intel/vulkan/anv_queue.c
+++ b/src/intel/vulkan/anv_queue.c
@@ -77,14 +77,15 @@ static int64_t anv_get_relative_timeout(uint64_t abs_timeout)
 }
 
 VkResult
-anv_device_execbuf(struct anv_device *device,
-                   struct drm_i915_gem_execbuffer2 *execbuf,
-                   struct anv_bo **execbuf_bos)
+anv_queue_execbuf(struct anv_queue *queue,
+                  struct drm_i915_gem_execbuffer2 *execbuf,
+                  struct anv_bo **execbuf_bos)
 {
+   struct anv_device *device = queue->device;
    int ret = device->no_hw ? 0 : anv_gem_execbuffer(device, execbuf);
    if (ret != 0) {
       /* We don't know the real error. */
-      return anv_device_set_lost(device, "execbuf2 failed: %m");
+      return anv_queue_set_lost(queue, "execbuf2 failed: %m");
    }
 
    struct drm_i915_gem_exec_object2 *objects =
@@ -114,9 +115,10 @@ anv_queue_finish(struct anv_queue *queue)
 }
 
 VkResult
-anv_device_submit_simple_batch(struct anv_device *device,
-                               struct anv_batch *batch)
+anv_queue_submit_simple_batch(struct anv_queue *queue,
+                              struct anv_batch *batch)
 {
+   struct anv_device *device = queue->device;
    struct drm_i915_gem_execbuffer2 execbuf;
    struct drm_i915_gem_exec_object2 exec2_objects[1];
    struct anv_bo *bo;
@@ -166,7 +168,7 @@ anv_device_submit_simple_batch(struct anv_device *device,
                       bo->size, bo->offset, false);
    }
 
-   result = anv_device_execbuf(device, &execbuf, &bo);
+   result = anv_queue_execbuf(queue, &execbuf, &bo);
    if (result != VK_SUCCESS)
       goto fail;
 
@@ -232,7 +234,7 @@ VkResult anv_QueueSubmit(
        * come up with something more efficient but this shouldn't be a
        * common case.
        */
-      result = anv_cmd_buffer_execbuf(device, NULL, NULL, 0, NULL, 0, fence);
+      result = anv_cmd_buffer_execbuf(queue, NULL, NULL, 0, NULL, 0, fence);
       goto out;
    }
 
@@ -246,7 +248,7 @@ VkResult anv_QueueSubmit(
           * come up with something more efficient but this shouldn't be a
           * common case.
           */
-         result = anv_cmd_buffer_execbuf(device, NULL,
+         result = anv_cmd_buffer_execbuf(queue, NULL,
                                          pSubmits[i].pWaitSemaphores,
                                          pSubmits[i].waitSemaphoreCount,
                                          pSubmits[i].pSignalSemaphores,
@@ -283,7 +285,7 @@ VkResult anv_QueueSubmit(
             num_out_semaphores = pSubmits[i].signalSemaphoreCount;
          }
 
-         result = anv_cmd_buffer_execbuf(device, cmd_buffer,
+         result = anv_cmd_buffer_execbuf(queue, cmd_buffer,
                                          in_semaphores, num_in_semaphores,
                                          out_semaphores, num_out_semaphores,
                                          execbuf_fence);
@@ -321,7 +323,10 @@ VkResult anv_QueueWaitIdle(
 {
    ANV_FROM_HANDLE(anv_queue, queue, _queue);
 
-   return anv_DeviceWaitIdle(anv_device_to_handle(queue->device));
+   if (anv_device_is_lost(queue->device))
+      return VK_ERROR_DEVICE_LOST;
+
+   return anv_queue_submit_simple_batch(queue, NULL);
 }
 
 VkResult anv_CreateFence(
diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c
index df76b33a7c3..cd0ced4d163 100644
--- a/src/intel/vulkan/genX_state.c
+++ b/src/intel/vulkan/genX_state.c
@@ -325,7 +325,7 @@ genX(init_device_state)(struct anv_device *device)
 
    assert(batch.next <= batch.end);
 
-   return anv_device_submit_simple_batch(device, &batch);
+   return anv_queue_submit_simple_batch(&device->queue, &batch);
 }
 
 static uint32_t




More information about the mesa-commit mailing list