<div dir="ltr"><div style="font-family:arial,sans-serif;font-size:13.3333339691162px">Reviewed the patch & it looks fine.</div><div style="font-family:arial,sans-serif;font-size:13.3333339691162px">Reviewed-by: "Akash Goel <<a href="mailto:akash.goels@gmail.com" target="_blank">akash.goels@gmail.com</a>>"</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 18, 2014 at 11:59 AM, Deepak S <span dir="ltr"><<a href="mailto:deepak.s@intel.com" target="_blank">deepak.s@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
On Thursday 13 November 2014 03:57 PM, Thomas Daniel wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
No longer create a work item to clean each execlist queue item.<br>
Instead, move retired execlist requests to a queue and clean up the<br>
items during retire_requests.<br>
<br>
v2: Fix legacy ring path broken during overzealous cleanup<br>
<br>
v3: Update idle detection to take execlists queue into account<br>
<br>
v4: Grab execlist lock when checking queue state<br>
<br>
v5: Fix leaking requests by freeing in execlists_retire_requests.<br>
<br>
Issue: VIZ-4274<br>
Signed-off-by: Thomas Daniel <<a href="mailto:thomas.daniel@intel.com" target="_blank">thomas.daniel@intel.com</a>><br>
---<br>
  drivers/gpu/drm/i915/i915_gem.<u></u>c         |    9 ++++++<br>
  drivers/gpu/drm/i915/intel_<u></u>lrc.c        |   53 ++++++++++++++++++------------<u></u>-<br>
  drivers/gpu/drm/i915/intel_<u></u>lrc.h        |    2 +-<br>
  drivers/gpu/drm/i915/intel_<u></u>ringbuffer.h |    1 +<br>
  4 files changed, 42 insertions(+), 23 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/i915/i915_<u></u>gem.c b/drivers/gpu/drm/i915/i915_<u></u>gem.c<br>
index 827edb5..408afe7 100644<br>
--- a/drivers/gpu/drm/i915/i915_<u></u>gem.c<br>
+++ b/drivers/gpu/drm/i915/i915_<u></u>gem.c<br>
@@ -2718,6 +2718,15 @@ i915_gem_retire_requests(<u></u>struct drm_device *dev)<br>
        for_each_ring(ring, dev_priv, i) {<br>
                i915_gem_retire_requests_ring(<u></u>ring);<br>
                idle &= list_empty(&ring->request_<u></u>list);<br>
+               if (i915.enable_execlists) {<br>
+                       unsigned long flags;<br>
+<br>
+                       spin_lock_irqsave(&ring-><u></u>execlist_lock, flags);<br>
+                       idle &= list_empty(&ring->execlist_<u></u>queue);<br>
+                       spin_unlock_irqrestore(&ring-><u></u>execlist_lock, flags);<br>
+<br>
+                       intel_execlists_retire_<u></u>requests(ring);<br>
+               }<br>
        }<br>
        if (idle)<br>
