[PATCH] RPC: eliminate rq_xprt field rq_xprt is just a copy of tk_xprt, and both are now in the same structure. We can get rid of rq_xprt. Test-plan: Compile kernel with CONFIG_NFS enabled. Version: Thu, 10 Mar 2005 19:00:45 -0500 Signed-off-by: Chuck Lever --- Documentation/rpc-transport-switch.txt | 10 +++++++--- include/linux/sunrpc/xprt.h | 15 ++++++++------- net/sunrpc/clnt.c | 2 +- net/sunrpc/xprt.c | 23 ++++++++++------------- net/sunrpc/xprtsock.c | 12 +++++++----- 5 files changed, 33 insertions(+), 29 deletions(-) diff -X /home/cel/src/linux/dont-diff -Naurp 82-rpc-rq_task/Documentation/rpc-transport-switch.txt 83-rpc-rq_xprt/Documentation/rpc-transport-switch.txt --- 82-rpc-rq_task/Documentation/rpc-transport-switch.txt 2005-03-07 17:38:45.194181000 -0500 +++ 83-rpc-rq_xprt/Documentation/rpc-transport-switch.txt 2005-03-07 18:01:34.657135000 -0500 @@ -788,17 +788,21 @@ iv.3 Procedure syntax and functional des sleep. It does not depend on any external locks being held. - void xprt_adjust_cwnd(struct rpc_rqst *req, int result) + void xprt_adjust_cwnd(struct rpc_xprt *xprt, struct rpc_rqst *req, int result) Transport implementations that need congestion control invoke this function to adjust their congestion window. - The function takes two arguments: the address of an rpc_rqst - structure representing the request that has caused the + The function takes three arguments: the address of an rpc_xprt + structure containing the transport context, the address of an + rpc_rqst structure representing the request that has caused the change in the transport's congestion window, and an integer containing an errno value indicating why the window needs to be adjusted. It returns nothing. + The caller must ensure that the xprt's reference count is + greater than one when calling this function. + This function can be called from asynchronous RPC tasks so it must not sleep. The transport_lock must be held before calling this function. diff -X /home/cel/src/linux/dont-diff -Naurp 82-rpc-rq_task/include/linux/sunrpc/xprt.h 83-rpc-rq_xprt/include/linux/sunrpc/xprt.h --- 82-rpc-rq_task/include/linux/sunrpc/xprt.h 2005-03-07 18:00:34.643595000 -0500 +++ 83-rpc-rq_xprt/include/linux/sunrpc/xprt.h 2005-03-07 18:01:34.676137000 -0500 @@ -72,10 +72,6 @@ struct rpc_timeout { unsigned char to_exponential; }; -struct rpc_clnt; -struct rpc_task; -struct rpc_xprt; - /* * This describes a complete RPC request */ @@ -83,7 +79,6 @@ struct rpc_rqst { /* * This is the user-visible part */ - struct rpc_xprt * rq_xprt; /* RPC client */ struct xdr_buf rq_snd_buf; /* send buffer */ struct xdr_buf rq_rcv_buf; /* recv buffer */ @@ -122,6 +117,10 @@ struct rpc_rqst { #define rq_svec rq_snd_buf.head #define rq_slen rq_snd_buf.len +struct rpc_clnt; +struct rpc_task; +struct rpc_xprt; + struct rpc_xprt_ops { void (*setbufsize)(struct rpc_xprt *, size_t, size_t); void (*print_addr)(struct rpc_xprt *, size_t, char *, int); @@ -212,12 +211,14 @@ void xprt_set_timeout(struct rpc_timeo unsigned long); struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *, u32); void xprt_complete_rqst(struct rpc_rqst *, size_t); -void xprt_adjust_cwnd(struct rpc_rqst *, int); +void xprt_adjust_cwnd(struct rpc_xprt *, struct rpc_rqst *, + int); void xprt_reserve(struct rpc_task *); int xprt_prepare_transmit(struct rpc_task *); void xprt_transmit(struct rpc_task *); void xprt_receive(struct rpc_task *); -int xprt_adjust_timeout(struct rpc_rqst *req); +int xprt_adjust_timeout(struct rpc_xprt *xprt, + struct rpc_rqst *req); void xprt_release(struct rpc_task *); void xprt_connect(struct rpc_task *); int xprt_register(struct xprt_type *); diff -X /home/cel/src/linux/dont-diff -Naurp 82-rpc-rq_task/net/sunrpc/clnt.c 83-rpc-rq_xprt/net/sunrpc/clnt.c --- 82-rpc-rq_task/net/sunrpc/clnt.c 2005-03-08 11:24:12.987431000 -0500 +++ 83-rpc-rq_xprt/net/sunrpc/clnt.c 2005-03-08 11:24:31.882912000 -0500 @@ -965,7 +965,7 @@ call_timeout(struct rpc_task *task) struct rpc_clnt *clnt = task->tk_client; struct rpc_xprt *xprt = task->tk_xprt; - if (xprt_adjust_timeout(&task->tk_rqst) == 0) { + if (xprt_adjust_timeout(xprt, &task->tk_rqst) == 0) { dprintk("RPC: %4d call_timeout (minor)\n", task->tk_pid); goto retry; } diff -X /home/cel/src/linux/dont-diff -Naurp 82-rpc-rq_task/net/sunrpc/xprt.c 83-rpc-rq_xprt/net/sunrpc/xprt.c --- 82-rpc-rq_task/net/sunrpc/xprt.c 2005-03-07 18:00:34.665595000 -0500 +++ 83-rpc-rq_xprt/net/sunrpc/xprt.c 2005-03-07 18:01:34.721135000 -0500 @@ -270,12 +270,10 @@ xprt_release_write(struct rpc_xprt *xprt * Adjust RPC congestion window * We use a time-smoothed congestion estimator to avoid heavy oscillation. */ -void xprt_adjust_cwnd(struct rpc_rqst *req, int result) +void xprt_adjust_cwnd(struct rpc_xprt *xprt, struct rpc_rqst *req, int result) { - unsigned long cwnd; - struct rpc_xprt *xprt = req->rq_xprt; + unsigned long cwnd = xprt->cwnd; - cwnd = xprt->cwnd; if (result >= 0 && cwnd <= xprt->cong) { /* The (cwnd >> 1) term makes sure * the result gets rounded properly. */ @@ -301,7 +299,8 @@ EXPORT_SYMBOL_GPL(xprt_adjust_cwnd); */ static void xprt_reset_majortimeo(struct rpc_rqst *req) { - struct rpc_timeout *to = &req->rq_xprt->timeout; + struct rpc_xprt *xprt = to_rpc_task(req)->tk_xprt; + struct rpc_timeout *to = &xprt->timeout; req->rq_majortimeo = req->rq_timeout; if (to->to_exponential) @@ -316,9 +315,8 @@ static void xprt_reset_majortimeo(struct /* * Adjust timeout values etc for next retransmit */ -int xprt_adjust_timeout(struct rpc_rqst *req) +int xprt_adjust_timeout(struct rpc_xprt *xprt, struct rpc_rqst *req) { - struct rpc_xprt *xprt = req->rq_xprt; struct rpc_timeout *to = &xprt->timeout; int status = 0; @@ -490,7 +488,7 @@ void xprt_complete_rqst(struct rpc_rqst struct rpc_task *task = to_rpc_task(req); #ifdef RPC_PROFILE - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; /* Profile only reads for now */ if (copied > 1024) { @@ -528,13 +526,13 @@ static void xprt_timer(struct rpc_task *task) { struct rpc_rqst *req = &task->tk_rqst; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; spin_lock(&xprt->transport_lock); if (req->rq_received) goto out; - xprt_adjust_cwnd(req, -ETIMEDOUT); + xprt_adjust_cwnd(xprt, req, -ETIMEDOUT); dprintk("RPC: %4d xprt_timer (%s request)\n", task->tk_pid, req ? "pending" : "backlogged"); @@ -554,7 +552,7 @@ int xprt_prepare_transmit(struct rpc_task *task) { struct rpc_rqst *req = &task->tk_rqst; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; int err = 0; dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid); @@ -585,7 +583,7 @@ void xprt_transmit(struct rpc_task *task) { struct rpc_rqst *req = &task->tk_rqst; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; int status; dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); @@ -658,7 +656,6 @@ static void xprt_request_init(struct rpc INIT_LIST_HEAD(&req->rq_list); req->rq_timeout = xprt->timeout.to_initval; - req->rq_xprt = xprt; req->rq_inited = 1; req->rq_xid = xprt_alloc_xid(xprt); req->rq_buffer = NULL; diff -X /home/cel/src/linux/dont-diff -Naurp 82-rpc-rq_task/net/sunrpc/xprtsock.c 83-rpc-rq_xprt/net/sunrpc/xprtsock.c --- 82-rpc-rq_task/net/sunrpc/xprtsock.c 2005-03-07 18:00:34.676595000 -0500 +++ 83-rpc-rq_xprt/net/sunrpc/xprtsock.c 2005-03-07 18:01:34.743135000 -0500 @@ -302,7 +302,7 @@ out: static void xs_nospace(struct rpc_task *task) { struct rpc_rqst *req = &task->tk_rqst; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; struct socket *sock = xs_private_data(xprt)->sock; dprintk("RPC: %4d xmit incomplete (%u left of %u)\n", @@ -341,7 +341,7 @@ static void xs_nospace(struct rpc_task * static int xs_udp_send_request(struct rpc_task *task) { struct rpc_rqst *req = &task->tk_rqst; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; struct socket *sock = xs_private_data(xprt)->sock; struct xdr_buf *xdr = &req->rq_snd_buf; int status; @@ -417,7 +417,7 @@ static inline void xs_encode_tcp_record_ static int xs_tcp_send_request(struct rpc_task *task) { struct rpc_rqst *req = &task->tk_rqst; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; struct socket *sock = xs_private_data(xprt)->sock; struct xdr_buf *xdr = &req->rq_snd_buf; int status, retry = 0; @@ -509,7 +509,7 @@ static void xs_udp_set_receive_timeout(s int timer = task->tk_msg.rpc_proc->p_timer; struct rpc_rtt *rtt = task->tk_client->cl_rtt; struct rpc_rqst *req = &task->tk_rqst; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = task->tk_xprt; task->tk_timeout = rpc_calc_rto(rtt, timer); task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries; @@ -665,7 +665,7 @@ static void xs_udp_data_ready(struct soc /* Adjust congestion window */ timer = task->tk_msg.rpc_proc->p_timer; - xprt_adjust_cwnd(rovr, copied); + xprt_adjust_cwnd(xprt, rovr, copied); if (timer) { struct rpc_rtt *rtt = task->tk_client->cl_rtt; if (rovr->rq_ntrans == 1) @@ -1564,6 +1564,8 @@ static void xs_udp6_connect_worker(void if (xprt->shutdown || !xprt_is_bound(xprt)) goto out; + dprintk("RPC: xs_tcp6_connect_worker for xprt %p\n", xprt); + /* Start by resetting any existing state */ xs_close(xprt);