drm/i915: Pull obj->userfault tracking under the ggtt->mutex
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 22 Aug 2019 06:09:13 +0000 (07:09 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 22 Aug 2019 07:53:41 +0000 (08:53 +0100)
Since we want to revoke the ggtt vma from only under the ggtt->mutex, we
need to move protection of the userfault tracking from the struct_mutex
to the ggtt->mutex.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190822060914.2671-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/gem/i915_gem_mman.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_vma.c

index dba5dd77914985e5b17a834a7eca5e0cea100f5f..595539a09e38599a0fc327c000532f76fa9aff6b 100644 (file)
@@ -306,14 +306,17 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
        if (ret)
                goto err_fence;
 
-       /* Mark as being mmapped into userspace for later revocation */
        assert_rpm_wakelock_held(rpm);
+
+       /* Mark as being mmapped into userspace for later revocation */
+       mutex_lock(&i915->ggtt.vm.mutex);
        if (!i915_vma_set_userfault(vma) && !obj->userfault_count++)
                list_add(&obj->userfault_link, &i915->ggtt.userfault_list);
+       mutex_unlock(&i915->ggtt.vm.mutex);
+
        if (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
                intel_wakeref_auto(&i915->ggtt.userfault_wakeref,
                                   msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
-       GEM_BUG_ON(!obj->userfault_count);
 
        i915_vma_set_ggtt_write(vma);
 
@@ -408,8 +411,8 @@ void i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
         * requirement that operations to the GGTT be made holding the RPM
         * wakeref.
         */
-       lockdep_assert_held(&i915->drm.struct_mutex);
        wakeref = intel_runtime_pm_get(&i915->runtime_pm);
+       mutex_lock(&i915->ggtt.vm.mutex);
 
        if (!obj->userfault_count)
                goto out;
@@ -426,6 +429,7 @@ void i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
        wmb();
 
 out:
+       mutex_unlock(&i915->ggtt.vm.mutex);
        intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 }
 
index f5d6702ec7df3d206b432bdc7b2feabd28923509..b0f51591f2e4a5bb89e91037ab5814cfdba5c36e 100644 (file)
@@ -94,7 +94,7 @@ static char get_tiling_flag(struct drm_i915_gem_object *obj)
 
 static char get_global_flag(struct drm_i915_gem_object *obj)
 {
-       return obj->userfault_count ? 'g' : ' ';
+       return READ_ONCE(obj->userfault_count) ? 'g' : ' ';
 }
 
 static char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
index 79f9d1fb7611450c23c15ea27b4833a8f25ccbcf..9840cb2f70b9e11eccf06ca2b6a26d5a0ab96500 100644 (file)
@@ -864,7 +864,7 @@ void i915_vma_revoke_mmap(struct i915_vma *vma)
        struct drm_vma_offset_node *node = &vma->obj->base.vma_node;
        u64 vma_offset;
 
-       lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+       lockdep_assert_held(&vma->vm->mutex);
 
        if (!i915_vma_has_userfault(vma))
                return;
@@ -987,7 +987,9 @@ int i915_vma_unbind(struct i915_vma *vma)
                        return ret;
 
                /* Force a pagefault for domain tracking on next user access */
+               mutex_lock(&vma->vm->mutex);
                i915_vma_revoke_mmap(vma);
+               mutex_unlock(&vma->vm->mutex);
 
                __i915_vma_iounmap(vma);
                vma->flags &= ~I915_VMA_CAN_FENCE;