lkml.org 
[lkml]   [2018]   [Nov]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.18 158/350] xprtrdma: Reset credit grant properly after a disconnect
    Date
    4.18-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Chuck Lever <chuck.lever@oracle.com>

    [ Upstream commit ef739b2175dde9c05594f768cb78149f1ce2ac36 ]

    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 e7ce710a8802 ("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: e7ce710a8802 ("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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/sunrpc/xprtrdma/svc_rdma_backchannel.c | 1 +
    net/sunrpc/xprtrdma/transport.c | 6 ++++++
    2 files changed, 7 insertions(+)

    --- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
    +++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
    @@ -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
    --- a/net/sunrpc/xprtrdma/transport.c
    +++ b/net/sunrpc/xprtrdma/transport.c
    @@ -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;
    }

    /**

    \
     
     \ /
      Last update: 2018-11-12 00:32    [W:4.015 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site