[Intel-gfx] [PATCH 2/3] drm/i915: Fix userptr deadlock with MAP_FIXED

Chris Wilson chris at chris-wilson.co.uk
Wed Jul 1 04:29:27 PDT 2015


On Wed, Jul 01, 2015 at 12:14:34PM +0100, Tvrtko Ursulin wrote:
> >  static void
> >+__i915_gem_userptr_set_active(struct drm_i915_gem_object *obj,
> >+			      bool value)
> >+{
> >+	/* During mm_invalidate_range we need to cancel any userptr that
> >+	 * overlaps the range being invalidated. Doing so requires the
> >+	 * struct_mutex, and that risks recursion. In order to cause
> >+	 * recursion, the user must alias the userptr address space with
> >+	 * a GTT mmapping (possible with a MAP_FIXED) - then when we have
> >+	 * to invalidate that mmaping, mm_invalidate_range is called with
> >+	 * the userptr address *and* the struct_mutex held.  To prevent that
> >+	 * we set a flag under the i915_mmu_notifier spinlock to indicate
> >+	 * whether this object is valid.
> >+	 */
> >+#if defined(CONFIG_MMU_NOTIFIER)
> >+	if (obj->userptr.mmu_object == NULL)
> >+		return;
> >+
> >+	spin_lock(&obj->userptr.mmu_object->mn->lock);
> >+	obj->userptr.mmu_object->active = value;
> >+	spin_unlock(&obj->userptr.mmu_object->mn->lock);
> >+#endif
> 
> Would this be more obvious as atomic_t? Since I suspect spinlock is
> just for the memory barrier, if that.

Yes, you could probably get away with a little thought and just a memory
barrier. But since one side is guarded by the spinlock, I think it is
easier to reuse that. Especially when the expression becomes a little
more complicated.

> Hm.. What if we get invalidate
> while get_pages is running, before it set active but after gup has
> succeeded?

Yeah, that actually is a probably. Especially thinking about the
gup_worker which we need to cancel.

Back to setting active earlier and clearing it along error paths.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the Intel-gfx mailing list