diff --git a/drivers/gpu/drm/i915/intel_<u></u>lrc.c b/drivers/gpu/drm/i915/intel_<u></u>lrc.c<br>
index cd74e5c..d920297 100644<br>
--- a/drivers/gpu/drm/i915/intel_<u></u>lrc.c<br>
+++ b/drivers/gpu/drm/i915/intel_<u></u>lrc.c<br>
@@ -386,7 +386,6 @@ static void execlists_context_unqueue(<u></u>struct intel_engine_cs *ring)<br>
  {<br>
        struct intel_ctx_submit_request *req0 = NULL, *req1 = NULL;<br>
        struct intel_ctx_submit_request *cursor = NULL, *tmp = NULL;<br>
-       struct drm_i915_private *dev_priv = ring->dev->dev_private;<br>
        assert_spin_locked(&ring-><u></u>execlist_lock);<br>
  @@ -403,7 +402,8 @@ static void execlists_context_unqueue(<u></u>struct intel_engine_cs *ring)<br>
                         * will update tail past first request's workload */<br>
                        cursor->elsp_submitted = req0->elsp_submitted;<br>
                        list_del(&req0->execlist_link)<u></u>;<br>
-                       queue_work(dev_priv->wq, &req0->work);<br>
+                       list_add_tail(&req0->execlist_<u></u>link,<br>
+                               &ring->execlist_retired_req_<u></u>list);<br>
                        req0 = cursor;<br>
                } else {<br>
                        req1 = cursor;<br>
@@ -425,7 +425,6 @@ static void execlists_context_unqueue(<u></u>struct intel_engine_cs *ring)<br>
  static bool execlists_check_remove_<u></u>request(struct intel_engine_cs *ring,<br>
                                           u32 request_id)<br>
  {<br>
-       struct drm_i915_private *dev_priv = ring->dev->dev_private;<br>
        struct intel_ctx_submit_request *head_req;<br>
        assert_spin_locked(&ring-><u></u>execlist_lock);<br>
@@ -443,7 +442,8 @@ static bool execlists_check_remove_<u></u>request(struct intel_engine_cs *ring,<br>
                        if (--head_req->elsp_submitted <= 0) {<br>
                                list_del(&head_req->execlist_<u></u>link);<br>
-                               queue_work(dev_priv->wq, &head_req->work);<br>
+                               list_add_tail(&head_req-><u></u>execlist_link,<br>
+                                       &ring->execlist_retired_req_<u></u>list);<br>
                                return true;<br>
                        }<br>
                }<br>
@@ -512,22 +512,6 @@ void intel_execlists_handle_ctx_<u></u>events(struct intel_engine_cs *ring)<br>
                   ((u32)ring->next_context_<u></u>status_buffer & 0x07) << 8);<br>
  }<br>
  -static void execlists_free_request_task(<u></u>struct work_struct *work)<br>
-{<br>
-       struct intel_ctx_submit_request *req =<br>
-               container_of(work, struct intel_ctx_submit_request, work);<br>
-       struct drm_device *dev = req->ring->dev;<br>
-       struct drm_i915_private *dev_priv = dev->dev_private;<br>
-<br>
-       intel_runtime_pm_put(dev_priv)<u></u>;<br>
-<br>
-       mutex_lock(&dev->struct_mutex)<u></u>;<br>
-       i915_gem_context_unreference(<u></u>req->ctx);<br>
-       mutex_unlock(&dev->struct_<u></u>mutex);<br>
-<br>
-       kfree(req);<br>
-}<br>
-<br>
  static int execlists_context_queue(struct intel_engine_cs *ring,<br>
                                   struct intel_context *to,<br>
                                   u32 tail)<br>
@@ -544,7 +528,6 @@ static int execlists_context_queue(struct intel_engine_cs *ring,<br>
        i915_gem_context_reference(<u></u>req->ctx);<br>
        req->ring = ring;<br>
        req->tail = tail;<br>
-       INIT_WORK(&req->work, execlists_free_request_task);<br>
        intel_runtime_pm_get(dev_priv)<u></u>;<br>
  @@ -565,7 +548,8 @@ static int execlists_context_queue(struct intel_engine_cs *ring,<br>
                        WARN(tail_req->elsp_submitted != 0,<br>
                             "More than 2 already-submitted reqs queued\n");<br>
                        list_del(&tail_req->execlist_<u></u>link);<br>
-                       queue_work(dev_priv->wq, &tail_req->work);<br>
+                       list_add_tail(&tail_req-><u></u>execlist_link,<br>
+                               &ring->execlist_retired_req_<u></u>list);<br>
                }<br>
        }<br>
  @@ -733,6 +717,30 @@ int intel_execlists_submission(<u></u>struct drm_device *dev, struct drm_file *file,<br>
        return 0;<br>
  }<br>
  +void intel_execlists_retire_<u></u>requests(struct intel_engine_cs *ring)<br>
