drm/i915: Propagate error from failing to queue a request
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 27 Oct 2010 15:11:02 +0000 (16:11 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 27 Oct 2010 22:31:03 +0000 (23:31 +0100)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 2af8e16..f168e82 100644 (file)
@@ -1041,10 +1041,10 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start,
                     unsigned long end);
 int i915_gpu_idle(struct drm_device *dev);
 int i915_gem_idle(struct drm_device *dev);
-uint32_t i915_add_request(struct drm_device *dev,
-                         struct drm_file *file_priv,
-                         struct drm_i915_gem_request *request,
-                         struct intel_ring_buffer *ring);
+int i915_add_request(struct drm_device *dev,
+                    struct drm_file *file_priv,
+                    struct drm_i915_gem_request *request,
+                    struct intel_ring_buffer *ring);
 int i915_do_wait_request(struct drm_device *dev,
                         uint32_t seqno,
                         bool interruptible,
index 74f5525..d0aaf97 100644 (file)
@@ -1683,7 +1683,7 @@ i915_gem_process_flushing_list(struct drm_device *dev,
        }
 }
 
-uint32_t
+int
 i915_add_request(struct drm_device *dev,
                 struct drm_file *file,
                 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;
        uint32_t seqno;
        int was_empty;
+       int ret;
+
+       BUG_ON(request == NULL);
 
        if (file != NULL)
                file_priv = file->driver_priv;
 
-       if (request == NULL) {
-               request = kzalloc(sizeof(*request), GFP_KERNEL);
-               if (request == NULL)
-                       return 0;
-       }
+       ret = ring->add_request(ring, &seqno);
+       if (ret)
+           return ret;
 
-       seqno = ring->add_request(ring, 0);
        ring->outstanding_lazy_request = false;
 
        request->seqno = seqno;
@@ -1727,7 +1727,7 @@ i915_add_request(struct drm_device *dev,
                        queue_delayed_work(dev_priv->wq,
                                           &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;
 
        if (ring->outstanding_lazy_request) {
-               seqno = i915_add_request(dev, NULL, NULL, ring);
-               if (seqno == 0)
+               struct drm_i915_gem_request *request;
+
+               request = kzalloc(sizeof(*request), GFP_KERNEL);
+               if (request == NULL)
                        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);
 
@@ -3844,8 +3854,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
         */
        i915_retire_commands(dev, ring);
 
-       i915_add_request(dev, file, request, ring);
-       request = NULL;
+       if (i915_add_request(dev, file, request, ring))
+               ring->outstanding_lazy_request = true;
+       else
+               request = NULL;
 
 err:
        for (i = 0; i < args->buffer_count; i++) {
index 78fa6a2..2d4a696 100644 (file)
@@ -221,11 +221,12 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
        int ret;
 
        BUG_ON(overlay->last_flip_req);
-       overlay->last_flip_req =
-               i915_add_request(dev, NULL, request, &dev_priv->render_ring);
-       if (overlay->last_flip_req == 0)
-               return -ENOMEM;
-
+       ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring);
+       if (ret) {
+           kfree(request);
+           return ret;
+       }
+       overlay->last_flip_req = request->seqno;
        overlay->flip_tail = tail;
        ret = i915_do_wait_request(dev,
                                   overlay->last_flip_req, true,
@@ -363,8 +364,13 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
        OUT_RING(flip_addr);
         ADVANCE_LP_RING();
 
-       overlay->last_flip_req =
-               i915_add_request(dev, NULL, request, &dev_priv->render_ring);
+       ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring);
+       if (ret) {
+               kfree(request);
+               return ret;
+       }
+
+       overlay->last_flip_req = request->seqno;
        return 0;
 }
 
index 6fe42c1..4803b32 100644 (file)
@@ -234,28 +234,28 @@ do {                                                                      \
  *
  * Returned sequence numbers are nonzero on success.
  */
-static u32
+static int
 render_ring_add_request(struct intel_ring_buffer *ring,
-                       u32 flush_domains)
+                       u32 *result)
 {
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       u32 seqno;
-
-       seqno = i915_gem_get_seqno(dev);
+       u32 seqno = i915_gem_get_seqno(dev);
+       int ret;
 
        if (IS_GEN6(dev)) {
-               if (intel_ring_begin(ring, 6) == 0) {
-                       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3);
-                       intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE |
-                                       PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
-                                       PIPE_CONTROL_NOTIFY);
-                       intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-                       intel_ring_emit(ring, seqno);
-                       intel_ring_emit(ring, 0);
-                       intel_ring_emit(ring, 0);
-                       intel_ring_advance(ring);
-               }
+               ret = intel_ring_begin(ring, 6);
+               if (ret)
+                   return ret;
+
+               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3);
+               intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE |
+                               PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
+                               PIPE_CONTROL_NOTIFY);
+               intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               intel_ring_emit(ring, seqno);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
        } else if (HAS_PIPE_CONTROL(dev)) {
                u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
 
@@ -264,42 +264,47 @@ render_ring_add_request(struct intel_ring_buffer *ring,
                 * PIPE_NOTIFY buffers out to memory before requesting
                 * an interrupt.
                 */
-               if (intel_ring_begin(ring, 32) == 0) {
-                       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                                       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, seqno);
-                       intel_ring_emit(ring, 0);
-                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
-                       scratch_addr += 128; /* write to separate cachelines */
-                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
-                       scratch_addr += 128;
-                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
-                       scratch_addr += 128;
-                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
-                       scratch_addr += 128;
-                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
-                       scratch_addr += 128;
-                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
-                       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                                       PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
-                                       PIPE_CONTROL_NOTIFY);
-                       intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-                       intel_ring_emit(ring, seqno);
-                       intel_ring_emit(ring, 0);
-                       intel_ring_advance(ring);
-               }
+               ret = intel_ring_begin(ring, 32);
+               if (ret)
+                       return ret;
+
+               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                               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, seqno);
+               intel_ring_emit(ring, 0);
+               PIPE_CONTROL_FLUSH(ring, scratch_addr);
+               scratch_addr += 128; /* write to separate cachelines */
+               PIPE_CONTROL_FLUSH(ring, scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(ring, scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(ring, scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(ring, scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(ring, scratch_addr);
+               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                               PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+                               PIPE_CONTROL_NOTIFY);
+               intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               intel_ring_emit(ring, seqno);
+               intel_ring_emit(ring, 0);
        } else {
-               if (intel_ring_begin(ring, 4) == 0) {
-                       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, seqno);
+               ret = intel_ring_begin(ring, 4);
+               if (ret)
+                   return ret;
 
-                       intel_ring_emit(ring, MI_USER_INTERRUPT);
-                       intel_ring_advance(ring);
-               }
+               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, seqno);
+
+               intel_ring_emit(ring, MI_USER_INTERRUPT);
        }
