svn commit: r251960 - head/sys/dev/drm2/i915

Konstantin Belousov kib at FreeBSD.org
Tue Jun 18 20:02:52 UTC 2013


Author: kib
Date: Tue Jun 18 20:02:52 2013
New Revision: 251960
URL: http://svnweb.freebsd.org/changeset/base/251960

Log:
  Since the gem pagefault handler relocks the vm object lock, other
  thread might fault on the same GTT offset meantime and instantiate the
  mapping.  Recheck that the mgt device object still does not have a
  page at the current offset after relocking, and return a possibly
  installed page.
  
  Reported by:	Oleg Sidorkin <osidorkin at gmail.com>
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/dev/drm2/i915/i915_gem.c

Modified: head/sys/dev/drm2/i915/i915_gem.c
==============================================================================
--- head/sys/dev/drm2/i915/i915_gem.c	Tue Jun 18 19:56:52 2013	(r251959)
+++ head/sys/dev/drm2/i915/i915_gem.c	Tue Jun 18 20:02:52 2013	(r251960)
@@ -1371,6 +1371,23 @@ unlocked_vmobj:
 	} else
 		DRM_LOCK(dev);
 
+	/*
+	 * Since the object lock was dropped, other thread might have
+	 * faulted on the same GTT address and instantiated the
+	 * mapping for the page.  Recheck.
+	 */
+	VM_OBJECT_WLOCK(vm_obj);
+	m = vm_page_lookup(vm_obj, OFF_TO_IDX(offset));
+	if (m != NULL) {
+		if ((m->flags & VPO_BUSY) != 0) {
+			DRM_UNLOCK(dev);
+			vm_page_sleep(m, "915pee");
+			goto retry;
+		}
+		goto have_page;
+	} else
+		VM_OBJECT_WUNLOCK(vm_obj);
+
 	/* Now bind it into the GTT if needed */
 	if (!obj->map_and_fenceable) {
 		ret = i915_gem_object_unbind(obj);
@@ -1424,8 +1441,9 @@ unlocked_vmobj:
 		goto retry;
 	}
 	m->valid = VM_PAGE_BITS_ALL;
-	*mres = m;
 	vm_page_insert(m, vm_obj, OFF_TO_IDX(offset));
+have_page:
+	*mres = m;
 	vm_page_busy(m);
 
 	CTR4(KTR_DRM, "fault %p %jx %x phys %x", gem_obj, offset, prot,


More information about the svn-src-head mailing list