drm/i915: Move releasing of the GEM request from free to retire/cancel
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Apr 2016 08:56:55 +0000 (09:56 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Apr 2016 11:17:32 +0000 (12:17 +0100)
If we move the release of the GEM request (i.e. decoupling it from the
various lists used for client and context tracking) after it is complete
(either by the GPU retiring the request, or by the caller cancelling the
request), we can remove the requirement that the final unreference of
the GEM request need to be under the struct_mutex.

The careful reader may notice that one or two impossible NULL pointer
tests are dropped for readability. These pointers cannot be NULL since
they are assigned during request construction and never unset.

v2,v3: Rebalance execlists by moving the context unpinning.
v4: Rebase onto -nightly
v5: Avoid trying to rebalance execlist/GuC context pinning, leave that
to the next step

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1461833819-3991-21-git-send-email-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_pm.c

index ea7aea044603fa8c276e84843492c1cda4f98a3f..0bd9d17ff9744a04eb456e43432cc47352349edf 100644 (file)
@@ -2373,23 +2373,9 @@ i915_gem_request_reference(struct drm_i915_gem_request *req)
 static inline void
 i915_gem_request_unreference(struct drm_i915_gem_request *req)
 {
-       WARN_ON(!mutex_is_locked(&req->engine->dev->struct_mutex));
        kref_put(&req->ref, i915_gem_request_free);
 }
 
-static inline void
-i915_gem_request_unreference__unlocked(struct drm_i915_gem_request *req)
-{
-       struct drm_device *dev;
-
-       if (!req)
-               return;
-
-       dev = req->engine->dev;
-       if (kref_put_mutex(&req->ref, i915_gem_request_free, &dev->struct_mutex))
-               mutex_unlock(&dev->struct_mutex);
-}
-
 static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
                                           struct drm_i915_gem_request *src)
 {
index 5c36577335c35863b2cd878be238a7e6aee93464..e9bf45a3ffa2bff4e2b5104f7ea65e1f70712a58 100644 (file)
@@ -1413,6 +1413,13 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
        list_del_init(&request->list);
        i915_gem_request_remove_from_client(request);
 
+       if (request->ctx) {
+               if (i915.enable_execlists)
+                       intel_lr_context_unpin(request->ctx, request->engine);
+
+               i915_gem_context_unreference(request->ctx);
+       }
+
        i915_gem_request_unreference(request);
 }
 
@@ -2716,18 +2723,6 @@ void i915_gem_request_free(struct kref *req_ref)
 {
        struct drm_i915_gem_request *req = container_of(req_ref,
                                                 typeof(*req), ref);
-       struct intel_context *ctx = req->ctx;
-
-       if (req->file_priv)
-               i915_gem_request_remove_from_client(req);
-
-       if (ctx) {
-               if (i915.enable_execlists)
-                       intel_lr_context_unpin(ctx, req->engine);
-
-               i915_gem_context_unreference(ctx);
-       }
-
        kmem_cache_free(req->i915->requests, req);
 }
 
@@ -3176,7 +3171,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
                        ret = __i915_wait_request(req[i], true,
                                                  args->timeout_ns > 0 ? &args->timeout_ns : NULL,
                                                  to_rps_client(file));
-               i915_gem_request_unreference__unlocked(req[i]);
+               i915_gem_request_unreference(req[i]);
        }
        return ret;
 
@@ -4202,7 +4197,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
        if (ret == 0)
                queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
 
-       i915_gem_request_unreference__unlocked(target);
+       i915_gem_request_unreference(target);
 
        return ret;
 }
index b4c24e77e8a22c6bcf7d6a23c03ead80d11be06a..2f36414702fe8cedbb0da8fe3a4349f44a0de40d 100644 (file)
@@ -11400,7 +11400,7 @@ static void intel_mmio_flip_work_func(struct work_struct *work)
                WARN_ON(__i915_wait_request(mmio_flip->req,
                                            false, NULL,
                                            &mmio_flip->i915->rps.mmioflips));
-               i915_gem_request_unreference__unlocked(mmio_flip->req);
+               i915_gem_request_unreference(mmio_flip->req);
        }
 
        /* For framebuffer backed by dmabuf, wait for fence */
index 695a464a5e64fd5cc42c4c12e1e88844ae8a375e..2422ac38ce5d6ea46e19bf1081109d187d90739c 100644 (file)
@@ -7385,7 +7385,7 @@ static void __intel_rps_boost_work(struct work_struct *work)
                gen6_rps_boost(to_i915(req->engine->dev), NULL,
                               req->emitted_jiffies);
 
-       i915_gem_request_unreference__unlocked(req);
+       i915_gem_request_unreference(req);
        kfree(boost);
 }