]> git.baikalelectronics.ru Git - kernel.git/commitdiff
xprtrdma: Reset credit grant properly after a disconnect
authorChuck Lever <chuck.lever@oracle.com>
Mon, 1 Oct 2018 18:25:14 +0000 (14:25 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 2 Oct 2018 19:45:09 +0000 (15:45 -0400)
On a fresh connection, an RPC/RDMA client is supposed to send only
one RPC Call until it gets a credit grant in the first RPC Reply
from the server [RFC 8166, Section 3.3.3].

There is a bug in the Linux client's credit accounting mechanism
introduced by commit e70f01d8867a ("xprtrdma: Avoid deadlock when
credit window is reset"). On connect, it simply dumps all pending
RPC Calls onto the new connection.

Servers have been tolerant of this bad behavior. Currently no server
implementation ever changes its credit grant over reconnects, and
servers always repost enough Receives before connections are fully
established.

To correct this issue, ensure that the client resets both the credit
grant _and_ the congestion window when handling a reconnect.

Fixes: e70f01d8867a ("xprtrdma: Avoid deadlock when credit ... ")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: stable@kernel.org
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
net/sunrpc/xprtrdma/transport.c

index a68180090554f2f40ebb9ed5cd72a70cd9639541..b9827665ff35570491f09976ad7cd4b972a6bee5 100644 (file)
@@ -248,6 +248,7 @@ static void
 xprt_rdma_bc_close(struct rpc_xprt *xprt)
 {
        dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
+       xprt->cwnd = RPC_CWNDSHIFT;
 }
 
 static void
index 143ce2579ba90cca47a87b5413ba35caf9d10792..98cbc7b060bad9f3fdf2ec3c4c1781ca9ee49abd 100644 (file)
@@ -468,6 +468,12 @@ xprt_rdma_close(struct rpc_xprt *xprt)
                xprt->reestablish_timeout = 0;
        xprt_disconnect_done(xprt);
        rpcrdma_ep_disconnect(ep, ia);
+
+       /* Prepare @xprt for the next connection by reinitializing
+        * its credit grant to one (see RFC 8166, Section 3.3.3).
+        */
+       r_xprt->rx_buf.rb_credits = 1;
+       xprt->cwnd = RPC_CWNDSHIFT;
 }
 
 /**