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,
 };
 
 /**
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to