Commit 3cce469c authored by Chris Wilson's avatar Chris Wilson

drm/i915: Propagate error from failing to queue a request

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent b2223497
...@@ -1041,10 +1041,10 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start, ...@@ -1041,10 +1041,10 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end); unsigned long end);
int i915_gpu_idle(struct drm_device *dev); int i915_gpu_idle(struct drm_device *dev);
int i915_gem_idle(struct drm_device *dev); int i915_gem_idle(struct drm_device *dev);
uint32_t i915_add_request(struct drm_device *dev, int i915_add_request(struct drm_device *dev,
struct drm_file *file_priv, struct drm_file *file_priv,
struct drm_i915_gem_request *request, struct drm_i915_gem_request *request,
struct intel_ring_buffer *ring); struct intel_ring_buffer *ring);
int i915_do_wait_request(struct drm_device *dev, int i915_do_wait_request(struct drm_device *dev,
uint32_t seqno, uint32_t seqno,
bool interruptible, bool interruptible,
......
...@@ -1683,7 +1683,7 @@ i915_gem_process_flushing_list(struct drm_device *dev, ...@@ -1683,7 +1683,7 @@ i915_gem_process_flushing_list(struct drm_device *dev,
} }
} }
uint32_t int
i915_add_request(struct drm_device *dev, i915_add_request(struct drm_device *dev,
struct drm_file *file, struct drm_file *file,
struct drm_i915_gem_request *request, struct drm_i915_gem_request *request,
...@@ -1693,17 +1693,17 @@ i915_add_request(struct drm_device *dev, ...@@ -1693,17 +1693,17 @@ i915_add_request(struct drm_device *dev,
struct drm_i915_file_private *file_priv = NULL; struct drm_i915_file_private *file_priv = NULL;
uint32_t seqno; uint32_t seqno;
int was_empty; int was_empty;
int ret;
BUG_ON(request == NULL);
if (file != NULL) if (file != NULL)
file_priv = file->driver_priv; file_priv = file->driver_priv;
if (request == NULL) { ret = ring->add_request(ring, &seqno);
request = kzalloc(sizeof(*request), GFP_KERNEL); if (ret)
if (request == NULL) return ret;
return 0;
}
seqno = ring->add_request(ring, 0);
ring->outstanding_lazy_request = false; ring->outstanding_lazy_request = false;
request->seqno = seqno; request->seqno = seqno;
...@@ -1727,7 +1727,7 @@ i915_add_request(struct drm_device *dev, ...@@ -1727,7 +1727,7 @@ i915_add_request(struct drm_device *dev,
queue_delayed_work(dev_priv->wq, queue_delayed_work(dev_priv->wq,
&dev_priv->mm.retire_work, HZ); &dev_priv->mm.retire_work, HZ);
} }
return seqno; return 0;
} }
/** /**
...@@ -1964,9 +1964,19 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, ...@@ -1964,9 +1964,19 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno,
return -EAGAIN; return -EAGAIN;
if (ring->outstanding_lazy_request) { if (ring->outstanding_lazy_request) {
seqno = i915_add_request(dev, NULL, NULL, ring); struct drm_i915_gem_request *request;
if (seqno == 0)
request = kzalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL)
return -ENOMEM; return -ENOMEM;
ret = i915_add_request(dev, NULL, request, ring);
if (ret) {
kfree(request);
return ret;
}
seqno = request->seqno;
} }
BUG_ON(seqno == dev_priv->next_seqno); BUG_ON(seqno == dev_priv->next_seqno);
...@@ -3844,8 +3854,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -3844,8 +3854,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
*/ */
i915_retire_commands(dev, ring); i915_retire_commands(dev, ring);
i915_add_request(dev, file, request, ring); if (i915_add_request(dev, file, request, ring))
request = NULL; ring->outstanding_lazy_request = true;
else
request = NULL;
err: err:
for (i = 0; i < args->buffer_count; i++) { for (i = 0; i < args->buffer_count; i++) {
......
...@@ -221,11 +221,12 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, ...@@ -221,11 +221,12 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
int ret; int ret;
BUG_ON(overlay->last_flip_req); BUG_ON(overlay->last_flip_req);
overlay->last_flip_req = ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring);
i915_add_request(dev, NULL, request, &dev_priv->render_ring); if (ret) {
if (overlay->last_flip_req == 0) kfree(request);
return -ENOMEM; return ret;
}
overlay->last_flip_req = request->seqno;
overlay->flip_tail = tail; overlay->flip_tail = tail;
ret = i915_do_wait_request(dev, ret = i915_do_wait_request(dev,
overlay->last_flip_req, true, overlay->last_flip_req, true,
...@@ -363,8 +364,13 @@ static int intel_overlay_continue(struct intel_overlay *overlay, ...@@ -363,8 +364,13 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
OUT_RING(flip_addr); OUT_RING(flip_addr);
ADVANCE_LP_RING(); ADVANCE_LP_RING();
overlay->last_flip_req = ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring);
i915_add_request(dev, NULL, request, &dev_priv->render_ring); if (ret) {
kfree(request);
return ret;
}
overlay->last_flip_req = request->seqno;
return 0; return 0;
} }
......
...@@ -234,28 +234,28 @@ do { \ ...@@ -234,28 +234,28 @@ do { \
* *
* Returned sequence numbers are nonzero on success. * Returned sequence numbers are nonzero on success.
*/ */
static u32 static int
render_ring_add_request(struct intel_ring_buffer *ring, render_ring_add_request(struct intel_ring_buffer *ring,
u32 flush_domains) u32 *result)
{ {
struct drm_device *dev = ring->dev; struct drm_device *dev = ring->dev;
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
u32 seqno; u32 seqno = i915_gem_get_seqno(dev);
int ret;
seqno = i915_gem_get_seqno(dev);
if (IS_GEN6(dev)) { if (IS_GEN6(dev)) {
if (intel_ring_begin(ring, 6) == 0) { ret = intel_ring_begin(ring, 6);
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); if (ret)
intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | return ret;
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
PIPE_CONTROL_NOTIFY); intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3);
intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE |
intel_ring_emit(ring, seqno); PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
intel_ring_emit(ring, 0); PIPE_CONTROL_NOTIFY);
intel_ring_emit(ring, 0); intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
intel_ring_advance(ring); intel_ring_emit(ring, seqno);
} intel_ring_emit(ring, 0);
intel_ring_emit(ring, 0);
} else if (HAS_PIPE_CONTROL(dev)) { } else if (HAS_PIPE_CONTROL(dev)) {
u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
...@@ -264,42 +264,47 @@ render_ring_add_request(struct intel_ring_buffer *ring, ...@@ -264,42 +264,47 @@ render_ring_add_request(struct intel_ring_buffer *ring,
* PIPE_NOTIFY buffers out to memory before requesting * PIPE_NOTIFY buffers out to memory before requesting
* an interrupt. * an interrupt.
*/ */
if (intel_ring_begin(ring, 32) == 0) { ret = intel_ring_begin(ring, 32);
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | if (ret)
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); return ret;
intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
intel_ring_emit(ring, seqno); intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
intel_ring_emit(ring, 0); PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
PIPE_CONTROL_FLUSH(ring, scratch_addr); intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
scratch_addr += 128; /* write to separate cachelines */ intel_ring_emit(ring, seqno);
PIPE_CONTROL_FLUSH(ring, scratch_addr); intel_ring_emit(ring, 0);
scratch_addr += 128; PIPE_CONTROL_FLUSH(ring, scratch_addr);
PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128; /* write to separate cachelines */
scratch_addr += 128; PIPE_CONTROL_FLUSH(ring, scratch_addr);
PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128;
scratch_addr += 128; PIPE_CONTROL_FLUSH(ring, scratch_addr);
PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128;
scratch_addr += 128; PIPE_CONTROL_FLUSH(ring, scratch_addr);
PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128;
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_FLUSH(ring, scratch_addr);
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | scratch_addr += 128;
PIPE_CONTROL_NOTIFY); PIPE_CONTROL_FLUSH(ring, scratch_addr);
intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
intel_ring_emit(ring, seqno); PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
intel_ring_emit(ring, 0); PIPE_CONTROL_NOTIFY);
intel_ring_advance(ring); intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
} intel_ring_emit(ring, seqno);
intel_ring_emit(ring, 0);
} else { } else {
if (intel_ring_begin(ring, 4) == 0) { ret = intel_ring_begin(ring, 4);
intel_ring_emit(ring, MI_STORE_DWORD_INDEX); if (ret)
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); return ret;
intel_ring_emit(ring, seqno);
intel_ring_emit(ring, MI_USER_INTERRUPT); intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_advance(ring); intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
} intel_ring_emit(ring, seqno);
intel_ring_emit(ring, MI_USER_INTERRUPT);
} }
return seqno;
intel_ring_advance(ring);
*result = seqno;
return 0;
} }
static u32 static u32
...@@ -370,25 +375,28 @@ bsd_ring_flush(struct intel_ring_buffer *ring, ...@@ -370,25 +375,28 @@ bsd_ring_flush(struct intel_ring_buffer *ring,
} }
} }
static u32 static int
ring_add_request(struct intel_ring_buffer *ring, ring_add_request(struct intel_ring_buffer *ring,
u32 flush_domains) u32 *result)
{ {
u32 seqno; u32 seqno;
int ret;
ret = intel_ring_begin(ring, 4);
if (ret)
return ret;
seqno = i915_gem_get_seqno(ring->dev); seqno = i915_gem_get_seqno(ring->dev);
if (intel_ring_begin(ring, 4) == 0) { intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, MI_STORE_DWORD_INDEX); intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); intel_ring_emit(ring, seqno);
intel_ring_emit(ring, seqno); intel_ring_emit(ring, MI_USER_INTERRUPT);
intel_ring_emit(ring, MI_USER_INTERRUPT); intel_ring_advance(ring);
intel_ring_advance(ring);
}
DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
*result = seqno;
return seqno; return 0;
} }
static void static void
......
...@@ -48,8 +48,8 @@ struct intel_ring_buffer { ...@@ -48,8 +48,8 @@ struct intel_ring_buffer {
void (*flush)(struct intel_ring_buffer *ring, void (*flush)(struct intel_ring_buffer *ring,
u32 invalidate_domains, u32 invalidate_domains,
u32 flush_domains); u32 flush_domains);
u32 (*add_request)(struct intel_ring_buffer *ring, int (*add_request)(struct intel_ring_buffer *ring,
u32 flush_domains); u32 *seqno);
u32 (*get_seqno)(struct intel_ring_buffer *ring); u32 (*get_seqno)(struct intel_ring_buffer *ring);
int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, int (*dispatch_execbuffer)(struct intel_ring_buffer *ring,
struct drm_i915_gem_execbuffer2 *exec, struct drm_i915_gem_execbuffer2 *exec,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment