On Wed, Jun 5, 2019 at 8:15 AM Chuck Lever <chuck.lever@xxxxxxxxxx> wrote: > > The DRC is not working at all after an RPC/RDMA transport reconnect. > The problem is that the new connection uses a different source port, > which defeats DRC hash. > > An NFS/RDMA client's source port is meaningless for RDMA transports. > The transport layer typically sets the source port value on the > connection to a random ephemeral port. The server already ignores it > for the "secure port" check. See commit 16e4d93f6de7 ("NFSD: Ignore > client's source port on RDMA transports"). > > I'm not sure why I never noticed this before. Hi Chuck, I have a question: is the reason for choosing this fix as oppose to fixing the client because it's server's responsibility to design a DRC differently for the NFSoRDMA? > > Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- > net/sunrpc/xprtrdma/svc_rdma_transport.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c > index 027a3b0..1b3700b 100644 > --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c > +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c > @@ -211,9 +211,14 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, > /* Save client advertised inbound read limit for use later in accept. */ > newxprt->sc_ord = param->initiator_depth; > > - /* Set the local and remote addresses in the transport */ > sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr; > svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa)); > + /* The remote port is arbitrary and not under the control of the > + * ULP. Set it to a fixed value so that the DRC continues to work > + * after a reconnect. > + */ > + rpc_set_port((struct sockaddr *)&newxprt->sc_xprt.xpt_remote, 0); > + > sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr; > svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa)); > >