From: Chuck Lever <chuck.lever@oracle.com>
To: linux-rdma@vger.kernel.org, linux-nfs@vger.kernel.org
Subject: [PATCH v1 08/14] svcrdma: Report Write/Reply chunk overruns
Date: Thu, 16 Mar 2017 11:53:31 -0400 [thread overview]
Message-ID: <20170316155331.4482.7734.stgit@klimt.1015granger.net> (raw)
In-Reply-To: <20170316154132.4482.56769.stgit@klimt.1015granger.net>
Observed at Connectathon 2017.
If a client has underestimated the size of a Write or Reply chunk,
the Linux server writes as much payload data as it can, then it
recognizes there was a problem and closes the connection without
sending the transport header.
This creates a couple of problems:
<> The client never receives indication of the server-side failure,
so it continues to retransmit the bad RPC. Forward progress on
the transport is blocked.
<> The reply payload pages are not moved out of the svc_rqst, thus
they can be released by the RPC server before the RDMA Writes
have completed.
The new rdma_rw-ized helpers return a distinct error code when a
Write/Reply chunk overrun occurs, so it's now easy for the caller
(svc_rdma_sendto) to recognize this case.
Instead of dropping the connection, post an RDMA_ERROR message. The
client now sees an RDMA_ERROR and can properly terminate the RPC
transaction.
As part of the new logic, set up the same delayed release for these
payload pages as would have occurred in the normal case.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/xprtrdma/svc_rdma_sendto.c | 59 ++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 1b230dc..489e602 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -484,6 +484,49 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma,
return ret;
}
+/* Given the client-provided Write and Reply chunks, the server was not
+ * able to form a complete reply. Return an RDMA_ERROR message so the
+ * client can retire this RPC transaction. As above, the Send completion
+ * routine releases payload pages that were part of a previous RDMA Write.
+ *
+ * Remote Invalidation is skipped for simplicity.
+ */
+static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma,
+ __be32 *rdma_resp, struct svc_rqst *rqstp)
+{
+ struct svc_rdma_op_ctxt *ctxt;
+ __be32 *p;
+ int ret;
+
+ ctxt = svc_rdma_get_context(rdma);
+
+ /* Replace the original transport header with an
+ * RDMA_ERROR response. XID etc are preserved.
+ */
+ p = rdma_resp + 3;
+ *p++ = rdma_error;
+ *p = err_chunk;
+
+ ret = svc_rdma_map_reply_hdr(rdma, ctxt, rdma_resp, 20);
+ if (ret < 0)
+ goto err;
+
+ svc_rdma_save_io_pages(rqstp, ctxt);
+
+ svc_rdma_build_send_wr(ctxt, 1 + ret);
+ ret = svc_rdma_send(rdma, &ctxt->send_wr);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ pr_err("svcrdma: failed to post Send WR (%d)\n", ret);
+ svc_rdma_unmap_dma(ctxt);
+ svc_rdma_put_context(ctxt, 1);
+ return ret;
+}
+
void svc_rdma_prep_reply_hdr(struct svc_rqst *rqstp)
{
}
@@ -545,13 +588,13 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
ret = svc_rdma_send_write_list(rdma, wr_lst, rdma_resp,
&rqstp->rq_res);
if (ret < 0)
- goto err1;
+ goto err2;
}
if (rp_ch) {
ret = svc_rdma_send_reply_chunk(rdma, wr_lst, rp_ch,
rdma_resp, &rqstp->rq_res);
if (ret < 0)
- goto err1;
+ goto err2;
}
ret = svc_rdma_post_recv(rdma, GFP_KERNEL);
@@ -563,6 +606,18 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
goto err0;
return 0;
+ err2:
+ if (ret != -E2BIG)
+ goto err1;
+
+ ret = svc_rdma_post_recv(rdma, GFP_KERNEL);
+ if (ret)
+ goto err1;
+ ret = svc_rdma_send_error_msg(rdma, rdma_resp, rqstp);
+ if (ret < 0)
+ goto err0;
+ return 0;
+
err1:
put_page(res_page);
err0:
next prev parent reply other threads:[~2017-03-16 15:53 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-16 15:52 [PATCH v1 00/14] Server-side NFS/RDMA changes for v4.12 Chuck Lever
2017-03-16 15:52 ` [PATCH v1 01/14] svcrdma: Move send_wr to svc_rdma_op_ctxt Chuck Lever
2017-03-21 17:49 ` Sagi Grimberg
2017-03-16 15:52 ` [PATCH v1 02/14] svcrdma: Add svc_rdma_map_reply_hdr() Chuck Lever
2017-03-21 17:54 ` Sagi Grimberg
2017-03-21 18:40 ` Chuck Lever
2017-03-22 13:07 ` Sagi Grimberg
2017-03-16 15:52 ` [PATCH v1 03/14] svcrdma: Eliminate RPCRDMA_SQ_DEPTH_MULT Chuck Lever
2017-03-21 17:58 ` Sagi Grimberg
2017-03-21 18:44 ` Chuck Lever
2017-03-22 13:09 ` Sagi Grimberg
2017-03-22 13:36 ` Chuck Lever
2017-03-22 19:06 ` Sagi Grimberg
2017-03-22 19:30 ` Chuck Lever
2017-03-16 15:52 ` [PATCH v1 04/14] svcrdma: Add helper to save pages under I/O Chuck Lever
2017-03-21 18:01 ` Sagi Grimberg
2017-03-16 15:53 ` [PATCH v1 05/14] svcrdma: Introduce local rdma_rw API helpers Chuck Lever
2017-03-22 14:17 ` Sagi Grimberg
2017-03-22 15:41 ` Chuck Lever
2017-03-24 22:19 ` Chuck Lever
2017-03-16 15:53 ` [PATCH v1 06/14] svcrdma: Use rdma_rw API in RPC reply path Chuck Lever
2017-03-16 15:53 ` [PATCH v1 07/14] svcrdma: Clean up RDMA_ERROR path Chuck Lever
2017-03-22 14:18 ` Sagi Grimberg
2017-03-16 15:53 ` Chuck Lever [this message]
2017-03-22 14:20 ` [PATCH v1 08/14] svcrdma: Report Write/Reply chunk overruns Sagi Grimberg
2017-03-16 15:53 ` [PATCH v1 09/14] svcrdma: Clean up RPC-over-RDMA backchannel reply processing Chuck Lever
2017-03-16 15:53 ` [PATCH v1 10/14] svcrdma: Reduce size of sge array in struct svc_rdma_op_ctxt Chuck Lever
2017-03-22 14:21 ` Sagi Grimberg
2017-03-16 15:53 ` [PATCH v1 11/14] svcrdma: Remove old RDMA Write completion handlers Chuck Lever
2017-03-22 14:22 ` Sagi Grimberg
2017-03-16 15:54 ` [PATCH v1 12/14] svcrdma: Remove the req_map cache Chuck Lever
2017-03-22 14:22 ` Sagi Grimberg
2017-03-16 15:54 ` [PATCH v1 13/14] svcrdma: Clean out old XDR encoders Chuck Lever
2017-03-22 14:23 ` Sagi Grimberg
2017-03-16 15:54 ` [PATCH v1 14/14] svcrdma: Clean up svc_rdma_post_recv() error handling Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170316155331.4482.7734.stgit@klimt.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).