diff options
| author | Trond Myklebust <trond.myklebust@fys.uio.no> | 2002-07-26 00:00:14 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-07-26 00:00:14 -0700 |
| commit | ff3cc6a09251f437f18029a7bd96f6bd55bccfb2 (patch) | |
| tree | 48bf0e097f28e00f103858a7cc264522b0381726 | |
| parent | 0be53f272bd1e45378781314423bf238f0493f74 (diff) | |
[PATCH] increase socket buffer for RPC over UDP
Make RPC over UDP use a socket buffer size that is large enough to fit
all the messages. Congestion control is in any case handled by the Van
Jacobson algoritm, and we need to work around a bug in
ip_build_xmit_slow() w.r.t. fragmentation when there is insufficient
buffer memory to fit the entire message.
| -rw-r--r-- | fs/nfs/inode.c | 3 | ||||
| -rw-r--r-- | include/linux/sunrpc/clnt.h | 1 | ||||
| -rw-r--r-- | include/linux/sunrpc/xprt.h | 4 | ||||
| -rw-r--r-- | net/sunrpc/clnt.c | 14 | ||||
| -rw-r--r-- | net/sunrpc/sunrpc_syms.c | 1 | ||||
| -rw-r--r-- | net/sunrpc/xprt.c | 21 |
6 files changed, 43 insertions, 1 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 40ad8333e475..ce7ad8ae64a3 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -425,7 +425,8 @@ int nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int sile goto failure_kill_reqlist; } - /* We're airborne */ + /* We're airborne Set socket buffersize */ + rpc_setbufsize(clnt, server->wsize + 100, server->rsize + 100); /* Check whether to start the lockd process */ if (!(server->flags & NFS_MOUNT_NONLM)) diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index d278df00ecb9..92fa9755592e 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -127,6 +127,7 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, void rpc_restart_call(struct rpc_task *); void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset); void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset); +void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); static __inline__ int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags) diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index e3c7a6b9c5ba..c9b93c6a7a27 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -122,6 +122,9 @@ struct rpc_xprt { unsigned long cong; /* current congestion */ unsigned long cwnd; /* congestion window */ + unsigned int rcvsize, /* socket receive buffer size */ + sndsize; /* socket send buffer size */ + struct rpc_wait_queue sending; /* requests waiting to send */ struct rpc_wait_queue resend; /* requests waiting to resend */ struct rpc_wait_queue pending; /* requests in flight */ @@ -177,6 +180,7 @@ int xprt_adjust_timeout(struct rpc_timeout *); void xprt_release(struct rpc_task *); void xprt_reconnect(struct rpc_task *); int xprt_clear_backlog(struct rpc_xprt *); +void xprt_sock_setbufsize(struct rpc_xprt *); #define XPRT_CONNECT 0 diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 4d98ac870e85..001c2253ec8f 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -335,6 +335,20 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags) rpcproc_count(task->tk_client, task->tk_msg.rpc_proc)++; } +void +rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize) +{ + struct rpc_xprt *xprt = clnt->cl_xprt; + + xprt->sndsize = 0; + if (sndsize) + xprt->sndsize = sndsize + RPC_SLACK_SPACE; + xprt->rcvsize = 0; + if (rcvsize) + xprt->rcvsize = rcvsize + RPC_SLACK_SPACE; + xprt_sock_setbufsize(xprt); +} + /* * Restart an (async) RPC call. Usually called from within the * exit handler. diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index d6bdb4630d2d..2b41eb87de5d 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -50,6 +50,7 @@ EXPORT_SYMBOL(rpc_clnt_sigmask); EXPORT_SYMBOL(rpc_clnt_sigunmask); EXPORT_SYMBOL(rpc_delay); EXPORT_SYMBOL(rpc_restart_call); +EXPORT_SYMBOL(rpc_setbufsize); /* Client transport */ EXPORT_SYMBOL(xprt_create_proto); diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index d805ed6c08d1..3d4ba37b48e1 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1421,6 +1421,27 @@ xprt_bind_socket(struct rpc_xprt *xprt, struct socket *sock) } /* + * Set socket buffer length + */ +void +xprt_sock_setbufsize(struct rpc_xprt *xprt) +{ + struct sock *sk = xprt->inet; + + if (xprt->stream) + return; + if (xprt->rcvsize) { + sk->userlocks |= SOCK_RCVBUF_LOCK; + sk->rcvbuf = xprt->rcvsize * RPC_MAXCONG * 2; + } + if (xprt->sndsize) { + sk->userlocks |= SOCK_SNDBUF_LOCK; + sk->sndbuf = xprt->sndsize * RPC_MAXCONG * 2; + sk->write_space(sk); + } +} + +/* * Create a client socket given the protocol and peer address. */ static struct socket * |
