Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Nov 2016 10:58:24 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r308980 - head/sys/fs/nfsclient
Message-ID:  <201611221058.uAMAwOhB092085@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Nov 22 10:58:24 2016
New Revision: 308980
URL: https://svnweb.freebsd.org/changeset/base/308980

Log:
  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

Modified:
  head/sys/fs/nfsclient/nfs_clbio.c
  head/sys/fs/nfsclient/nfs_clvnops.c

Modified: head/sys/fs/nfsclient/nfs_clbio.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clbio.c	Tue Nov 22 10:52:58 2016	(r308979)
+++ head/sys/fs/nfsclient/nfs_clbio.c	Tue Nov 22 10:58:24 2016	(r308980)
@@ -78,6 +78,40 @@ static int nfs_directio_write(struct vno
 /*
  * 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 *a
 	} 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

Modified: head/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c	Tue Nov 22 10:52:58 2016	(r308979)
+++ head/sys/fs/nfsclient/nfs_clvnops.c	Tue Nov 22 10:58:24 2016	(r308980)
@@ -2569,13 +2569,20 @@ ncl_commit(struct vnode *vp, u_quad_t of
 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 *a
 	 * 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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611221058.uAMAwOhB092085>