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
This commit is contained in:
parent
ed01d9894e
commit
29edde94ac
@ -1474,8 +1474,8 @@ i915_gem_pager_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot,
|
||||
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, vm_ooffset_t offset, int prot,
|
||||
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 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot,
|
||||
* 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 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot,
|
||||
/* 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 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot,
|
||||
|
||||
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 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot,
|
||||
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 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot,
|
||||
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 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot,
|
||||
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,
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user