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