diff options
author | Tom Talpey <talpey@netapp.com> | 2008-10-09 15:00:40 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-10-10 15:10:36 -0400 |
commit | 575448bd36208f99fe0dd554a43518d798966740 (patch) | |
tree | 191d98d11586952ec961c56b58335cc76346b4b6 | |
parent | b334eaabf4f92226d2df13c613888a507f03da99 (diff) |
RPC/RDMA: suppress retransmit on RPC/RDMA clients.
An RPC/RDMA client cannot retransmit on an unbroken connection,
doing so violates its flow control with the server.
Signed-off-by: Tom Talpey <talpey@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | net/sunrpc/xprtrdma/rpc_rdma.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/transport.c | 16 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 1 |
3 files changed, 15 insertions, 4 deletions
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index e55427f73dfe..721dae795d68 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
@@ -681,6 +681,8 @@ rpcrdma_conn_func(struct rpcrdma_ep *ep) | |||
681 | struct rpc_xprt *xprt = ep->rep_xprt; | 681 | struct rpc_xprt *xprt = ep->rep_xprt; |
682 | 682 | ||
683 | spin_lock_bh(&xprt->transport_lock); | 683 | spin_lock_bh(&xprt->transport_lock); |
684 | if (++xprt->connect_cookie == 0) /* maintain a reserved value */ | ||
685 | ++xprt->connect_cookie; | ||
684 | if (ep->rep_connected > 0) { | 686 | if (ep->rep_connected > 0) { |
685 | if (!xprt_test_and_set_connected(xprt)) | 687 | if (!xprt_test_and_set_connected(xprt)) |
686 | xprt_wake_pending_tasks(xprt, 0); | 688 | xprt_wake_pending_tasks(xprt, 0); |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 89970b0a4cc9..0aefc6485385 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
@@ -587,6 +587,7 @@ xprt_rdma_allocate(struct rpc_task *task, size_t size) | |||
587 | } | 587 | } |
588 | dprintk("RPC: %s: size %zd, request 0x%p\n", __func__, size, req); | 588 | dprintk("RPC: %s: size %zd, request 0x%p\n", __func__, size, req); |
589 | out: | 589 | out: |
590 | req->rl_connect_cookie = 0; /* our reserved value */ | ||
590 | return req->rl_xdr_buf; | 591 | return req->rl_xdr_buf; |
591 | 592 | ||
592 | outfail: | 593 | outfail: |
@@ -690,13 +691,20 @@ xprt_rdma_send_request(struct rpc_task *task) | |||
690 | req->rl_reply->rr_xprt = xprt; | 691 | req->rl_reply->rr_xprt = xprt; |
691 | } | 692 | } |
692 | 693 | ||
693 | if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req)) { | 694 | /* Must suppress retransmit to maintain credits */ |
694 | xprt_disconnect_done(xprt); | 695 | if (req->rl_connect_cookie == xprt->connect_cookie) |
695 | return -ENOTCONN; /* implies disconnect */ | 696 | goto drop_connection; |
696 | } | 697 | req->rl_connect_cookie = xprt->connect_cookie; |
698 | |||
699 | if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req)) | ||
700 | goto drop_connection; | ||
697 | 701 | ||
698 | rqst->rq_bytes_sent = 0; | 702 | rqst->rq_bytes_sent = 0; |
699 | return 0; | 703 | return 0; |
704 | |||
705 | drop_connection: | ||
706 | xprt_disconnect_done(xprt); | ||
707 | return -ENOTCONN; /* implies disconnect */ | ||
700 | } | 708 | } |
701 | 709 | ||
702 | static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | 710 | static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 05b7898e1f4b..2db2344d487e 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -181,6 +181,7 @@ struct rpcrdma_req { | |||
181 | size_t rl_size; /* actual length of buffer */ | 181 | size_t rl_size; /* actual length of buffer */ |
182 | unsigned int rl_niovs; /* 0, 2 or 4 */ | 182 | unsigned int rl_niovs; /* 0, 2 or 4 */ |
183 | unsigned int rl_nchunks; /* non-zero if chunks */ | 183 | unsigned int rl_nchunks; /* non-zero if chunks */ |
184 | unsigned int rl_connect_cookie; /* retry detection */ | ||
184 | struct rpcrdma_buffer *rl_buffer; /* home base for this structure */ | 185 | struct rpcrdma_buffer *rl_buffer; /* home base for this structure */ |
185 | struct rpcrdma_rep *rl_reply;/* holder for reply buffer */ | 186 | struct rpcrdma_rep *rl_reply;/* holder for reply buffer */ |
186 | struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];/* chunk segments */ | 187 | struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];/* chunk segments */ |