[PATCH 29/33] drm/i915: Mark the GT as busy before idling the previous request

Chris Wilson chris at chris-wilson.co.uk
Tue Jul 4 18:55:01 UTC 2017


In a synchronous setup, we may retire the last request before we
complete allocating the next request. As the last request is retired, we
queue a timer to mark the device as idle, and promptly have to execute
ad cancel that timer once we complete allocating the request and need to
keep the device awake. If we rearrange the mark_busy() to occur before
we retire the previous request, we can skip this ping-pong.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_request.c | 43 ++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 483af8921060..2da4b3f117ab 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -261,6 +261,13 @@ static int reserve_seqno(struct intel_engine_cs *engine)
 
 static void unreserve_seqno(struct intel_engine_cs *engine)
 {
+	if (!--engine->i915->gt.active_requests) {
+		GEM_BUG_ON(!engine->i915->gt.awake);
+		mod_delayed_work(engine->i915->wq,
+				 &engine->i915->gt.idle_work,
+				 msecs_to_jiffies(100));
+	}
+
 	GEM_BUG_ON(!engine->timeline->inflight_seqnos);
 	engine->timeline->inflight_seqnos--;
 }
@@ -329,12 +336,6 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
 	list_del_init(&request->link);
 	spin_unlock_irq(&engine->timeline->lock);
 
-	if (!--request->i915->gt.active_requests) {
-		GEM_BUG_ON(!request->i915->gt.awake);
-		mod_delayed_work(request->i915->wq,
-				 &request->i915->gt.idle_work,
-				 msecs_to_jiffies(100));
-	}
 	unreserve_seqno(request->engine);
 	advance_ring(request);
 
@@ -576,6 +577,9 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
 	if (ret)
 		goto err_unpin;
 
+	if (!dev_oriv->gt.active_requests++)
+		mark_busy(dev_priv);
+
 	/* Move the oldest request to the slab-cache (if not in use!) */
 	req = list_first_entry_or_null(&engine->timeline->requests,
 				       typeof(*req), link);
@@ -860,25 +864,23 @@ i915_gem_request_await_object(struct drm_i915_gem_request *to,
 	return ret;
 }
 
-static void i915_gem_mark_busy(const struct intel_engine_cs *engine)
+static void mark_busy(struct drm_i915_private *i915)
 {
-	struct drm_i915_private *dev_priv = engine->i915;
-
-	if (dev_priv->gt.awake)
+	if (i915->gt.awake)
 		return;
 
-	GEM_BUG_ON(!dev_priv->gt.active_requests);
+	GEM_BUG_ON(!i915->gt.active_requests);
 
-	intel_runtime_pm_get_noresume(dev_priv);
-	dev_priv->gt.awake = true;
+	intel_runtime_pm_get_noresume(i915);
+	i915->gt.awake = true;
 
-	intel_enable_gt_powersave(dev_priv);
-	i915_update_gfx_val(dev_priv);
-	if (INTEL_GEN(dev_priv) >= 6)
-		gen6_rps_busy(dev_priv);
+	intel_enable_gt_powersave(i915);
+	i915_update_gfx_val(i915);
+	if (INTEL_GEN(i915) >= 6)
+		gen6_rps_busy(i915);
 
-	queue_delayed_work(dev_priv->wq,
-			   &dev_priv->gt.retire_work,
+	queue_delayed_work(i915->wq,
+			   &i915->gt.retire_work,
 			   round_jiffies_up_relative(HZ));
 }
 
@@ -963,9 +965,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
 	list_add_tail(&request->ring_link, &ring->request_list);
 	request->emitted_jiffies = jiffies;
 
-	if (!request->i915->gt.active_requests++)
-		i915_gem_mark_busy(engine);
-
 	/* Let the backend know a new request has arrived that may need
 	 * to adjust the existing execution schedule due to a high priority
 	 * request - i.e. we may want to preempt the current request in order
-- 
2.13.2



More information about the Intel-gfx-trybot mailing list