xprtrdma: Disconnect after an ib_post_send() immediate error
authorChuck Lever <chuck.lever@oracle.com>
Mon, 2 Aug 2021 18:44:17 +0000 (14:44 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Mon, 9 Aug 2021 20:40:51 +0000 (16:40 -0400)
ib_post_send() does not disconnect the QP when it returns an
immediate error. Thus, the code that posts LocalInv has to
explicitly disconnect after an immediate error. This is just
like the frwr_send() callers handle it.

If a disconnect isn't done here, the transport deadlocks.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtrdma/xprt_rdma.h

index 229fcc9a906491846a5d0a35ffef166efbc84c0d..754c5dffe1272e12a3c8e661e4b2bac21e2853db 100644 (file)
@@ -557,6 +557,10 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
 
        /* On error, the MRs get destroyed once the QP has drained. */
        trace_xprtrdma_post_linv_err(req, rc);
+
+       /* Force a connection loss to ensure complete recovery.
+        */
+       rpcrdma_force_disconnect(ep);
 }
 
 /**
@@ -653,4 +657,8 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         * retransmission.
         */
        rpcrdma_unpin_rqst(req->rl_reply);
+
+       /* Force a connection loss to ensure complete recovery.
+        */
+       rpcrdma_force_disconnect(ep);
 }
index 649c23518ec042285a12159b498c06359ffc49f2..c1797ea19418ef3ba8a2e5a58160419faec3f5fb 100644 (file)
@@ -124,7 +124,7 @@ static void rpcrdma_xprt_drain(struct rpcrdma_xprt *r_xprt)
  * connection is closed or lost. (The important thing is it needs
  * to be invoked "at least" once).
  */
-static void rpcrdma_force_disconnect(struct rpcrdma_ep *ep)
+void rpcrdma_force_disconnect(struct rpcrdma_ep *ep)
 {
        if (atomic_add_unless(&ep->re_force_disconnect, 1, 1))
                xprt_force_disconnect(ep->re_xprt);
index 5d231d94e94402bf6718701152719b4e994ab77d..927e20a2c04e6288a6624b54b5f2534378298597 100644 (file)
@@ -454,6 +454,7 @@ extern unsigned int xprt_rdma_memreg_strategy;
 /*
  * Endpoint calls - xprtrdma/verbs.c
  */
+void rpcrdma_force_disconnect(struct rpcrdma_ep *ep);
 void rpcrdma_flush_disconnect(struct rpcrdma_xprt *r_xprt, struct ib_wc *wc);
 int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt);
 void rpcrdma_xprt_disconnect(struct rpcrdma_xprt *r_xprt);