aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 52739f82df1e..0eea2bfe111b 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -12,8 +12,9 @@
12 * - Next, the caller puts together the RPC message, stuffs it into 12 * - Next, the caller puts together the RPC message, stuffs it into
13 * the request struct, and calls xprt_transmit(). 13 * the request struct, and calls xprt_transmit().
14 * - xprt_transmit sends the message and installs the caller on the 14 * - xprt_transmit sends the message and installs the caller on the
15 * transport's wait list. At the same time, it installs a timer that 15 * transport's wait list. At the same time, if a reply is expected,
16 * is run after the packet's timeout has expired. 16 * it installs a timer that is run after the packet's timeout has
17 * expired.
17 * - When a packet arrives, the data_ready handler walks the list of 18 * - When a packet arrives, the data_ready handler walks the list of
18 * pending requests for that transport. If a matching XID is found, the 19 * pending requests for that transport. If a matching XID is found, the
19 * caller is woken up, and the timer removed. 20 * caller is woken up, and the timer removed.
@@ -46,6 +47,8 @@
46#include <linux/sunrpc/clnt.h> 47#include <linux/sunrpc/clnt.h>
47#include <linux/sunrpc/metrics.h> 48#include <linux/sunrpc/metrics.h>
48 49
50#include "sunrpc.h"
51
49/* 52/*
50 * Local variables 53 * Local variables
51 */ 54 */
@@ -873,7 +876,10 @@ void xprt_transmit(struct rpc_task *task)
873 dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); 876 dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
874 877
875 if (!req->rq_received) { 878 if (!req->rq_received) {
876 if (list_empty(&req->rq_list)) { 879 if (list_empty(&req->rq_list) && rpc_reply_expected(task)) {
880 /*
881 * Add to the list only if we're expecting a reply
882 */
877 spin_lock_bh(&xprt->transport_lock); 883 spin_lock_bh(&xprt->transport_lock);
878 /* Update the softirq receive buffer */ 884 /* Update the softirq receive buffer */
879 memcpy(&req->rq_private_buf, &req->rq_rcv_buf, 885 memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
@@ -908,8 +914,13 @@ void xprt_transmit(struct rpc_task *task)
908 /* Don't race with disconnect */ 914 /* Don't race with disconnect */
909 if (!xprt_connected(xprt)) 915 if (!xprt_connected(xprt))
910 task->tk_status = -ENOTCONN; 916 task->tk_status = -ENOTCONN;
911 else if (!req->rq_received) 917 else if (!req->rq_received && rpc_reply_expected(task)) {
918 /*
919 * Sleep on the pending queue since
920 * we're expecting a reply.
921 */
912 rpc_sleep_on(&xprt->pending, task, xprt_timer); 922 rpc_sleep_on(&xprt->pending, task, xprt_timer);
923 }
913 spin_unlock_bh(&xprt->transport_lock); 924 spin_unlock_bh(&xprt->transport_lock);
914} 925}
915 926
@@ -982,11 +993,17 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
982 */ 993 */
983void xprt_release(struct rpc_task *task) 994void xprt_release(struct rpc_task *task)
984{ 995{
985 struct rpc_xprt *xprt = task->tk_xprt; 996 struct rpc_xprt *xprt;
986 struct rpc_rqst *req; 997 struct rpc_rqst *req;
998 int is_bc_request;
987 999
988 if (!(req = task->tk_rqstp)) 1000 if (!(req = task->tk_rqstp))
989 return; 1001 return;
1002
1003 /* Preallocated backchannel request? */
1004 is_bc_request = bc_prealloc(req);
1005
1006 xprt = req->rq_xprt;
990 rpc_count_iostats(task); 1007 rpc_count_iostats(task);
991 spin_lock_bh(&xprt->transport_lock); 1008 spin_lock_bh(&xprt->transport_lock);
992 xprt->ops->release_xprt(xprt, task); 1009 xprt->ops->release_xprt(xprt, task);
@@ -999,10 +1016,19 @@ void xprt_release(struct rpc_task *task)
999 mod_timer(&xprt->timer, 1016 mod_timer(&xprt->timer,
1000 xprt->last_used + xprt->idle_timeout); 1017 xprt->last_used + xprt->idle_timeout);
1001 spin_unlock_bh(&xprt->transport_lock); 1018 spin_unlock_bh(&xprt->transport_lock);
1002 xprt->ops->buf_free(req->rq_buffer); 1019 if (!bc_prealloc(req))
1020 xprt->ops->buf_free(req->rq_buffer);
1003 task->tk_rqstp = NULL; 1021 task->tk_rqstp = NULL;
1004 if (req->rq_release_snd_buf) 1022 if (req->rq_release_snd_buf)
1005 req->rq_release_snd_buf(req); 1023 req->rq_release_snd_buf(req);
1024
1025 /*
1026 * Early exit if this is a backchannel preallocated request.
1027 * There is no need to have it added to the RPC slot list.
1028 */
1029 if (is_bc_request)
1030 return;
1031
1006 memset(req, 0, sizeof(*req)); /* mark unused */ 1032 memset(req, 0, sizeof(*req)); /* mark unused */
1007 1033
1008 dprintk("RPC: %5u release request %p\n", task->tk_pid, req); 1034 dprintk("RPC: %5u release request %p\n", task->tk_pid, req);