aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2014-07-29 17:23:52 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2014-07-31 16:22:53 -0400
commita7bc211ac926172ad20463afcf00ae7b9ebcd950 (patch)
tree5ae7beefa905240849896f501146c751677a2a94 /net
parent6ab59945f292a5c6cbc4a6c2011f1a732a116af2 (diff)
xprtrdma: On disconnect, don't ignore pending CQEs
xprtrdma is currently throwing away queued completions during a reconnect. RPC replies posted just before connection loss, or successful completions that change the state of an FRMR, can be missed. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Tested-by: Steve Wise <swise@opengridcomputing.com> Tested-by: Shirley Ma <shirley.ma@oracle.com> Tested-by: Devesh Sharma <devesh.sharma@emulex.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtrdma/verbs.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 13ff87400203..e49cdc930dfd 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -310,6 +310,13 @@ rpcrdma_recvcq_upcall(struct ib_cq *cq, void *cq_context)
310 rpcrdma_recvcq_poll(cq, ep); 310 rpcrdma_recvcq_poll(cq, ep);
311} 311}
312 312
313static void
314rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
315{
316 rpcrdma_recvcq_upcall(ep->rep_attr.recv_cq, ep);
317 rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep);
318}
319
313#ifdef RPC_DEBUG 320#ifdef RPC_DEBUG
314static const char * const conn[] = { 321static const char * const conn[] = {
315 "address resolved", 322 "address resolved",
@@ -872,9 +879,7 @@ retry:
872 if (rc && rc != -ENOTCONN) 879 if (rc && rc != -ENOTCONN)
873 dprintk("RPC: %s: rpcrdma_ep_disconnect" 880 dprintk("RPC: %s: rpcrdma_ep_disconnect"
874 " status %i\n", __func__, rc); 881 " status %i\n", __func__, rc);
875 882 rpcrdma_flush_cqs(ep);
876 rpcrdma_clean_cq(ep->rep_attr.recv_cq);
877 rpcrdma_clean_cq(ep->rep_attr.send_cq);
878 883
879 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia); 884 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
880 id = rpcrdma_create_id(xprt, ia, 885 id = rpcrdma_create_id(xprt, ia,
@@ -985,8 +990,7 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
985{ 990{
986 int rc; 991 int rc;
987 992
988 rpcrdma_clean_cq(ep->rep_attr.recv_cq); 993 rpcrdma_flush_cqs(ep);
989 rpcrdma_clean_cq(ep->rep_attr.send_cq);
990 rc = rdma_disconnect(ia->ri_id); 994 rc = rdma_disconnect(ia->ri_id);
991 if (!rc) { 995 if (!rc) {
992 /* returns without wait if not connected */ 996 /* returns without wait if not connected */