From e9855d6b54147025cc775ee187d98826205a5344 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 8 Mar 2004 23:52:53 +0000 Subject: [PATCH] Increase the default socket buffer for NFS to deal with linux bugs and to improve performance. The default nfs socket buffer is now 65535 bytes, settable with a sysctl (vfs.nfs.soreserve). It is my belief that when large data block sizes (32K) are negotiated, the larger socket buff should improve read-ahead performance and reduce nfs socket buffer lock contention that occurs with multiple nfsd's. I was able to do some testing over GigE and it did seem to help, but problems with one of the machines made the tests less then reliable. Credits: Richard Sharpe originally encountered issues with linux NFS clients that were traced to linux doing a bad job in its delayed-ack code. David Rhodus created an initial patch which I used as a partial basis for this commit (circa October 2003). --- sys/sys/socketvar.h | 5 +++-- sys/vfs/nfs/nfs_syscalls.c | 18 +++++++++++++++++- sys/vfs/nfs/nfsproto.h | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 3dbf21a964..e554977100 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -32,7 +32,7 @@ * * @(#)socketvar.h 8.3 (Berkeley) 2/19/95 * $FreeBSD: src/sys/sys/socketvar.h,v 1.46.2.10 2003/08/24 08:24:39 hsu Exp $ - * $DragonFly: src/sys/sys/socketvar.h,v 1.9 2004/03/05 16:57:16 hsu Exp $ + * $DragonFly: src/sys/sys/socketvar.h,v 1.10 2004/03/08 23:52:51 dillon Exp $ */ #ifndef _SYS_SOCKETVAR_H_ @@ -288,7 +288,8 @@ MALLOC_DECLARE(M_ACCF); #endif extern int maxsockets; -extern u_long sb_max; +extern u_long sb_max; /* nominal limit */ +extern u_long sb_max_adj; /* actual limit used by sbreserve() */ extern struct vm_zone *socket_zone; extern so_gen_t so_gencnt; diff --git a/sys/vfs/nfs/nfs_syscalls.c b/sys/vfs/nfs/nfs_syscalls.c index b9efffa243..0d6b0ce3b4 100644 --- a/sys/vfs/nfs/nfs_syscalls.c +++ b/sys/vfs/nfs/nfs_syscalls.c @@ -35,7 +35,7 @@ * * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 * $FreeBSD: src/sys/nfs/nfs_syscalls.c,v 1.58.2.1 2000/11/26 02:30:06 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_syscalls.c,v 1.12 2004/03/05 16:57:16 hsu Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_syscalls.c,v 1.13 2004/03/08 23:52:53 dillon Exp $ */ #include @@ -116,6 +116,8 @@ static int nfs_privport = 0; SYSCTL_INT(_vfs_nfs, NFS_NFSPRIVPORT, nfs_privport, CTLFLAG_RW, &nfs_privport, 0, ""); SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay, CTLFLAG_RW, &nfsrvw_procrastinate, 0, ""); SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate_v3, 0, ""); +static int nfs_soreserve = 65535; +SYSCTL_INT(_vfs_nfs, OID_AUTO, soreserve, CTLFLAG_RW, &nfs_soreserve, 0, ""); /* * NFS server system calls @@ -336,10 +338,24 @@ nfssvc_addsock(struct file *fp, struct sockaddr *mynam, struct thread *td) } } #endif + /* + * Reserve buffer space in the socket. Note that due to bugs in + * Linux's delayed-ack code, serious performance degredation may + * occur with linux hosts if the minimum is used. + */ if (so->so_type == SOCK_STREAM) siz = NFS_MAXPACKET + sizeof (u_long); else siz = NFS_MAXPACKET; + if (siz < nfs_soreserve) + siz = nfs_soreserve; + if (siz > sb_max_adj) { + printf("Warning: vfs.nfs.soreserve (%d) " + "limited to adjusted sb_max (%ld)\n", + nfs_soreserve, sb_max_adj); + siz = sb_max_adj; + } + error = soreserve(so, siz, siz, &td->td_proc->p_rlimit[RLIMIT_SBSIZE]); if (error) { if (mynam != NULL) diff --git a/sys/vfs/nfs/nfsproto.h b/sys/vfs/nfs/nfsproto.h index 54a9ed4c11..cd81a91291 100644 --- a/sys/vfs/nfs/nfsproto.h +++ b/sys/vfs/nfs/nfsproto.h @@ -35,7 +35,7 @@ * * @(#)nfsproto.h 8.2 (Berkeley) 3/30/95 * $FreeBSD: src/sys/nfs/nfsproto.h,v 1.7 1999/08/28 00:50:03 peter Exp $ - * $DragonFly: src/sys/vfs/nfs/nfsproto.h,v 1.2 2003/06/17 04:28:54 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfsproto.h,v 1.3 2004/03/08 23:52:53 dillon Exp $ */ #ifndef _NFS_NFSPROTO_H_ -- 2.41.0