From 2bea90d43a050bbc4021d44e59beb34f384438db Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 29 Mar 2007 16:47:53 -0400 Subject: SUNRPC: RPC buffer size estimates are too large The RPC buffer size estimation logic in net/sunrpc/clnt.c always significantly overestimates the requirements for the buffer size. A little instrumentation demonstrated that in fact rpc_malloc was never allocating the buffer from the mempool, but almost always called kmalloc. To compute the size of the RPC buffer more precisely, split p_bufsiz into two fields; one for the argument size, and one for the result size. Then, compute the sum of the exact call and reply header sizes, and split the RPC buffer precisely between the two. That should keep almost all RPC buffers within the 2KiB buffer mempool limit. And, we can finally be rid of RPC_SLACK_SPACE! Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 3 ++- include/linux/sunrpc/xprt.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux/sunrpc') diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index c7a78eef2b4f..32c48a0b0d71 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -84,7 +84,8 @@ struct rpc_procinfo { u32 p_proc; /* RPC procedure number */ kxdrproc_t p_encode; /* XDR encode function */ kxdrproc_t p_decode; /* XDR decode function */ - unsigned int p_bufsiz; /* req. buffer size */ + unsigned int p_arglen; /* argument hdr length (u32) */ + unsigned int p_replen; /* reply hdr length (u32) */ unsigned int p_count; /* call count */ unsigned int p_timer; /* Which RTT timer to use */ u32 p_statidx; /* Which procedure to account */ diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index f780e72fc417..7aa29502b187 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -84,7 +84,9 @@ struct rpc_rqst { struct list_head rq_list; __u32 * rq_buffer; /* XDR encode buffer */ - size_t rq_bufsize; + size_t rq_bufsize, + rq_callsize, + rq_rcvsize; struct xdr_buf rq_private_buf; /* The receive buffer * used in the softirq. -- cgit v1.2.2 From c5a4dd8b7c15927a8fbff83171b57cad675a79b9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 29 Mar 2007 16:47:58 -0400 Subject: SUNRPC: Eliminate side effects from rpc_malloc Currently rpc_malloc sets req->rq_buffer internally. Make this a more generic interface: return a pointer to the new buffer (or NULL) and make the caller set req->rq_buffer and req->rq_bufsize. This looks much more like kmalloc and eliminates the side effects. To fix a potential deadlock, this patch also replaces GFP_NOFS with GFP_NOWAIT in rpc_malloc. This prevents async RPCs from sleeping outside the RPC's task scheduler while allocating their buffer. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/sunrpc/sched.h | 2 +- include/linux/sunrpc/xprt.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux/sunrpc') diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 3069ecca0129..2047fb202a13 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -264,7 +264,7 @@ struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *); void rpc_wake_up_status(struct rpc_wait_queue *, int); void rpc_delay(struct rpc_task *, unsigned long); void * rpc_malloc(struct rpc_task *, size_t); -void rpc_free(struct rpc_task *); +void rpc_free(void *); int rpciod_up(void); void rpciod_down(void); int __rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *)); diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 7aa29502b187..745afc1d3068 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -114,7 +114,7 @@ struct rpc_xprt_ops { void (*set_port)(struct rpc_xprt *xprt, unsigned short port); void (*connect)(struct rpc_task *task); void * (*buf_alloc)(struct rpc_task *task, size_t size); - void (*buf_free)(struct rpc_task *task); + void (*buf_free)(void *buffer); int (*send_request)(struct rpc_task *task); void (*set_retrans_timeout)(struct rpc_task *task); void (*timer)(struct rpc_task *task); -- cgit v1.2.2 From a509050bd3b8e0aa269c2241aa10d74ca7701e2f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 29 Mar 2007 16:48:04 -0400 Subject: SUNRPC: introduce rpcbind: replacement for in-kernel portmapper Introduce a replacement for the in-kernel portmapper client that supports all 3 versions of the rpcbind protocol. This code is not used yet. Original code by Groupe Bull updated for the latest kernel, with multiple bug fixes. Note that rpcb_clnt.c does not yet support registering via versions 3 and 4 of the rpcbind protocol. That is planned for a later patch. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 3 +++ include/linux/sunrpc/debug.h | 1 + include/linux/sunrpc/xprt.h | 1 + 3 files changed, 5 insertions(+) (limited to 'include/linux/sunrpc') diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 32c48a0b0d71..ca7553785932 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -124,6 +124,8 @@ int rpc_destroy_client(struct rpc_clnt *); void rpc_release_client(struct rpc_clnt *); void rpc_getport(struct rpc_task *); int rpc_register(u32, u32, int, unsigned short, int *); +int rpcb_register(u32, u32, int, unsigned short, int *); +void rpcb_getport(struct rpc_task *); void rpc_call_setup(struct rpc_task *, struct rpc_message *, int); @@ -146,6 +148,7 @@ char * rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); * Helper function for NFSroot support */ int rpc_getport_external(struct sockaddr_in *, __u32, __u32, int); +int rpcb_getport_external(struct sockaddr_in *, __u32, __u32, int); #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_CLNT_H */ diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h index b7c7307ceec6..707f96fe47d3 100644 --- a/include/linux/sunrpc/debug.h +++ b/include/linux/sunrpc/debug.h @@ -18,6 +18,7 @@ #define RPCDBG_NFS 0x0008 #define RPCDBG_AUTH 0x0010 #define RPCDBG_PMAP 0x0020 +#define RPCDBG_BIND 0x0020 #define RPCDBG_SCHED 0x0040 #define RPCDBG_TRANS 0x0080 #define RPCDBG_SVCSOCK 0x0100 diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 745afc1d3068..fa89ce6ce076 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -152,6 +152,7 @@ struct rpc_xprt { unsigned long state; /* transport state */ unsigned char shutdown : 1, /* being shut down */ resvport : 1; /* use a reserved port */ + unsigned int bind_index; /* bind function index */ /* * Connection of transports -- cgit v1.2.2 From 4c2eaf073f0cc2b5bf593b8133c078b9d9406e95 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 29 Mar 2007 16:48:27 -0400 Subject: SUNRPC: remove old portmapper net/sunrpc/pmap_clnt.c has been replaced by net/sunrpc/rpcb_clnt.c. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 3 --- include/linux/sunrpc/debug.h | 1 - include/linux/sunrpc/msg_prot.h | 4 ---- 3 files changed, 8 deletions(-) (limited to 'include/linux/sunrpc') diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index ca7553785932..66611423c8ee 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -122,8 +122,6 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); int rpc_shutdown_client(struct rpc_clnt *); int rpc_destroy_client(struct rpc_clnt *); void rpc_release_client(struct rpc_clnt *); -void rpc_getport(struct rpc_task *); -int rpc_register(u32, u32, int, unsigned short, int *); int rpcb_register(u32, u32, int, unsigned short, int *); void rpcb_getport(struct rpc_task *); @@ -147,7 +145,6 @@ char * rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); /* * Helper function for NFSroot support */ -int rpc_getport_external(struct sockaddr_in *, __u32, __u32, int); int rpcb_getport_external(struct sockaddr_in *, __u32, __u32, int); #endif /* __KERNEL__ */ diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h index 707f96fe47d3..3912cf16361e 100644 --- a/include/linux/sunrpc/debug.h +++ b/include/linux/sunrpc/debug.h @@ -17,7 +17,6 @@ #define RPCDBG_DEBUG 0x0004 #define RPCDBG_NFS 0x0008 #define RPCDBG_AUTH 0x0010 -#define RPCDBG_PMAP 0x0020 #define RPCDBG_BIND 0x0020 #define RPCDBG_SCHED 0x0040 #define RPCDBG_TRANS 0x0080 diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h index 606cb2165232..784d4c3ef651 100644 --- a/include/linux/sunrpc/msg_prot.h +++ b/include/linux/sunrpc/msg_prot.h @@ -78,10 +78,6 @@ enum rpc_auth_stat { RPCSEC_GSS_CTXPROBLEM = 14 }; -#define RPC_PMAP_PROGRAM 100000 -#define RPC_PMAP_VERSION 2 -#define RPC_PMAP_PORT 111 - #define RPC_MAXNETNAMELEN 256 /* -- cgit v1.2.2