Date: Tue, 17 Mar 2015 19:19:19 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r280189 - in head/sys: fs/nfsclient vm Message-ID: <201503171919.t2HJJJN9060326@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Tue Mar 17 19:19:19 2015 New Revision: 280189 URL: https://svnweb.freebsd.org/changeset/base/280189 Log: o Enhance vm_pager_free_nonreq() function: - Allow to call the function with vm object lock held. - Allow to specify reqpage that doesn't match any page in the region, meaning freeing all pages. o Utilize the new function in couple more places in vnode pager. Reviewed by: alc, kib Sponsored by: Netflix Sponsored by: Nginx, Inc. Modified: head/sys/fs/nfsclient/nfs_clbio.c head/sys/vm/vm_pager.c head/sys/vm/vm_pager.h head/sys/vm/vnode_pager.c Modified: head/sys/fs/nfsclient/nfs_clbio.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clbio.c Tue Mar 17 19:16:51 2015 (r280188) +++ head/sys/fs/nfsclient/nfs_clbio.c Tue Mar 17 19:19:19 2015 (r280189) @@ -140,7 +140,8 @@ ncl_getpages(struct vop_getpages_args *a * can only occur at the file EOF. */ if (pages[ap->a_reqpage]->valid != 0) { - vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages); + vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages, + FALSE); return (VM_PAGER_OK); } @@ -172,7 +173,8 @@ ncl_getpages(struct vop_getpages_args *a if (error && (uio.uio_resid == count)) { ncl_printf("nfs_getpages: error %d\n", error); - vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages); + vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages, + FALSE); return (VM_PAGER_ERROR); } Modified: head/sys/vm/vm_pager.c ============================================================================== --- head/sys/vm/vm_pager.c Tue Mar 17 19:16:51 2015 (r280188) +++ head/sys/vm/vm_pager.c Tue Mar 17 19:19:19 2015 (r280189) @@ -283,29 +283,35 @@ vm_pager_object_lookup(struct pagerlst * } /* - * Free the non-requested pages from the given array. + * Free the non-requested pages from the given array. To remove all pages, + * caller should provide out of range reqpage number. */ void vm_pager_free_nonreq(vm_object_t object, vm_page_t ma[], int reqpage, - int npages) + int npages, boolean_t object_locked) { + enum { UNLOCKED, CALLER_LOCKED, INTERNALLY_LOCKED } locked; int i; - boolean_t object_locked; - VM_OBJECT_ASSERT_UNLOCKED(object); - object_locked = FALSE; + if (object_locked) { + VM_OBJECT_ASSERT_WLOCKED(object); + locked = CALLER_LOCKED; + } else { + VM_OBJECT_ASSERT_UNLOCKED(object); + locked = UNLOCKED; + } for (i = 0; i < npages; ++i) { if (i != reqpage) { - if (!object_locked) { + if (locked == UNLOCKED) { VM_OBJECT_WLOCK(object); - object_locked = TRUE; + locked = INTERNALLY_LOCKED; } vm_page_lock(ma[i]); vm_page_free(ma[i]); vm_page_unlock(ma[i]); } } - if (object_locked) + if (locked == INTERNALLY_LOCKED) VM_OBJECT_WUNLOCK(object); } Modified: head/sys/vm/vm_pager.h ============================================================================== --- head/sys/vm/vm_pager.h Tue Mar 17 19:16:51 2015 (r280188) +++ head/sys/vm/vm_pager.h Tue Mar 17 19:19:19 2015 (r280189) @@ -113,7 +113,7 @@ static __inline boolean_t vm_pager_has_p void vm_pager_init(void); vm_object_t vm_pager_object_lookup(struct pagerlst *, void *); void vm_pager_free_nonreq(vm_object_t object, vm_page_t ma[], int reqpage, - int npages); + int npages, boolean_t object_locked); /* * vm_page_get_pages: Modified: head/sys/vm/vnode_pager.c ============================================================================== --- head/sys/vm/vnode_pager.c Tue Mar 17 19:16:51 2015 (r280188) +++ head/sys/vm/vnode_pager.c Tue Mar 17 19:19:19 2015 (r280189) @@ -732,7 +732,7 @@ vnode_pager_local_getpages0(struct vnode */ if (mreq->valid != 0) { vm_pager_free_nonreq(mreq->object, m, reqpage, - round_page(bytecount) / PAGE_SIZE); + round_page(bytecount) / PAGE_SIZE, FALSE); if (iodone != NULL) iodone(arg, m, reqpage, 0); return (VM_PAGER_OK); @@ -806,7 +806,7 @@ vnode_pager_generic_getpages(struct vnod return (error); } else if (error != 0) { relpbuf(bp, freecnt); - vm_pager_free_nonreq(object, m, reqpage, count); + vm_pager_free_nonreq(object, m, reqpage, count, FALSE); return (VM_PAGER_ERROR); /* @@ -817,7 +817,7 @@ vnode_pager_generic_getpages(struct vnod } else if ((PAGE_SIZE / bsize) > 1 && (vp->v_mount->mnt_stat.f_type != nfs_mount_type)) { relpbuf(bp, freecnt); - vm_pager_free_nonreq(object, m, reqpage, count); + vm_pager_free_nonreq(object, m, reqpage, count, FALSE); PCPU_INC(cnt.v_vnodein); PCPU_INC(cnt.v_vnodepgsin); return vnode_pager_input_smlfs(object, m[reqpage]); @@ -836,7 +836,7 @@ vnode_pager_generic_getpages(struct vnod */ if (m[reqpage]->valid == VM_PAGE_BITS_ALL) { relpbuf(bp, freecnt); - vm_pager_free_nonreq(object, m, reqpage, count); + vm_pager_free_nonreq(object, m, reqpage, count, FALSE); return (VM_PAGER_OK); } else if (reqblock == -1) { relpbuf(bp, freecnt); @@ -845,12 +845,7 @@ vnode_pager_generic_getpages(struct vnod ("vnode_pager_generic_getpages: page %p is dirty", m)); VM_OBJECT_WLOCK(object); m[reqpage]->valid = VM_PAGE_BITS_ALL; - for (i = 0; i < count; i++) - if (i != reqpage) { - vm_page_lock(m[i]); - vm_page_free(m[i]); - vm_page_unlock(m[i]); - } + vm_pager_free_nonreq(object, m, reqpage, count, TRUE); VM_OBJECT_WUNLOCK(object); return (VM_PAGER_OK); } else if (m[reqpage]->valid != 0) { @@ -871,14 +866,9 @@ vnode_pager_generic_getpages(struct vnod if (vnode_pager_addr(vp, IDX_TO_OFF(m[i]->pindex), &firstaddr, &runpg) != 0) { relpbuf(bp, freecnt); - VM_OBJECT_WLOCK(object); - for (; i < count; i++) - if (i != reqpage) { - vm_page_lock(m[i]); - vm_page_free(m[i]); - vm_page_unlock(m[i]); - } - VM_OBJECT_WUNLOCK(object); + /* The requested page may be out of range. */ + vm_pager_free_nonreq(object, m + i, reqpage - i, + count - i, FALSE); return (VM_PAGER_ERROR); } if (firstaddr == -1) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503171919.t2HJJJN9060326>