From: Bob Pearson <rpearsonhpe@gmail.com>
To: jgg@nvidia.com, leon@kernel.org, zyjzyj2000@gmail.com,
jhack@hpe.com, linux-rdma@vger.kernel.org
Subject: Re: [PATCH] RDMA/rxe: Fix incomplete state save in rxe_requester
Date: Fri, 21 Jul 2023 13:59:19 -0500 [thread overview]
Message-ID: <c6f80a3c-9a10-2cf0-b126-2221fdad884f@gmail.com> (raw)
In-Reply-To: <20230721180443.16817-1-rpearsonhpe@gmail.com>
On 7/21/23 13:04, Bob Pearson wrote:
> If a send packet is dropped by the IP layer in rxe_requester()
> the call to rxe_xmit_packet() can fail with err == -EAGAIN.
> To recover, the state of the wqe is restored to the state before
> the packet was sent so it can be resent. However, the routines
> that save and restore the state miss a significnt part of the
> variable state in the wqe, the dma struct which is used to process
> through the sge table. And, the state is not saved before the packet
> is built which modifies the dma struct.
>
> Under heavy stress testing with many QPs on a fast node sending
> large messages to a slow node dropped packets are observed and
> the resent packets are corrupted because the dma struct was not
> restored. This patch fixes this behavior and allows the test cases
> to succeed.
>
> Fixes: 3050b9985024 ("IB/rxe: Fix race condition between requester and completer")
> Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
> ---
> drivers/infiniband/sw/rxe/rxe_req.c | 47 ++++++++++++++++-------------
> 1 file changed, 26 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
> index 76d85731a45f..10ff2715d9bb 100644
> --- a/drivers/infiniband/sw/rxe/rxe_req.c
> +++ b/drivers/infiniband/sw/rxe/rxe_req.c
> @@ -708,10 +708,11 @@ static void save_state(struct rxe_send_wqe *wqe,
> struct rxe_send_wqe *rollback_wqe,
> u32 *rollback_psn)
> {
> - rollback_wqe->state = wqe->state;
> + rollback_wqe->state = wqe->state;
> rollback_wqe->first_psn = wqe->first_psn;
> - rollback_wqe->last_psn = wqe->last_psn;
> - *rollback_psn = qp->req.psn;
> + rollback_wqe->last_psn = wqe->last_psn;
> + rollback_wqe->dma = wqe->dma;
> + *rollback_psn = qp->req.psn;
> }
>
> static void rollback_state(struct rxe_send_wqe *wqe,
> @@ -719,10 +720,11 @@ static void rollback_state(struct rxe_send_wqe *wqe,
> struct rxe_send_wqe *rollback_wqe,
> u32 rollback_psn)
> {
> - wqe->state = rollback_wqe->state;
> + wqe->state = rollback_wqe->state;
> wqe->first_psn = rollback_wqe->first_psn;
> - wqe->last_psn = rollback_wqe->last_psn;
> - qp->req.psn = rollback_psn;
> + wqe->last_psn = rollback_wqe->last_psn;
> + wqe->dma = rollback_wqe->dma;
> + qp->req.psn = rollback_psn;
> }
>
> static void update_state(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
> @@ -922,6 +924,9 @@ int rxe_requester(struct rxe_qp *qp)
> payload = mtu;
> }
>
> + /* save wqe state before we build and send packet */
> + save_state(wqe, qp, &rollback_wqe, &rollback_psn);
> +
> skb = rxe_init_req_packet(qp, wqe, opcode, payload, &pkt);
> if (unlikely(!skb)) {
> rxe_err_qp(qp, "failed to create packet for %s",
> @@ -929,29 +934,29 @@ int rxe_requester(struct rxe_qp *qp)
> goto err;
> }
>
> - /*
> - * To prevent a race on wqe access between requester and completer,
> - * wqe members state and psn need to be set before calling
> - * rxe_xmit_packet().
> - * Otherwise, completer might initiate an unjustified retry flow.
> - */
> - save_state(wqe, qp, &rollback_wqe, &rollback_psn);
> + /* update wqe state as though we had sent it */
> update_wqe_state(qp, wqe, &pkt);
> update_wqe_psn(qp, wqe, &pkt, payload);
>
> err = rxe_xmit_packet(qp, &pkt, skb);
> if (err) {
> - qp->need_req_skb = 1;
> + if (err != -EAGAIN) {
> + wqe->status = IB_WC_LOC_QP_OP_ERR;
> + goto err;
> + }
>
> + /* the packet was dropped so reset wqe to the state
> + * before we sent it so we can try to resend
> + */
> rollback_state(wqe, qp, &rollback_wqe, rollback_psn);
>
> - if (err == -EAGAIN) {
> - rxe_sched_task(&qp->req.task);
> - goto exit;
> - }
> + /* force a delay until the dropped packet is freed and
> + * the send queue is drained below the low water mark
> + */
> + qp->need_req_skb = 1;
>
> - wqe->status = IB_WC_LOC_QP_OP_ERR;
> - goto err;
> + rxe_sched_task(&qp->req.task);
> + goto exit;
> }
>
> update_state(qp, &pkt);
Never mind. Missing some prereq patches.
prev parent reply other threads:[~2023-07-21 18:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-21 18:04 [PATCH] RDMA/rxe: Fix incomplete state save in rxe_requester Bob Pearson
2023-07-21 18:59 ` Bob Pearson [this message]
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=c6f80a3c-9a10-2cf0-b126-2221fdad884f@gmail.com \
--to=rpearsonhpe@gmail.com \
--cc=jgg@nvidia.com \
--cc=jhack@hpe.com \
--cc=leon@kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=zyjzyj2000@gmail.com \
/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