+{<br>
+       struct intel_ctx_submit_request *req, *tmp;<br>
+       struct drm_i915_private *dev_priv = ring->dev->dev_private;<br>
+       unsigned long flags;<br>
+       struct list_head retired_list;<br>
+<br>
+       WARN_ON(!mutex_is_locked(&<u></u>ring->dev->struct_mutex));<br>
+       if (list_empty(&ring->execlist_<u></u>retired_req_list))<br>
+               return;<br>
+<br>
+       INIT_LIST_HEAD(&retired_list);<br>
+       spin_lock_irqsave(&ring-><u></u>execlist_lock, flags);<br>
+       list_replace_init(&ring-><u></u>execlist_retired_req_list, &retired_list);<br>
+       spin_unlock_irqrestore(&ring-><u></u>execlist_lock, flags);<br>
+<br>
+       list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) {<br>
+               intel_runtime_pm_put(dev_priv)<u></u>;<br>
+               i915_gem_context_unreference(<u></u>req->ctx);<br>
+               list_del(&req->execlist_link);<br>
+               kfree(req);<br>
</blockquote>
<br></div></div>
Hi Thomas,<br>
<br>
I am fine with the current changes after v5.<br>
Reviewed-by: Deepak S <<a href="mailto:deepak.s@linux.intel.com" target="_blank">deepak.s@linux.intel.com</a>><br>
<br>
Thanks<span class="HOEnZb"><font color="#888888"><br>
Deepak</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+       }<br>
+}<br>
+<br>
  void intel_logical_ring_stop(struct intel_engine_cs *ring)<br>
  {<br>
        struct drm_i915_private *dev_priv = ring->dev->dev_private;<br>
@@ -1248,6 +1256,7 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin<br>
        init_waitqueue_head(&ring-><u></u>irq_queue);<br>
        INIT_LIST_HEAD(&ring-><u></u>execlist_queue);<br>
+       INIT_LIST_HEAD(&ring-><u></u>execlist_retired_req_list);<br>
        spin_lock_init(&ring-><u></u>execlist_lock);<br>
        ring->next_context_status_<u></u>buffer = 0;<br>
  diff --git a/drivers/gpu/drm/i915/intel_<u></u>lrc.h b/drivers/gpu/drm/i915/intel_<u></u>lrc.h<br>
index 33c3b4b..84bbf19 100644<br>
--- a/drivers/gpu/drm/i915/intel_<u></u>lrc.h<br>
+++ b/drivers/gpu/drm/i915/intel_<u></u>lrc.h<br>
@@ -104,11 +104,11 @@ struct intel_ctx_submit_request {<br>
        u32 tail;<br>
        struct list_head execlist_link;<br>
-       struct work_struct work;<br>
        int elsp_submitted;<br>
  };<br>
    void intel_execlists_handle_ctx_<u></u>events(struct intel_engine_cs *ring);<br>
+void intel_execlists_retire_<u></u>requests(struct intel_engine_cs *ring);<br>
    #endif /* _INTEL_LRC_H_ */<br>
diff --git a/drivers/gpu/drm/i915/intel_<u></u>ringbuffer.h b/drivers/gpu/drm/i915/intel_<u></u>ringbuffer.h<br>
index 96479c8..8c002d2 100644<br>
--- a/drivers/gpu/drm/i915/intel_<u></u>ringbuffer.h<br>
+++ b/drivers/gpu/drm/i915/intel_<u></u>ringbuffer.h<br>
@@ -235,6 +235,7 @@ struct  intel_engine_cs {<br>
        /* Execlists */<br>
        spinlock_t execlist_lock;<br>
        struct list_head execlist_queue;<br>
+       struct list_head execlist_retired_req_list;<br>
        u8 next_context_status_buffer;<br>
        u32             irq_keep_mask; /* bitmask for interrupts that should not be masked */<br>
        int             (*emit_request)(struct intel_ringbuffer *ringbuf);<br>
</blockquote>
<br></div></div><div class="HOEnZb"><div class="h5">
______________________________<u></u>_________________<br>
Intel-gfx mailing list<br>
<a href="mailto:Intel-gfx@lists.freedesktop.org" target="_blank">Intel-gfx@lists.freedesktop.<u></u>org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/intel-gfx" target="_blank">http://lists.freedesktop.org/<u></u>mailman/listinfo/intel-gfx</a><br>
</div></div></blockquote></div><br></div>