diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2014-07-29 17:23:52 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2014-07-31 16:22:53 -0400 |
commit | a7bc211ac926172ad20463afcf00ae7b9ebcd950 (patch) | |
tree | 5ae7beefa905240849896f501146c751677a2a94 /net | |
parent | 6ab59945f292a5c6cbc4a6c2011f1a732a116af2 (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.c | 14 |
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 | ||
313 | static void | ||
314 | rpcrdma_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 |
314 | static const char * const conn[] = { | 321 | static 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 */ |