summaryrefslogtreecommitdiffstats
path: root/src/intel
diff options
context:
space:
mode:
authorLionel Landwerlin <[email protected]>2019-08-23 13:48:28 +0200
committerLionel Landwerlin <[email protected]>2019-11-11 21:46:51 +0000
commit3da798c9f1b463f514cf058577fe38561810ba74 (patch)
treed2c0b22e8c42bf998505ff2ef7d075c8956cd338 /src/intel
parent89de271bc2923834adf13d9b45bae9a1811c94f6 (diff)
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 <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel')
-rw-r--r--src/intel/vulkan/anv_batch_chain.c5
-rw-r--r--src/intel/vulkan/anv_device.c26
-rw-r--r--src/intel/vulkan/anv_private.h24
-rw-r--r--src/intel/vulkan/anv_queue.c27
-rw-r--r--src/intel/vulkan/genX_state.c2
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