Date: Fri, 6 Mar 2015 14:15:30 +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: r279688 - in head/sys: sys vm Message-ID: <201503061415.t26EFUUM066099@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Fri Mar 6 14:15:30 2015 New Revision: 279688 URL: https://svnweb.freebsd.org/changeset/base/279688 Log: - In vnode_pager_generic_getpages() use different free counters for synchronous and asynchronous requests. The latter can saturate the I/O and we do not want them to affect regular paging. - Allocate the pbuf at the very beginning of the function, so that if we are low on certain kind of pbufs don't even proceed to BMAP, but sleep. Reviewed by: kib Sponsored by: Nginx, Inc. Sponsored by: Netflix Modified: head/sys/sys/buf.h head/sys/vm/vm_pager.c head/sys/vm/vnode_pager.c Modified: head/sys/sys/buf.h ============================================================================== --- head/sys/sys/buf.h Fri Mar 6 11:27:58 2015 (r279687) +++ head/sys/sys/buf.h Fri Mar 6 14:15:30 2015 (r279688) @@ -475,6 +475,8 @@ extern struct buf *swbuf; /* Swap I/O b extern int nswbuf; /* Number of swap I/O buffer headers. */ extern int cluster_pbuf_freecnt; /* Number of pbufs for clusters */ extern int vnode_pbuf_freecnt; /* Number of pbufs for vnode pager */ +extern int vnode_async_pbuf_freecnt; /* Number of pbufs for vnode pager, + asynchronous reads */ extern caddr_t unmapped_buf; void runningbufwakeup(struct buf *); Modified: head/sys/vm/vm_pager.c ============================================================================== --- head/sys/vm/vm_pager.c Fri Mar 6 11:27:58 2015 (r279687) +++ head/sys/vm/vm_pager.c Fri Mar 6 14:15:30 2015 (r279688) @@ -215,6 +215,7 @@ vm_pager_bufferinit() cluster_pbuf_freecnt = nswbuf / 2; vnode_pbuf_freecnt = nswbuf / 2 + 1; + vnode_async_pbuf_freecnt = nswbuf / 2; } /* Modified: head/sys/vm/vnode_pager.c ============================================================================== --- head/sys/vm/vnode_pager.c Fri Mar 6 11:27:58 2015 (r279687) +++ head/sys/vm/vnode_pager.c Fri Mar 6 14:15:30 2015 (r279688) @@ -104,6 +104,7 @@ struct pagerops vnodepagerops = { }; int vnode_pbuf_freecnt; +int vnode_async_pbuf_freecnt; /* Create the VM system backing object for this vnode */ int @@ -751,7 +752,7 @@ vnode_pager_generic_getpages(struct vnod { vm_object_t object; off_t foff; - int i, j, size, bsize, first; + int i, j, size, bsize, first, *freecnt; daddr_t firstaddr, reqblock; struct bufobj *bo; int runpg; @@ -771,6 +772,10 @@ vnode_pager_generic_getpages(struct vnod bsize = vp->v_mount->mnt_stat.f_iosize; foff = IDX_TO_OFF(m[reqpage]->pindex); + freecnt = iodone != NULL ? + &vnode_async_pbuf_freecnt : &vnode_pbuf_freecnt; + bp = getpbuf(freecnt); + /* * Get the underlying device blocks for the file with VOP_BMAP(). * If the file system doesn't support VOP_BMAP, use old way of @@ -778,8 +783,8 @@ vnode_pager_generic_getpages(struct vnod */ error = VOP_BMAP(vp, foff / bsize, &bo, &reqblock, NULL, NULL); if (error == EOPNOTSUPP) { + relpbuf(bp, freecnt); VM_OBJECT_WLOCK(object); - for (i = 0; i < count; i++) if (i != reqpage) { vm_page_lock(m[i]); @@ -792,6 +797,7 @@ vnode_pager_generic_getpages(struct vnod VM_OBJECT_WUNLOCK(object); return (error); } else if (error != 0) { + relpbuf(bp, freecnt); vm_pager_free_nonreq(object, m, reqpage, count); return (VM_PAGER_ERROR); @@ -802,6 +808,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); PCPU_INC(cnt.v_vnodein); PCPU_INC(cnt.v_vnodepgsin); @@ -820,9 +827,11 @@ vnode_pager_generic_getpages(struct vnod * media. */ if (m[reqpage]->valid == VM_PAGE_BITS_ALL) { + relpbuf(bp, freecnt); vm_pager_free_nonreq(object, m, reqpage, count); return (VM_PAGER_OK); } else if (reqblock == -1) { + relpbuf(bp, freecnt); pmap_zero_page(m[reqpage]); KASSERT(m[reqpage]->dirty == 0, ("vnode_pager_generic_getpages: page %p is dirty", m)); @@ -853,6 +862,7 @@ vnode_pager_generic_getpages(struct vnod for (first = 0, i = 0; i < count; i = runend) { 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) { @@ -941,7 +951,6 @@ vnode_pager_generic_getpages(struct vnod size = (size + secmask) & ~secmask; } - bp = getpbuf(&vnode_pbuf_freecnt); bp->b_kvaalloc = bp->b_data; /* @@ -1016,7 +1025,7 @@ vnode_pager_generic_getpages_done_async( bp->b_pages[i] = NULL; bp->b_vp = NULL; pbrelbo(bp); - relpbuf(bp, &vnode_pbuf_freecnt); + relpbuf(bp, &vnode_async_pbuf_freecnt); } static int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503061415.t26EFUUM066099>