[Intel-gfx] [PATCH v2 3/3] drm/i915: Only spin whilst waiting on the current request
Chris Wilson
chris at chris-wilson.co.uk
Fri Nov 27 06:26:22 PST 2015
Limit busywaiting only to the request currently being processed by the
GPU. If the request is not currently being processed by the GPU, there
is a very low likelihood of it being completed within the 2 microsecond
spin timeout and so we will just be wasting CPU cycles.
v2: Check for logical inversion when rebasing - we were incorrectly
checking for this request being active, and instead busywaiting for
when the GPU was not yet processing the request of interest.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin at intel.com>
Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
Cc: Tvrtko Ursulin <tvrtko.ursulin at linux.intel.com>
Cc: Eero Tamminen <eero.t.tamminen at intel.com>
Cc: "Rantala, Valtteri" <valtteri.rantala at intel.com>
Cc: stable at kernel.vger.org
---
drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 25 +++++++++++++++----------
drivers/gpu/drm/i915/i915_gem.c | 12 +++++++++---
drivers/gpu/drm/i915/i915_gpu_error.c | 2 +-
drivers/gpu/drm/i915/i915_guc_submission.c | 2 +-
5 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index a3b22bdacd44..f0aeafbcf307 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -710,7 +710,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
if (req->pid)
task = pid_task(req->pid, PIDTYPE_PID);
seq_printf(m, " %x @ %d: %s [%d]\n",
- req->seqno,
+ req->seqno_complete,
(int) (jiffies - req->emitted_jiffies),
task ? task->comm : "<unknown>",
task ? task->pid : -1);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 95bb27de774f..19986bd032ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2192,8 +2192,12 @@ struct drm_i915_gem_request {
struct drm_i915_private *i915;
struct intel_engine_cs *ring;
- /** GEM sequence number associated with this request. */
- uint32_t seqno;
+ /* GEM sequence numbers associated with this request:
+ * active - marks the start of the request, passed when
+ * the GPU completes the previous request
+ * complete - marks the end of the request
+ */
+ u32 seqno_active, seqno_complete;
/** Position in the ringbuffer of the start of the request */
u32 head;
@@ -2270,7 +2274,7 @@ int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
static inline uint32_t
i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
{
- return req ? req->seqno : 0;
+ return req ? req->seqno_complete : 0;
}
static inline struct intel_engine_cs *
@@ -2909,16 +2913,17 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
return (int32_t)(seq1 - seq2) >= 0;
}
+static inline bool i915_gem_request_active(struct drm_i915_gem_request *req)
+{
+ u32 seqno = req->ring->get_seqno(req->ring, true);
+ return i915_seqno_passed(seqno, req->seqno_active);
+}
+
static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
bool lazy_coherency)
{
- u32 seqno;
-
- BUG_ON(req == NULL);
-
- seqno = req->ring->get_seqno(req->ring, lazy_coherency);
-
- return i915_seqno_passed(seqno, req->seqno);
+ u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
+ return i915_seqno_passed(seqno, req->seqno_complete);
}
int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c0941e8a70f7..490840324e88 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1193,9 +1193,14 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
* takes to sleep on a request, on the order of a microsecond.
*/
- if (i915_gem_request_get_ring(req)->irq_refcount)
+ if (req->ring->irq_refcount)
return -EBUSY;
+ /* Only spin if we know the GPU is processing this request */
+ if (!i915_seqno_passed(req->ring->get_seqno(req->ring, false),
+ req->seqno_active))
+ return -EAGAIN;
+
timeout = local_clock_us(&cpu) + 10;
while (!need_resched()) {
if (i915_gem_request_completed(req, true))
@@ -2592,7 +2597,8 @@ void __i915_add_request(struct drm_i915_gem_request *request,
request->batch_obj = obj;
request->emitted_jiffies = jiffies;
- ring->last_submitted_seqno = request->seqno;
+ request->seqno_active = ring->last_submitted_seqno;
+ ring->last_submitted_seqno = request->seqno_complete;
list_add_tail(&request->list, &ring->request_list);
trace_i915_gem_request_add(request);
@@ -2691,7 +2697,7 @@ int i915_gem_request_alloc(struct intel_engine_cs *ring,
if (req == NULL)
return -ENOMEM;
- ret = i915_gem_get_seqno(ring->dev, &req->seqno);
+ ret = i915_gem_get_seqno(ring->dev, &req->seqno_complete);
if (ret)
goto err;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2f04e4f2ff35..33501499bf51 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1072,7 +1072,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
struct drm_i915_error_request *erq;
erq = &error->ring[i].requests[count++];
- erq->seqno = request->seqno;
+ erq->seqno = request->seqno_complete;
erq->jiffies = request->emitted_jiffies;
erq->tail = request->postfix;
}
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 036b42bae827..d313e1938d58 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -625,7 +625,7 @@ int i915_guc_submit(struct i915_guc_client *client,
spin_lock(&guc->host2guc_lock);
guc->submissions[ring_id] += 1;
- guc->last_seqno[ring_id] = rq->seqno;
+ guc->last_seqno[ring_id] = rq->seqno_complete;
spin_unlock(&guc->host2guc_lock);
return q_ret;
--
2.6.2
More information about the Intel-gfx
mailing list