diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-08-05 09:14:08 (GMT) |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-08-05 09:54:35 (GMT) |
commit | 8a3b3d576c933d99fe774e9cb88005b87c3fb5c4 (patch) | |
tree | d2765e13d01b67a5cedb28bde5cbe068dea10fd9 /drivers/gpu/drm/i915/i915_gem_userptr.c | |
parent | b8f9096d6a51e3ac31deb0f57a9a323059bb4281 (diff) | |
download | linux-8a3b3d576c933d99fe774e9cb88005b87c3fb5c4.tar.xz |
drm/i915: Convert non-blocking userptr waits for requests over to using RCU
We can completely avoid taking the struct_mutex around the non-blocking
waits by switching over to the RCU request management (trading the mutex
for a RCU read lock and some complex atomic operations). The improvement
is that we gain further contention reduction, and overall the code
become simpler due to the reduced mutex dancing.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470388464-28458-3-git-send-email-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_userptr.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_userptr.c | 34 |
1 files changed, 7 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 53f64fc..96ab616 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -63,32 +63,12 @@ struct i915_mmu_object { static void wait_rendering(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->base.dev; - struct drm_i915_gem_request *requests[I915_NUM_ENGINES]; - int i, n; - - if (!i915_gem_object_is_active(obj)) - return; - - n = 0; - for (i = 0; i < I915_NUM_ENGINES; i++) { - struct drm_i915_gem_request *req; + unsigned long active = __I915_BO_ACTIVE(obj); + int idx; - req = i915_gem_active_get(&obj->last_read[i], - &obj->base.dev->struct_mutex); - if (req) - requests[n++] = req; - } - - mutex_unlock(&dev->struct_mutex); - - for (i = 0; i < n; i++) - i915_wait_request(requests[i], false, NULL, NULL); - - mutex_lock(&dev->struct_mutex); - - for (i = 0; i < n; i++) - i915_gem_request_put(requests[i]); + for_each_active(active, idx) + i915_gem_active_wait_unlocked(&obj->last_read[idx], + false, NULL, NULL); } static void cancel_userptr(struct work_struct *work) @@ -97,6 +77,8 @@ static void cancel_userptr(struct work_struct *work) struct drm_i915_gem_object *obj = mo->obj; struct drm_device *dev = obj->base.dev; + wait_rendering(obj); + mutex_lock(&dev->struct_mutex); /* Cancel any active worker and force us to re-evaluate gup */ obj->userptr.work = NULL; @@ -105,8 +87,6 @@ static void cancel_userptr(struct work_struct *work) struct drm_i915_private *dev_priv = to_i915(dev); bool was_interruptible; - wait_rendering(obj); - was_interruptible = dev_priv->mm.interruptible; dev_priv->mm.interruptible = false; |