Commit b7d151ba authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Pull obj->userfault tracking under the ggtt->mutex



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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190822060914.2671-2-chris@chris-wilson.co.uk
parent e2ccc50a
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -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);
}

+1 −1
Original line number Diff line number Diff line
@@ -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)
+3 −1
Original line number Diff line number Diff line
@@ -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;