svn commit: r312075 - stable/11/sys/dev/drm2/i915

Konstantin Belousov kib at FreeBSD.org
Fri Jan 13 13:50:45 UTC 2017


Author: kib
Date: Fri Jan 13 13:50:44 2017
New Revision: 312075
URL: https://svnweb.freebsd.org/changeset/base/312075

Log:
  MFC r309712:
  Use the populate() driver paging method for i915 driver.
  
  MFC r310027:
  Fix bug in r309712, do not leak gem object pin count in case of error
  or retry.

Modified:
  stable/11/sys/dev/drm2/i915/i915_gem.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/drm2/i915/i915_gem.c
==============================================================================
--- stable/11/sys/dev/drm2/i915/i915_gem.c	Fri Jan 13 13:47:26 2017	(r312074)
+++ stable/11/sys/dev/drm2/i915/i915_gem.c	Fri Jan 13 13:50:44 2017	(r312075)
@@ -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);
@@ -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,24 +1566,17 @@ 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:
@@ -1615,7 +1585,7 @@ 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 +1599,6 @@ out:
 		goto retry;
 	}
 	VM_OBJECT_WLOCK(vm_obj);
-	vm_object_pip_wakeup(vm_obj);
 	return (VM_PAGER_ERROR);
 }
 
@@ -1645,9 +1614,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-stable mailing list