---
drivers/gpu/drm/i915/intel_lrc.c | 45 ++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 65eea51..1fa36de 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -507,23 +507,11 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
if (to != ring->default_context)
intel_lr_context_pin(ring, to);
- if (!request) {
- /*
- * If there isn't a request associated with this submission,
- * create one as a temporary holder.
- */
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
- request->ring = ring;
- request->ctx = to;
- kref_init(&request->ref);
- request->uniq = dev_priv->request_uniq++;
- i915_gem_context_reference(request->ctx);
- } else {
- i915_gem_request_reference(request);
- WARN_ON(to != request->ctx);
- }
+ WARN_ON(!request);
+ WARN_ON(to != request->ctx);
+
+ i915_gem_request_reference(request);
+
request->tail = tail;
intel_runtime_pm_get(dev_priv);
@@ -677,6 +665,7 @@ static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf,
struct intel_engine_cs *ring = ringbuf->ring;
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_gem_request *local_req;
unsigned long end;
int ret;
@@ -684,8 +673,23 @@ static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf,
if (ret != -ENOSPC)
return ret;
- /* Force the context submission in case we have been skipping it */
- intel_logical_ring_advance_and_submit(ringbuf, ctx, NULL);
+ /*
+ * Force the context submission in case we have been skipping it.
+ * This requires creating a place holder request so that the LRC
+ * submission can be tracked. Note that if this point has been
+ * reached then it is the current submission that is blocking the
+ * driver and the only course of action is to do a partial send and
+ * wait for it to complete.
+ * Note also that because there is no space left in the ring, it is
+ * not possible to write the request submission prologue (which does
+ * things like update seqno values and trigger completion interrupts).
+ * Thus the request cannot be submitted via i915_add_request() and
+ * can not be waiting on by i915_gem_wait_request().
+ */
+ ret = dev_priv->gt.alloc_request(ring, ctx, &local_req);
+ if (ret)
+ return ret;
+ intel_logical_ring_advance_and_submit(ringbuf, ctx, local_req);
/* With GEM the hangcheck timer should kick us out of the loop,
* leaving it early runs the risk of corrupting GEM state (due
@@ -717,6 +721,9 @@ static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf,
}
} while (1);
+ /* This request is now done with and can be disposed of. */
+ i915_gem_request_unreference(local_req);
+
return ret;
}
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx