aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-08-17 10:47:19 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2017-08-18 07:01:41 -0400
commit636918f130296fac1ab195ba087688f91bd627f8 (patch)
tree44898395a4e5138e6ffb25db5a57915c6747b4a2
parent0519bcb1737c58b91da23735394ecf26ae211fbc (diff)
drm/i915: Mark the GT as busy before idling the previous request
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. v2: Joonas pointed out that unreserve_seqno() was now doing more than doing seqno handling and should be renamed to reflect its wider purpose. That also highlighted the new asymmetry with reserve_seqno(), so fixup that and rename both to [un]reserve_engine(). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20170817144719.10968-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.c88
1 files changed, 45 insertions, 43 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 9eedd33eb524..813a3b546d6e 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -244,27 +244,60 @@ int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
244 return reset_all_global_seqno(dev_priv, seqno - 1); 244 return reset_all_global_seqno(dev_priv, seqno - 1);
245} 245}
246 246
247static int reserve_seqno(struct intel_engine_cs *engine) 247static void mark_busy(struct drm_i915_private *i915)
248{ 248{
249 if (i915->gt.awake)
250 return;
251
252 GEM_BUG_ON(!i915->gt.active_requests);
253
254 intel_runtime_pm_get_noresume(i915);
255 i915->gt.awake = true;
256
257 intel_enable_gt_powersave(i915);
258 i915_update_gfx_val(i915);
259 if (INTEL_GEN(i915) >= 6)
260 gen6_rps_busy(i915);
261
262 queue_delayed_work(i915->wq,
263 &i915->gt.retire_work,
264 round_jiffies_up_relative(HZ));
265}
266
267static int reserve_engine(struct intel_engine_cs *engine)
268{
269 struct drm_i915_private *i915 = engine->i915;
249 u32 active = ++engine->timeline->inflight_seqnos; 270 u32 active = ++engine->timeline->inflight_seqnos;
250 u32 seqno = engine->timeline->seqno; 271 u32 seqno = engine->timeline->seqno;
251 int ret; 272 int ret;
252 273
253 /* Reservation is fine until we need to wrap around */ 274 /* Reservation is fine until we need to wrap around */
254 if (likely(!add_overflows(seqno, active))) 275 if (unlikely(add_overflows(seqno, active))) {
255 return 0; 276 ret = reset_all_global_seqno(i915, 0);
256 277 if (ret) {
257 ret = reset_all_global_seqno(engine->i915, 0); 278 engine->timeline->inflight_seqnos--;
258 if (ret) { 279 return ret;
259 engine->timeline->inflight_seqnos--; 280 }
260 return ret;
261 } 281 }
262 282
283 if (!i915->gt.active_requests++)
284 mark_busy(i915);
285
263 return 0; 286 return 0;
264} 287}
265 288
266static void unreserve_seqno(struct intel_engine_cs *engine) 289static void unreserve_engine(struct intel_engine_cs *engine)
267{ 290{
291 struct drm_i915_private *i915 = engine->i915;
292
293 if (!--i915->gt.active_requests) {
294 /* Cancel the mark_busy() from our reserve_engine() */
295 GEM_BUG_ON(!i915->gt.awake);
296 mod_delayed_work(i915->wq,
297 &i915->gt.idle_work,
298 msecs_to_jiffies(100));
299 }
300
268 GEM_BUG_ON(!engine->timeline->inflight_seqnos); 301 GEM_BUG_ON(!engine->timeline->inflight_seqnos);
269 engine->timeline->inflight_seqnos--; 302 engine->timeline->inflight_seqnos--;
270} 303}
@@ -333,13 +366,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
333 list_del_init(&request->link); 366 list_del_init(&request->link);
334 spin_unlock_irq(&engine->timeline->lock); 367 spin_unlock_irq(&engine->timeline->lock);
335 368
336 if (!--request->i915->gt.active_requests) { 369 unreserve_engine(request->engine);
337 GEM_BUG_ON(!request->i915->gt.awake);
338 mod_delayed_work(request->i915->wq,
339 &request->i915->gt.idle_work,
340 msecs_to_jiffies(100));
341 }
342 unreserve_seqno(request->engine);
343 advance_ring(request); 370 advance_ring(request);
344 371
345 free_capture_list(request); 372 free_capture_list(request);
@@ -575,7 +602,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
575 return ERR_CAST(ring); 602 return ERR_CAST(ring);
576 GEM_BUG_ON(!ring); 603 GEM_BUG_ON(!ring);
577 604
578 ret = reserve_seqno(engine); 605 ret = reserve_engine(engine);
579 if (ret) 606 if (ret)
580 goto err_unpin; 607 goto err_unpin;
581 608
@@ -681,7 +708,7 @@ err_ctx:
681 708
682 kmem_cache_free(dev_priv->requests, req); 709 kmem_cache_free(dev_priv->requests, req);
683err_unreserve: 710err_unreserve:
684 unreserve_seqno(engine); 711 unreserve_engine(engine);
685err_unpin: 712err_unpin:
686 engine->context_unpin(engine, ctx); 713 engine->context_unpin(engine, ctx);
687 return ERR_PTR(ret); 714 return ERR_PTR(ret);
@@ -863,28 +890,6 @@ i915_gem_request_await_object(struct drm_i915_gem_request *to,
863 return ret; 890 return ret;
864} 891}
865 892
866static void i915_gem_mark_busy(const struct intel_engine_cs *engine)
867{
868 struct drm_i915_private *dev_priv = engine->i915;
869
870 if (dev_priv->gt.awake)
871 return;
872
873 GEM_BUG_ON(!dev_priv->gt.active_requests);
874
875 intel_runtime_pm_get_noresume(dev_priv);
876 dev_priv->gt.awake = true;
877
878 intel_enable_gt_powersave(dev_priv);
879 i915_update_gfx_val(dev_priv);
880 if (INTEL_GEN(dev_priv) >= 6)
881 gen6_rps_busy(dev_priv);
882
883 queue_delayed_work(dev_priv->wq,
884 &dev_priv->gt.retire_work,
885 round_jiffies_up_relative(HZ));
886}
887
888/* 893/*
889 * NB: This function is not allowed to fail. Doing so would mean the the 894 * NB: This function is not allowed to fail. Doing so would mean the the
890 * request is not being tracked for completion but the work itself is 895 * request is not being tracked for completion but the work itself is
@@ -966,9 +971,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
966 list_add_tail(&request->ring_link, &ring->request_list); 971 list_add_tail(&request->ring_link, &ring->request_list);
967 request->emitted_jiffies = jiffies; 972 request->emitted_jiffies = jiffies;
968 973
969 if (!request->i915->gt.active_requests++)
970 i915_gem_mark_busy(engine);
971
972 /* Let the backend know a new request has arrived that may need 974 /* Let the backend know a new request has arrived that may need
973 * to adjust the existing execution schedule due to a high priority 975 * to adjust the existing execution schedule due to a high priority
974 * request - i.e. we may want to preempt the current request in order 976 * request - i.e. we may want to preempt the current request in order