-       return seqno;
+
+       intel_ring_advance(ring);
+       *result = seqno;
+       return 0;
 }
 
 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,
-                u32 flush_domains)
+                u32 *result)
 {
        u32 seqno;
+       int ret;
+
+       ret = intel_ring_begin(ring, 4);
+       if (ret)
+               return ret;
 
        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, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-               intel_ring_emit(ring, seqno);
-               intel_ring_emit(ring, MI_USER_INTERRUPT);
-               intel_ring_advance(ring);
-       }
+       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, seqno);
+       intel_ring_emit(ring, MI_USER_INTERRUPT);
+       intel_ring_advance(ring);
 
        DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
-
-       return seqno;
+       *result = seqno;
+       return 0;
 }
 
 static void
index 7ad9e94..acd2337 100644 (file)
@@ -48,8 +48,8 @@ struct  intel_ring_buffer {
        void            (*flush)(struct intel_ring_buffer *ring,
                                 u32    invalidate_domains,
                                 u32    flush_domains);
-       u32             (*add_request)(struct intel_ring_buffer *ring,
-                                      u32 flush_domains);
+       int             (*add_request)(struct intel_ring_buffer *ring,
+                                      u32 *seqno);
        u32             (*get_seqno)(struct intel_ring_buffer *ring);
        int             (*dispatch_execbuffer)(struct intel_ring_buffer *ring,
                                               struct drm_i915_gem_execbuffer2 *exec,