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@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Lionel Landwerlin 2019-08-23 13:48:28 +02:00
parent 89de271bc2
commit 3da798c9f1
5 changed files with 60 additions and 24 deletions

View File

@ -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)

View File

@ -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,
@ -2885,6 +2885,28 @@ _anv_device_set_lost(struct anv_device *device,
return err;
}
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)
{
@ -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

View File

@ -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,

View File

@ -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(

View File

@ -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