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

Konstantin Belousov kib at FreeBSD.org
Thu Dec 8 11:39:10 UTC 2016


Author: kib
Date: Thu Dec  8 11:39:08 2016
New Revision: 309712
URL: https://svnweb.freebsd.org/changeset/base/309712

Log:
  Use the populate() driver paging method for i915 driver.
  
  In particular, the fault access type is accounted for when the
  aperture page is moved to GTT domain.  On the other hand, the current
  pager structure is left intact, most important, only one page is
  instantiated per populate call.
  
  Reviewed by:	alc
  Sponsored by:	The FreeBSD Foundation
  MFC after:	3 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	Thu Dec  8 11:35:53 2016	(r309711)
+++ head/sys/dev/drm2/i915/i915_gem.c	Thu Dec  8 11:39:08 2016	(r309712)
@@ -1474,8 +1474,8 @@ i915_gem_pager_ctor(void *handle, vm_oof
 int i915_intr_pf;
 
 static int
-i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot,
-    vm_page_t *mres)
+i915_gem_pager_populate(vm_object_t vm_obj, vm_pindex_t pidx, int fault_type,
+    vm_prot_t max_prot, vm_pindex_t *first, vm_pindex_t *last)
 {
 	struct drm_gem_object *gem_obj = vm_obj->handle;
 	struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
@@ -1483,31 +1483,9 @@ i915_gem_pager_fault(vm_object_t vm_obj,
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	vm_page_t page;
 	int ret = 0;
-#ifdef FREEBSD_WIP
-	bool write = (prot & VM_PROT_WRITE) != 0;
-#else
-	bool write = true;
-#endif /* FREEBSD_WIP */
+	bool write = (max_prot & VM_PROT_WRITE) != 0;
 	bool pinned;
 
-	vm_object_pip_add(vm_obj, 1);
-
-	/*
-	 * Remove the placeholder page inserted by vm_fault() from the
-	 * object before dropping the object lock. If
-	 * i915_gem_release_mmap() is active in parallel on this gem
-	 * object, then it owns the drm device sx and might find the
-	 * placeholder already. Then, since the page is busy,
-	 * i915_gem_release_mmap() sleeps waiting for the busy state
-	 * of the page cleared. We will be unable to acquire drm
-	 * device lock until i915_gem_release_mmap() is able to make a
-	 * progress.
-	 */
-	if (*mres != NULL) {
-		vm_page_lock(*mres);
-		vm_page_remove(*mres);
-		vm_page_unlock(*mres);
-	}
 	VM_OBJECT_WUNLOCK(vm_obj);
 retry:
 	ret = 0;
@@ -1527,7 +1505,7 @@ retry:
 	 * mapping for the page.  Recheck.
 	 */
 	VM_OBJECT_WLOCK(vm_obj);
-	page = vm_page_lookup(vm_obj, OFF_TO_IDX(offset));
+	page = vm_page_lookup(vm_obj, pidx);
 	if (page != NULL) {
 		if (vm_page_busied(page)) {
 			DRM_UNLOCK(dev);
@@ -1543,7 +1521,7 @@ retry:
 	/* Now bind it into the GTT if needed */
 	ret = i915_gem_object_pin(obj, 0, true, false);
 	if (ret)
-		goto unlock;
+		goto unpin;
 	pinned = 1;
 
 	ret = i915_gem_object_set_to_gtt_domain(obj, write);
@@ -1556,20 +1534,19 @@ retry:
 
 	obj->fault_mappable = true;
 
-	VM_OBJECT_WLOCK(vm_obj);
-	page = PHYS_TO_VM_PAGE(dev_priv->mm.gtt_base_addr + obj->gtt_offset + offset);
-	KASSERT((page->flags & PG_FICTITIOUS) != 0,
-	    ("physical address %#jx not fictitious",
-	    (uintmax_t)(dev_priv->mm.gtt_base_addr + obj->gtt_offset + offset)));
+	page = PHYS_TO_VM_PAGE(dev_priv->mm.gtt_base_addr + obj->gtt_offset +
+	    IDX_TO_OFF(pidx));
 	if (page == NULL) {
-		VM_OBJECT_WUNLOCK(vm_obj);
 		ret = -EFAULT;
 		goto unpin;
 	}
 	KASSERT((page->flags & PG_FICTITIOUS) != 0,
-	    ("not fictitious %p", page));
+	    ("physical address %#jx not fictitious, page %p",
+	    (uintmax_t)(dev_priv->mm.gtt_base_addr + obj->gtt_offset +
+	    IDX_TO_OFF(pidx)), page));
 	KASSERT(page->wire_count == 1, ("wire_count not 1 %p", page));
 
+	VM_OBJECT_WLOCK(vm_obj);
 	if (vm_page_busied(page)) {
 		i915_gem_object_unpin(obj);
 		DRM_UNLOCK(dev);
@@ -1578,7 +1555,7 @@ retry:
 		vm_page_busy_sleep(page, "915pbs", false);
 		goto retry;
 	}
-	if (vm_page_insert(page, vm_obj, OFF_TO_IDX(offset))) {
+	if (vm_page_insert(page, vm_obj, pidx)) {
 		i915_gem_object_unpin(obj);
 		DRM_UNLOCK(dev);
 		VM_OBJECT_WUNLOCK(vm_obj);
@@ -1589,33 +1566,24 @@ retry:
 have_page:
 	vm_page_xbusy(page);
 
-	CTR4(KTR_DRM, "fault %p %jx %x phys %x", gem_obj, offset, prot,
+	CTR4(KTR_DRM, "fault %p %jx %x phys %x", gem_obj, pidx, fault_type,
 	    page->phys_addr);
 	if (pinned) {
 		/*
 		 * We may have not pinned the object if the page was
-		 * found by the call to vm_page_lookup()
+		 * found by the call to vm_page_lookup().
 		 */
 		i915_gem_object_unpin(obj);
 	}
 	DRM_UNLOCK(dev);
-	if (*mres != NULL) {
-		KASSERT(*mres != page, ("losing %p %p", *mres, page));
-		vm_page_lock(*mres);
-		vm_page_free(*mres);
-		vm_page_unlock(*mres);
-	}
-	*mres = page;
-	vm_object_pip_wakeup(vm_obj);
+	*first = *last = pidx;
 	return (VM_PAGER_OK);
 
 unpin:
-	i915_gem_object_unpin(obj);
-unlock:
 	DRM_UNLOCK(dev);
 out:
 	KASSERT(ret != 0, ("i915_gem_pager_fault: wrong return"));
-	CTR4(KTR_DRM, "fault_fail %p %jx %x err %d", gem_obj, offset, prot,
+	CTR4(KTR_DRM, "fault_fail %p %jx %x err %d", gem_obj, pidx, fault_type,
 	    -ret);
 	if (ret == -ERESTARTSYS) {
 		/*
@@ -1629,7 +1597,6 @@ out:
 		goto retry;
 	}
 	VM_OBJECT_WLOCK(vm_obj);
-	vm_object_pip_wakeup(vm_obj);
 	return (VM_PAGER_ERROR);
 }
 
@@ -1645,9 +1612,9 @@ i915_gem_pager_dtor(void *handle)
 }
 
 struct cdev_pager_ops i915_gem_pager_ops = {
-	.cdev_pg_fault	= i915_gem_pager_fault,
-	.cdev_pg_ctor	= i915_gem_pager_ctor,
-	.cdev_pg_dtor	= i915_gem_pager_dtor
+	.cdev_pg_populate	= i915_gem_pager_populate,
+	.cdev_pg_ctor		= i915_gem_pager_ctor,
+	.cdev_pg_dtor		= i915_gem_pager_dtor,
 };
 
 /**


More information about the svn-src-all mailing list