Use buffer pager for NFS.
The pager, due to its construction, implements clustering for the page-ins. In particular, buildworld load demonstrates reduction of the READ RPCs from 39k down to 24k. No change in real or CPU time was observed. Discussed with, and measured by: bde No objections from: rmacklem Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
fc2c3afee0
commit
753a007f0d
sys/fs/nfsclient
@ -78,6 +78,40 @@ static int nfs_directio_write(struct vnode *vp, struct uio *uiop,
|
||||
/*
|
||||
* Vnode op for VM getpages.
|
||||
*/
|
||||
SYSCTL_DECL(_vfs_nfs);
|
||||
static int use_buf_pager = 1;
|
||||
SYSCTL_INT(_vfs_nfs, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN,
|
||||
&use_buf_pager, 0,
|
||||
"Use buffer pager instead of direct readrpc call");
|
||||
|
||||
static daddr_t
|
||||
ncl_gbp_getblkno(struct vnode *vp, vm_ooffset_t off)
|
||||
{
|
||||
|
||||
return (off / vp->v_bufobj.bo_bsize);
|
||||
}
|
||||
|
||||
static int
|
||||
ncl_gbp_getblksz(struct vnode *vp, daddr_t lbn)
|
||||
{
|
||||
struct nfsnode *np;
|
||||
u_quad_t nsize;
|
||||
int biosize, bcount;
|
||||
|
||||
np = VTONFS(vp);
|
||||
mtx_lock(&np->n_mtx);
|
||||
nsize = np->n_size;
|
||||
mtx_unlock(&np->n_mtx);
|
||||
|
||||
biosize = vp->v_bufobj.bo_bsize;
|
||||
bcount = biosize;
|
||||
if ((off_t)lbn * biosize >= nsize)
|
||||
bcount = 0;
|
||||
else if ((off_t)(lbn + 1) * biosize > nsize)
|
||||
bcount = nsize - (off_t)lbn * biosize;
|
||||
return (bcount);
|
||||
}
|
||||
|
||||
int
|
||||
ncl_getpages(struct vop_getpages_args *ap)
|
||||
{
|
||||
@ -126,6 +160,10 @@ ncl_getpages(struct vop_getpages_args *ap)
|
||||
} else
|
||||
mtx_unlock(&nmp->nm_mtx);
|
||||
|
||||
if (use_buf_pager)
|
||||
return (vfs_bio_getpages(vp, pages, npages, ap->a_rbehind,
|
||||
ap->a_rahead, ncl_gbp_getblkno, ncl_gbp_getblksz));
|
||||
|
||||
/*
|
||||
* If the requested page is partially valid, just return it and
|
||||
* allow the pager to zero-out the blanks. Partially valid pages
|
||||
|
@ -2569,13 +2569,20 @@ ncl_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred,
|
||||
static int
|
||||
nfs_strategy(struct vop_strategy_args *ap)
|
||||
{
|
||||
struct buf *bp = ap->a_bp;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
struct ucred *cr;
|
||||
|
||||
bp = ap->a_bp;
|
||||
vp = ap->a_vp;
|
||||
KASSERT(bp->b_vp == vp, ("missing b_getvp"));
|
||||
KASSERT(!(bp->b_flags & B_DONE),
|
||||
("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp));
|
||||
BUF_ASSERT_HELD(bp);
|
||||
|
||||
if (vp->v_type == VREG && bp->b_blkno == bp->b_lblkno)
|
||||
bp->b_blkno = bp->b_lblkno * (vp->v_bufobj.bo_bsize /
|
||||
DEV_BSIZE);
|
||||
if (bp->b_iocmd == BIO_READ)
|
||||
cr = bp->b_rcred;
|
||||
else
|
||||
@ -2587,8 +2594,8 @@ nfs_strategy(struct vop_strategy_args *ap)
|
||||
* otherwise just do it ourselves.
|
||||
*/
|
||||
if ((bp->b_flags & B_ASYNC) == 0 ||
|
||||
ncl_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
|
||||
(void) ncl_doio(ap->a_vp, bp, cr, curthread, 1);
|
||||
ncl_asyncio(VFSTONFS(vp->v_mount), bp, NOCRED, curthread))
|
||||
(void) ncl_doio(vp, bp, cr, curthread, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user