drm/i915: Propagate error from failing to queue a request
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
@@ -1041,7 +1041,7 @@ 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);
|
||||||
|
@@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,7 +3854,9 @@ 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))
|
||||||
|
ring->outstanding_lazy_request = true;
|
||||||
|
else
|
||||||
request = NULL;
|
request = NULL;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
@@ -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,
|
|||||||
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,18 +234,20 @@ 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);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3);
|
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3);
|
||||||
intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE |
|
intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE |
|
||||||
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
|
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
|
||||||
@@ -254,8 +256,6 @@ render_ring_add_request(struct intel_ring_buffer *ring,
|
|||||||
intel_ring_emit(ring, seqno);
|
intel_ring_emit(ring, seqno);
|
||||||
intel_ring_emit(ring, 0);
|
intel_ring_emit(ring, 0);
|
||||||
intel_ring_emit(ring, 0);
|
intel_ring_emit(ring, 0);
|
||||||
intel_ring_advance(ring);
|
|
||||||
}
|
|
||||||
} 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,7 +264,10 @@ 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);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
|
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
|
||||||
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
|
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
|
||||||
intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
|
intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
|
||||||
@@ -287,19 +290,21 @@ render_ring_add_request(struct intel_ring_buffer *ring,
|
|||||||
intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
|
intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
|
||||||
intel_ring_emit(ring, seqno);
|
intel_ring_emit(ring, seqno);
|
||||||
intel_ring_emit(ring, 0);
|
intel_ring_emit(ring, 0);
|
||||||
intel_ring_advance(ring);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (intel_ring_begin(ring, 4) == 0) {
|
ret = intel_ring_begin(ring, 4);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
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);
|
||||||
}
|
*result = seqno;
|
||||||
}
|
return 0;
|
||||||
return seqno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
@@ -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 {
|
|||||||
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,
|
||||||
|
Reference in New Issue
Block a user