From 07a12cd75abd21e69571c3187fe48ebb1f074604 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sun, 19 May 2024 13:50:10 +0000 Subject: [PATCH 1/5] ttm: Sync more with Linux. Add the original copyright and attribution since this is now, intentionally, a modified copy of the original and not just roughly the same algorithm. --- sys/external/bsd/drm2/ttm/ttm_bo_vm.c | 319 ++++++++++++++++---------- 1 file changed, 198 insertions(+), 121 deletions(-) diff --git a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c index 661978a01415..5b944ba7c785 100644 --- a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c +++ b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c @@ -29,6 +29,36 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/************************************************************************** + * + * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + #include __KERNEL_RCSID(0, "$NetBSD: ttm_bo_vm.c,v 1.22 2022/07/21 08:07:56 riastradh Exp $"); @@ -44,8 +74,6 @@ __KERNEL_RCSID(0, "$NetBSD: ttm_bo_vm.c,v 1.22 2022/07/21 08:07:56 riastradh Exp #include -static int ttm_bo_uvm_fault_idle(struct ttm_buffer_object *, - struct uvm_faultinfo *); static int ttm_bo_uvm_lookup(struct ttm_bo_device *, unsigned long, unsigned long, struct ttm_buffer_object **); @@ -67,12 +95,81 @@ ttm_bo_uvm_detach(struct uvm_object *uobj) ttm_bo_put(bo); } -int -ttm_bo_uvm_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, +static int +ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, struct uvm_faultinfo *vmf) +{ + int err, ret = 0; + + if (__predict_true(!bo->moving)) + goto out_unlock; + + /* + * Quick non-stalling check for idle. + */ + if (dma_fence_is_signaled(bo->moving)) + goto out_clear; + + /* + * If possible, avoid waiting for GPU with mmap_sem + * held. + */ + if (1) { /* always retriable in NetBSD */ + ret = ERESTART; + + ttm_bo_get(bo); + uvmfault_unlockall(vmf, vmf->entry->aref.ar_amap, NULL); + (void) dma_fence_wait(bo->moving, true); + dma_resv_unlock(bo->base.resv); + ttm_bo_put(bo); + goto out_unlock; + } + + /* + * Ordinary wait. + */ + err = dma_fence_wait(bo->moving, true); + if (__predict_false(err != 0)) { + ret = (err != -ERESTARTSYS) ? EINVAL/*SIGBUS*/ : + 0/*retry access in userland*/; + goto out_unlock; + } + +out_clear: + dma_fence_put(bo->moving); + bo->moving = NULL; + +out_unlock: + return ret; +} + +static int +ttm_bo_vm_reserve(struct ttm_buffer_object *bo, struct uvm_faultinfo *vmf) +{ + + /* + * Work around locking order reversal in fault / nopfn + * between mmap_sem and bo_reserve: Perform a trylock operation + * for reserve, and if it fails, retry the fault after waiting + * for the buffer to become unreserved. + */ + if (__predict_false(!dma_resv_trylock(bo->base.resv))) { + ttm_bo_get(bo); + uvmfault_unlockall(vmf, vmf->entry->aref.ar_amap, NULL); + if (!dma_resv_lock_interruptible(bo->base.resv, NULL)) + dma_resv_unlock(bo->base.resv); + ttm_bo_put(bo); + return ERESTART; + } + + return 0; +} + +static int +ttm_bo_uvm_fault_reserved(struct uvm_faultinfo *vmf, vaddr_t vaddr, struct vm_page **pps, int npages, int centeridx, vm_prot_t access_type, int flags) { - struct uvm_object *const uobj = ufi->entry->object.uvm_obj; + struct uvm_object *const uobj = vmf->entry->object.uvm_obj; struct ttm_buffer_object *const bo = container_of(uobj, struct ttm_buffer_object, uvmobj); struct ttm_bo_device *const bdev = bo->bdev; @@ -88,100 +185,89 @@ ttm_bo_uvm_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, unsigned i; vm_prot_t vm_prot; /* VM_PROT_* */ pgprot_t pgprot; /* VM_PROT_* | PMAP_* cacheability flags */ - int ret; - - /* Thanks, uvm, but we don't need this lock. */ - rw_exit(uobj->vmobjlock); + int err, ret; - /* Copy-on-write mappings make no sense for the graphics aperture. */ - if (UVM_ET_ISCOPYONWRITE(ufi->entry)) { - ret = -EIO; - goto out0; - } - - /* Try to lock the buffer. */ - ret = ttm_bo_reserve(bo, true, true, NULL); - if (ret) { - if (ret != -EBUSY) - goto out0; - /* - * It's currently locked. Unlock the fault, wait for - * it, and start over. - */ - uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, NULL); - if (!dma_resv_lock_interruptible(bo->base.resv, NULL)) - dma_resv_unlock(bo->base.resv); - - return ERESTART; - } - - /* drm prime buffers are not mappable. XXX Catch this earlier? */ - if (bo->ttm && ISSET(bo->ttm->page_flags, TTM_PAGE_FLAG_SG)) { - ret = -EINVAL; - goto out1; - } + /* + * Refuse to fault imported pages. This should be handled + * (if at all) by redirecting mmap to the exporter. + */ + if (bo->ttm && (bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) + return EINVAL; /* SIGBUS */ - /* Notify the driver of a fault if it wants. */ if (bdev->driver->fault_reserve_notify) { - ret = (*bdev->driver->fault_reserve_notify)(bo); - if (ret) { - if (ret == -ERESTART) - ret = -EIO; - goto out1; + struct dma_fence *moving = dma_fence_get(bo->moving); + + err = bdev->driver->fault_reserve_notify(bo); + switch (err) { + case 0: + break; + case -EBUSY: + case -ERESTARTSYS: + return 0; /* retry access in userland */ + default: + return EINVAL; /* SIGBUS */ } - } - ret = ttm_bo_uvm_fault_idle(bo, ufi); - if (ret) { - KASSERT(ret == -ERESTART || ret == -EFAULT); - goto out1; + if (bo->moving != moving) { + spin_lock(&ttm_bo_glob.lru_lock); + ttm_bo_move_to_lru_tail(bo, NULL); + spin_unlock(&ttm_bo_glob.lru_lock); + } + dma_fence_put(moving); } - ret = ttm_mem_io_lock(man, true); - if (ret) { - ret = -EIO; - goto out1; - } - ret = ttm_mem_io_reserve_vm(bo); - if (ret) { - ret = -EIO; - goto out2; + /* + * Wait for buffer data in transit, due to a pipelined + * move. + */ + ret = ttm_bo_vm_fault_idle(bo, vmf); + if (__predict_false(ret != 0)) + return ret; + + err = ttm_mem_io_lock(man, true); + if (__predict_false(err != 0)) + return 0; /* retry access in userland */ + err = ttm_mem_io_reserve_vm(bo); + if (__predict_false(err)) { + ret = EINVAL; /* SIGBUS */ + goto out_io_unlock; } - vm_prot = ufi->entry->protection; - if (bo->mem.bus.is_iomem) { - u.base = (bo->mem.bus.base + bo->mem.bus.offset); - size = bo->mem.bus.size; - pgprot = ttm_io_prot(bo->mem.placement, vm_prot); - } else { + vm_prot = vmf->entry->protection; + if (!bo->mem.bus.is_iomem) { struct ttm_operation_ctx ctx = { .interruptible = false, .no_wait_gpu = false, - .flags = TTM_OPT_FLAG_FORCE_ALLOC, + .flags = TTM_OPT_FLAG_FORCE_ALLOC }; + u.ttm = bo->ttm; size = (size_t)bo->ttm->num_pages << PAGE_SHIFT; if (ISSET(bo->mem.placement, TTM_PL_FLAG_CACHED)) pgprot = vm_prot; else pgprot = ttm_io_prot(bo->mem.placement, vm_prot); - if (ttm_tt_populate(u.ttm, &ctx)) { - ret = -ENOMEM; - goto out2; + if (ttm_tt_populate(bo->ttm, &ctx)) { + ret = ENOMEM; + goto out_io_unlock; } + } else { + u.base = (bo->mem.bus.base + bo->mem.bus.offset); + size = bo->mem.bus.size; + pgprot = ttm_io_prot(bo->mem.placement, vm_prot); } - KASSERT(ufi->entry->start <= vaddr); - KASSERT((ufi->entry->offset & (PAGE_SIZE - 1)) == 0); - KASSERT(ufi->entry->offset <= size); - KASSERT((vaddr - ufi->entry->start) <= (size - ufi->entry->offset)); + KASSERT(vmf->entry->start <= vaddr); + KASSERT((vmf->entry->offset & (PAGE_SIZE - 1)) == 0); + KASSERT(vmf->entry->offset <= size); + KASSERT((vaddr - vmf->entry->start) <= (size - vmf->entry->offset)); KASSERTMSG(((size_t)npages << PAGE_SHIFT <= - ((size - ufi->entry->offset) - (vaddr - ufi->entry->start))), + ((size - vmf->entry->offset) - (vaddr - vmf->entry->start))), "vaddr=%jx npages=%d bo=%p is_iomem=%d size=%zu" " start=%jx offset=%jx", (uintmax_t)vaddr, npages, bo, (int)bo->mem.bus.is_iomem, size, - (uintmax_t)ufi->entry->start, (uintmax_t)ufi->entry->offset); - uoffset = (ufi->entry->offset + (vaddr - ufi->entry->start)); + (uintmax_t)vmf->entry->start, (uintmax_t)vmf->entry->offset); + uoffset = (vmf->entry->offset + (vaddr - vmf->entry->start)); startpage = (uoffset >> PAGE_SHIFT); for (i = 0; i < npages; i++) { paddr_t paddr; @@ -201,65 +287,55 @@ ttm_bo_uvm_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, paddr = pmap_phys_address(cookie); } - ret = -pmap_enter(ufi->orig_map->pmap, vaddr + i*PAGE_SIZE, + ret = pmap_enter(vmf->orig_map->pmap, vaddr + i*PAGE_SIZE, paddr, vm_prot, (PMAP_CANFAIL | pgprot)); - if (ret) - goto out3; + if (ret) { + KASSERT(ret != ERESTART); + break; + } } - -out3: pmap_update(ufi->orig_map->pmap); -out2: ttm_mem_io_unlock(man); -out1: ttm_bo_unreserve(bo); -out0: uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, NULL); - /* XXX errno Linux->NetBSD */ - return -ret; + pmap_update(vmf->orig_map->pmap); + ret = 0; /* retry access in userland */ +out_io_unlock: + ttm_mem_io_unlock(man); + KASSERT(ret != ERESTART); + return ret; } -static int -ttm_bo_uvm_fault_idle(struct ttm_buffer_object *bo, struct uvm_faultinfo *ufi) +int +ttm_bo_uvm_fault(struct uvm_faultinfo *vmf, vaddr_t vaddr, + struct vm_page **pps, int npages, int centeridx, vm_prot_t access_type, + int flags) { - int err, ret = 0; - - if (__predict_true(!bo->moving)) - goto out_unlock; - - /* - * Quick non-stalling check for idle. - */ - if (dma_fence_is_signaled(bo->moving)) - goto out_clear; + struct uvm_object *const uobj = vmf->entry->object.uvm_obj; + struct ttm_buffer_object *const bo = container_of(uobj, + struct ttm_buffer_object, uvmobj); + int ret; - /* - * If possible, avoid waiting for GPU with mmap_sem - * held. - * XXX Need to integrate this properly into caller's - * error branches so it doesn't uvmfault_unlockall twice. - */ - if (0) { - ret = -ERESTART; + /* Thanks, uvm, but we don't need this lock. */ + rw_exit(uobj->vmobjlock); - ttm_bo_get(bo); - uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, NULL); - (void) dma_fence_wait(bo->moving, true); - dma_resv_unlock(bo->base.resv); - ttm_bo_put(bo); - goto out_unlock; + /* Copy-on-write mappings make no sense for the graphics aperture. */ + if (UVM_ET_ISCOPYONWRITE(vmf->entry)) { + ret = EINVAL; /* SIGBUS */ + goto out; } - /* - * Ordinary wait. - */ - err = dma_fence_wait(bo->moving, true); - if (__predict_false(ret != 0)) { - ret = (err != -ERESTARTSYS) ? -EFAULT : -ERESTART; - goto out_unlock; + ret = ttm_bo_vm_reserve(bo, vmf); + if (ret) { + /* ttm_bo_vm_reserve already unlocked on ERESTART */ + KASSERTMSG(ret == ERESTART, "ret=%d", ret); + return ret; } -out_clear: - dma_fence_put(bo->moving); - bo->moving = NULL; + ret = ttm_bo_uvm_fault_reserved(vmf, vaddr, pps, npages, centeridx, + access_type, flags); + if (ret == ERESTART) /* already unlocked on ERESTART */ + return ret; -out_unlock: + dma_resv_unlock(bo->base.resv); + +out: uvmfault_unlockall(vmf, vmf->entry->aref.ar_amap, NULL); return ret; } @@ -333,7 +409,8 @@ ttm_bo_uvm_lookup(struct ttm_bo_device *bdev, unsigned long startpage, node = drm_vma_offset_lookup_locked(bdev->vma_manager, startpage, npages); if (node != NULL) { - bo = container_of(node, struct ttm_buffer_object, base.vma_node); + bo = container_of(node, struct ttm_buffer_object, + base.vma_node); if (!kref_get_unless_zero(&bo->kref)) bo = NULL; } From b5ef3c6d53e2d467bfe198ef2fc96eb6ef0711e9 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sun, 19 May 2024 14:23:18 +0000 Subject: [PATCH 2/5] ttm: Respect PGO_ALLPAGES. Not sure this is useful but it reduces XXX's and makes this match udv_fault better so it's easier to understand. --- sys/external/bsd/drm2/ttm/ttm_bo_vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c index 5b944ba7c785..a42e784f9a5d 100644 --- a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c +++ b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c @@ -272,7 +272,8 @@ ttm_bo_uvm_fault_reserved(struct uvm_faultinfo *vmf, vaddr_t vaddr, for (i = 0; i < npages; i++) { paddr_t paddr; - /* XXX PGO_ALLPAGES? */ + if ((flags & PGO_ALLPAGES) == 0 && i != centeridx) + continue; if (pps[i] == PGO_DONTCARE) continue; if (!bo->mem.bus.is_iomem) { From f0af70df88ab677b98ff1232256d3b560024217b Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sun, 19 May 2024 14:35:35 +0000 Subject: [PATCH 3/5] ttm: Sync cacheability flag logic with Linux. --- sys/external/bsd/drm2/ttm/ttm_bo_vm.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c index a42e784f9a5d..ff8ed0787258 100644 --- a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c +++ b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c @@ -183,8 +183,8 @@ ttm_bo_uvm_fault_reserved(struct uvm_faultinfo *vmf, vaddr_t vaddr, voff_t uoffset; /* offset in bytes into bo */ unsigned startpage; /* offset in pages into bo */ unsigned i; - vm_prot_t vm_prot; /* VM_PROT_* */ - pgprot_t pgprot; /* VM_PROT_* | PMAP_* cacheability flags */ + vm_prot_t vm_prot = vmf->entry->protection; /* VM_PROT_* */ + pgprot_t prot = vm_prot; /* VM_PROT_* | PMAP_* cacheability flags */ int err, ret; /* @@ -233,20 +233,17 @@ ttm_bo_uvm_fault_reserved(struct uvm_faultinfo *vmf, vaddr_t vaddr, goto out_io_unlock; } - vm_prot = vmf->entry->protection; + prot = ttm_io_prot(bo->mem.placement, prot); if (!bo->mem.bus.is_iomem) { struct ttm_operation_ctx ctx = { .interruptible = false, .no_wait_gpu = false, .flags = TTM_OPT_FLAG_FORCE_ALLOC + }; u.ttm = bo->ttm; size = (size_t)bo->ttm->num_pages << PAGE_SHIFT; - if (ISSET(bo->mem.placement, TTM_PL_FLAG_CACHED)) - pgprot = vm_prot; - else - pgprot = ttm_io_prot(bo->mem.placement, vm_prot); if (ttm_tt_populate(bo->ttm, &ctx)) { ret = ENOMEM; goto out_io_unlock; @@ -254,7 +251,6 @@ ttm_bo_uvm_fault_reserved(struct uvm_faultinfo *vmf, vaddr_t vaddr, } else { u.base = (bo->mem.bus.base + bo->mem.bus.offset); size = bo->mem.bus.size; - pgprot = ttm_io_prot(bo->mem.placement, vm_prot); } KASSERT(vmf->entry->start <= vaddr); @@ -287,9 +283,12 @@ ttm_bo_uvm_fault_reserved(struct uvm_faultinfo *vmf, vaddr_t vaddr, vm_prot, 0); paddr = pmap_phys_address(cookie); +#if 0 /* XXX Why no PMAP_* flags added here? */ + mmapflags = pmap_mmap_flags(cookie); +#endif } ret = pmap_enter(vmf->orig_map->pmap, vaddr + i*PAGE_SIZE, - paddr, vm_prot, (PMAP_CANFAIL | pgprot)); + paddr, vm_prot, PMAP_CANFAIL | prot); if (ret) { KASSERT(ret != ERESTART); break; From ef61dc44addd5904b9cd1b9e5a7a5cede7fcff4d Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sun, 19 May 2024 14:53:45 +0000 Subject: [PATCH 4/5] ttm: Add XXX about readahead fault failures. --- sys/external/bsd/drm2/ttm/ttm_bo_vm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c index ff8ed0787258..d80ec12194bb 100644 --- a/sys/external/bsd/drm2/ttm/ttm_bo_vm.c +++ b/sys/external/bsd/drm2/ttm/ttm_bo_vm.c @@ -290,6 +290,11 @@ ttm_bo_uvm_fault_reserved(struct uvm_faultinfo *vmf, vaddr_t vaddr, ret = pmap_enter(vmf->orig_map->pmap, vaddr + i*PAGE_SIZE, paddr, vm_prot, PMAP_CANFAIL | prot); if (ret) { + /* + * XXX Continue with ret=0 if i != centeridx, + * so we don't fail if only readahead pages + * fail? + */ KASSERT(ret != ERESTART); break; } From 1a05590d2e9971259d39fadaf58992236965bb56 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Mon, 20 May 2024 02:05:52 +0000 Subject: [PATCH 5/5] i915: Reduce diff in fault routine. Omit needless EINTR interception. This is now already handled by i915_error_to_vmf_fault. --- .../drm2/dist/drm/i915/gem/i915_gem_mman.c | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c index 5e1b054cf386..d5d240db673a 100644 --- a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c +++ b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c @@ -252,14 +252,14 @@ compute_partial_view(const struct drm_i915_gem_object *obj, */ int pmap_enter_default(pmap_t, vaddr_t, paddr_t, vm_prot_t, unsigned); #define pmap_enter pmap_enter_default +#endif +#ifdef __NetBSD__ static int i915_error_to_vmf_fault(int err) -{ - return err; -} #else static vm_fault_t i915_error_to_vmf_fault(int err) +#endif { switch (err) { default: @@ -269,11 +269,19 @@ static vm_fault_t i915_error_to_vmf_fault(int err) case -EFAULT: /* purged object */ case -ENODEV: /* bad object, how did you get here! */ case -ENXIO: /* unable to access backing store (on device) */ +#ifdef __NetBSD__ + return EINVAL; /* SIGBUS */ +#else return VM_FAULT_SIGBUS; +#endif case -ENOSPC: /* shmemfs allocation failure */ case -ENOMEM: /* our allocation failure */ +#ifdef __NetBSD__ + return ENOMEM; +#else return VM_FAULT_OOM; +#endif case 0: case -EAGAIN: @@ -284,10 +292,13 @@ static vm_fault_t i915_error_to_vmf_fault(int err) * EBUSY is ok: this just means that another thread * already did the job. */ +#ifdef __NetBSD__ + return 0; /* retry access in userland */ +#else return VM_FAULT_NOPAGE; +#endif } } -#endif #ifdef __NetBSD__ static int @@ -313,7 +324,7 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) /* Sanity check that we allow writing into this object */ if (unlikely(i915_gem_object_is_readonly(obj) && write)) #ifdef __NetBSD__ - return -EFAULT; + return EINVAL; /* SIGBUS */ #else return VM_FAULT_SIGBUS; #endif @@ -403,7 +414,7 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) /* Sanity check that we allow writing into this object */ if (i915_gem_object_is_readonly(obj) && write) #ifdef __NetBSD__ - return -EFAULT; + return EINVAL; /* SIGBUS */ #else return VM_FAULT_SIGBUS; #endif @@ -548,7 +559,6 @@ i915_gem_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, struct vm_page **pps, struct i915_mmap_offset *mmo = container_of(uobj, struct i915_mmap_offset, uobj); struct drm_i915_gem_object *obj = mmo->obj; - bool pinned = false; int error; KASSERT(rw_lock_held(obj->base.filp->vmobjlock)); @@ -568,22 +578,15 @@ i915_gem_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, struct vm_page **pps, */ rw_exit(obj->base.filp->vmobjlock); - /* XXX errno Linux->NetBSD */ - error = -i915_gem_object_pin_pages(obj); - if (error) - goto out; - pinned = true; - switch (mmo->mmap_type) { case I915_MMAP_TYPE_WC: case I915_MMAP_TYPE_WB: case I915_MMAP_TYPE_UC: - /* XXX errno Linux->NetBSD */ - error = -vm_fault_cpu(ufi, mmo, vaddr, pps, npages, centeridx, + error = vm_fault_cpu(ufi, mmo, vaddr, pps, npages, centeridx, flags); break; case I915_MMAP_TYPE_GTT: - error = -vm_fault_gtt(ufi, mmo, vaddr, pps, npages, centeridx, + error = vm_fault_gtt(ufi, mmo, vaddr, pps, npages, centeridx, flags); break; default: @@ -591,19 +594,7 @@ i915_gem_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, struct vm_page **pps, mmo->mmap_type); } -out: if (pinned) - i915_gem_object_unpin_pages(obj); uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, NULL); - - /* - * Remap EINTR to success, so that we return to userland. - * On the way out, we'll deliver the signal, and if the signal - * is not fatal then the user code which faulted will most likely - * fault again, and we'll come back here for another try. - */ - if (error == EINTR) - error = 0; - return error; }