From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (unknown [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id E571E8015A for ; Thu, 10 Sep 2026 15:26:24 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 68AFP6e0026478; Thu, 10 Sep 2026 18:25:07 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 68AFP6e0026478 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="rz0PCoTb" Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 68AFP5Mn026474 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Thu, 10 Sep 2026 18:25:05 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 68AFP5Mn026474 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-49b7c1dc61eso57716175e9.3 for ; Thu, 10 Sep 2026 08:25:05 -0700 (PDT) X-Forwarded-Encrypted: i=2; AKwUvBw+Zc+VN39Qx+7Vjk1P1aBDiQfzGTtavF3zBEXPa+tfptsN8wEilpYc/qknJKcYqWCYJUlHqw==@openvz.org X-Gm-Message-State: AFuF++lE+RPXyhk3PjMPerCEWueK6yHo3q53wjxphhMJ0x3FbW90lajY 2SjpJVwFJBuNKxJC4x7NIrvpitkHOvkzT+/lsHh3/1TJczitlAqQ8hACQqpL+AkzX6J4EjZ6nzB 8JF1pfT8KrSj1ybetFUJR3WZ6SsfnonoRHIeWb/83dubpxCqEj5UqSQ== X-Gm-Gg: AYBFou1L8sHiBOe0ILJpzZiPVRxdBA80gpqE+8WpeIx8yYS+7dJQTMhJaA/bJxTJ7ol bFx4go4pZWZrIPVpnlf73YlK+3RghXEAxscmGDsaSCbmuZpcLuwu00dwsZJM0xdks4KA7jAzuaf fSOtBEa0MGeqlxBRidBYoCm6F8q2ty/A6afwAtMUvanetx8z9ezMcADc+8AljwKM056jTDOIVd8 oYEQB522awxFB5Dh+SaRGXaZ44Sn0HNpUPMIxhlizU4jbuUuy1Tfwe05iaBZTdFhmO+fgvsKx4G FfHWJ4jr/UgrAHXXtNjf9njM9K/FxyRT5uIETvzBTInuS8aU2zyF6WeZqLxw3vxLeFzO2mXn6ok mYuxZYDM74+8aIuftfCf0zhg+lasB X-Received: by 2002:a05:600c:55d2:b0:49c:fa21:e74b with SMTP id 5b1f17b1804b1-49d259252bemr60564455e9.33.1789053904697; Thu, 10 Sep 2026 08:25:04 -0700 (PDT) X-Received: by 2002:a05:600c:55d2:b0:49c:fa21:e74b with SMTP id 5b1f17b1804b1-49d259252bemr60563885e9.33.1789053904106; Thu, 10 Sep 2026 08:25:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1789053904; cv=none; d=google.com; s=arc-20260327; b=RMU43CDIaPPykstLq6JHiF2v8VnTZxKQ8Rl3yTIwh9cglrTRSyoCkbes8KZADYFP/Y ADET+SjnfJBWkL0TG101MkAfQW4ExwkiTOesN84HVs2eSTIJiGj8IPD+BOngJ17dapGk 35x6zgDAZLj248aRKZQo1xgX9Wyc9sWE4Enkvqd7hU+7hmCrI09nGPo2Ycr66jd7ondw dhEFgAzhnLUcB+yViYzqXMjU9s27sjhlhKNM48t58LnshVOw9R6SdXIcg4m45T/bGWaa HHQZ7pTqpb1FVzxIf546cgAUAfPtb+P6JaS0kVg2zSO86xA62FIlI5nthdMdcu1gVXvo rhdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:dkim-signature; bh=7Vy8cjL2AByGUP/3Rw8UnJfRTimrnleoIwkY9/4eTaQ=; fh=4Jv222c4KVXB4X5Nzu8wmQHnNxhpNIGtWW+08r7iZzg=; b=r2KLq+klOrey+hArwGPcy5TZFeTThS5k1S54RZ3sGGyaHJ5seeZApDiGS/CtfFONF9 7uoo0ImckDtktjX9/JtiqMkElZRmgrrvKUqGhRggSIl285xh16V96seVe1SioGjymIGW o2pXdxhG6Z/uSqrx6JuJpDYlhMM0/UnJFIKDrpu5FHazm2FLH1Y3RyG/ExTg30s67NJK Y1UAvvLsyEmJhAOx1ZGesYCEDKg+fKxyYIEIvtDh4EZB8Ic5OCOBDRzEGo7z0pQR2J17 6MzG8MiZONwh9SP6uEyo7ZJ7sR6uGXxPqBqayM4Io2MclMs0RKdr9ICeHJ3fqfB23+iw h0vA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=rz0PCoTb; spf=pass (google.com: domain of aleksandr.kharten@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=aleksandr.kharten@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com Received: from relay.virtuozzo.com (relay.virtuozzo.com. [130.117.225.111]) by mx.google.com with ESMTPS id ffacd0b85a97d-485885d3e01si42050855f8f.343.2026.09.10.08.25.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2026 08:25:03 -0700 (PDT) Received-SPF: pass (google.com: domain of aleksandr.kharten@virtuozzo.com designates 130.117.225.111 as permitted sender) client-ip=130.117.225.111; Authentication-Results: mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=rz0PCoTb; spf=pass (google.com: domain of aleksandr.kharten@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=aleksandr.kharten@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=Message-Id:Content-Type:MIME-Version:Subject:Date :From; bh=7Vy8cjL2AByGUP/3Rw8UnJfRTimrnleoIwkY9/4eTaQ=; b=rz0PCoTb05G0X6Jh8pN 2qOR+Y3/ud4IfltBBzRtHRDduZXLbycoeDb4TVOowsf8YFhpkvnMCW7OTsJfbIHTzEByC611aGCAG 4PUSqJ9Cl1m871/+1nkzT0YeTvbtYMDLAye470ROhcwD6EpXlW5v8Yz7AseQzW2caE9reBM9zm089 iV4z6z9bkrXVdki0WotmZtfzVwmm08WqpVyZJhR9i8KzKNRGzlvlrkNONsJBDcBAYWpFeoi6hPnw0 eqmygQvZ09ojcFGXMGMrQ+H+WK7KfA9dJuKwfenoFX0YRWObvPxlyMrmWgtjRhb7vAbn3cHg0NfEL 5jwH2TYkou0NF/g==; Received: from [192.168.26.78] (helo=[127.0.1.1]) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1x4gbV-00GhP2-2t; Thu, 10 Sep 2026 17:25:01 +0200 From: Aleksandr Kharten Date: Thu, 10 Sep 2026 19:24:59 +0400 MIME-Version: 1.0 Message-Id: <20260910-b4-vstor-141673-fix-lost-rdma-reply-v1-1-5cdd9b8180ab@virtuozzo.com> X-B4-Tracking: v=1; b=H4sIAMrLomoC/yWNQQ6CMBBFr0Jm7SQtNDR4FeOipaPWICUzpVEJd 7fq8v38vLeBEEcSODYbMJUoMc0V9KGB8ebmK2EMlaFVba8GNaA3WCQnRm10bzu8xCdOSTJyeDh kWqYXWhesIa97HTqopoWp3n6VE5S3VnD+r7L6O435G4B9/wAmL0WyjQAAAA== X-Change-ID: 20260909-b4-vstor-141673-fix-lost-rdma-reply-7ad74eb161d3 To: Alexey Kuznetsov , Konstantin Khorenko X-Mailer: b4 0.16.0 X-OZ-Fwd: true Cc: Aleksandr Kharten , devel@openvz.org, Kui Liu , Andrey Zaitsev Subject: [Devel] [PATCH vz10] fs/fuse kio: fix lost rpc response over rdma io X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org Call ->done() when the peer's RDMA_READ_ACK arrives rather than waiting for our own TX completion as well, so that a large message is reported as sent before its response can come back. The tx itself is still released only once both events are in, as the HCA may still be using its MR. https://virtuozzo.atlassian.net/browse/VSTOR-141673 --- A message larger than RDMA_THRESHOLD is not pushed to the peer but advertised: rio_submit() registers its payload in an MR and sends a header carrying the rkey, then the peer pulls the payload with RDMA READ and reports RDMA_READ_ACK. Hence ->done() cannot be called right after rio_tx_post_send() as it is for small messages, and rio_handle_tx() used to call it only once both the peer's ack and our own TX completion had arrived, counting the two events with ++tx->tx_state. These two events are not ordered. The peer's HCA coalesces its RC acknowledgment, so our TX completion can be reported hundreds of microseconds after the peer has acked the RDMA READ and has already answered the request. The response then reaches handle_response() before pcs_rpc_sent() has put the request on ep->pending_queue, so pcs_rpc_lookup_xid() finds nothing, the response is dropped silently, and the request can only be completed by the kill calendar one response timeout later. Call ->done() when RDMA_READ_ACK arrives instead. The ack means the peer has the payload, and it cannot be overtaken by the response, as both come from the same RX queue and are handled in order, so the request always reaches ep->pending_queue before its response is looked up. Releasing the tx still requires both events, as the HCA may still be using its MR; the payload it works on does not belong to the message, which was either copied into the MR of the tx or is pinned by the page references the tx took itself in pcs_sgl_buf_init_from_msg(). Signed-off-by: Aleksandr Kharten --- fs/fuse/kio/pcs/pcs_rdma_io.c | 55 ++++++++++++++++++++++++++++++++----------- fs/fuse/kio/pcs/pcs_rdma_rw.h | 8 +++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_rdma_io.c b/fs/fuse/kio/pcs/pcs_rdma_io.c index 1c464e0e60f3..171e0bf3098b 100644 --- a/fs/fuse/kio/pcs/pcs_rdma_io.c +++ b/fs/fuse/kio/pcs/pcs_rdma_io.c @@ -60,8 +60,9 @@ struct rio_rx { enum { TX_FREE, /* free tx request available for use */ - TX_WAIT_FOR_TX_COMPL, /* tx request sent, wait for TX completion */ - TX_WAIT_FOR_READ_ACK, /* wait for peer to ack RDMA read */ + TX_WAIT_FOR_TX_COMPL, /* wait for TX completion and RDMA read ack */ + TX_WAIT_FOR_READ_ACK, /* TX completed, wait for RDMA read ack */ + TX_READ_ACKED, /* msg completed on ack, wait for TX completion */ TX_MSG_DONE, /* default: call msg->done() */ TX_SUBMIT_RDMA_READ_ACK, /* let our peer know that our RDMA_READ is done */ }; @@ -720,10 +721,9 @@ static int rio_submit(struct pcs_rdmaio *rio, struct pcs_msg *msg, int type, u64 * lose an error. * * But, if the message is big enough to trigger RDMA READ - * transfer, we are going to call ->done() callback after we - * receive RDMA_READ_ACK message from our peer. Since messages - * in a single RX queue are guaranteed to come in order, there - * is no race in this case. + * transfer, ->done() cannot be called here: the peer has not + * pulled the payload yet. It is called from rio_handle_tx() + * when RDMA_READ_ACK arrives, see the comment there. */ rio_msg_sent(rio, tx, msg, rb == NULL); } @@ -795,7 +795,21 @@ static inline void rio_kick_write_queue(struct pcs_rdmaio *rio) rio_enable_kick(rio); } -static void rio_handle_tx(struct pcs_rdmaio *rio, struct rio_tx *tx, int ok) +/* Events a tx waits for, see rio_handle_tx() */ +enum rio_tx_event { + TX_EV_SEND_CQE, /* TX completion from our HCA */ + TX_EV_READ_ACK, /* RDMA_READ_ACK from peer */ +}; + +/* + * Handle one of the two events @tx waits for. They are not ordered: the peer + * may ack the RDMA read, and send its response, before our HCA reports the + * send. Hence msg->done() is called on TX_EV_READ_ACK, which the response + * cannot overtake as both come from the same RX queue, while the tx is + * released only after both events, as the HCA may still be using its MR. + */ +static void rio_handle_tx(struct pcs_rdmaio *rio, struct rio_tx *tx, int ok, + enum rio_tx_event ev) { struct pcs_msg *msg = tx->msg; u64 xid = tx->xid; @@ -814,9 +828,25 @@ static void rio_handle_tx(struct pcs_rdmaio *rio, struct rio_tx *tx, int ok) rio->n_rdma_read_ongoing--; break; case TX_WAIT_FOR_TX_COMPL: - case TX_WAIT_FOR_READ_ACK: - if (++tx->tx_state != TX_MSG_DONE) + if (ev == TX_EV_SEND_CQE) { + /* Still waiting for the peer to ack RDMA read */ + tx->tx_state = TX_WAIT_FOR_READ_ACK; return; + } + /* + * The peer is done with the payload, complete msg now + * and keep the tx until our own TX completion arrives. + * The tx must keep no reference to msg, which may be + * freed by the completion below. + */ + tx->tx_state = TX_READ_ACKED; + tx->msg = NULL; + pcs_rdma_msg_detach(&tx->send.msg); + break; + case TX_WAIT_FOR_READ_ACK: + rio_put_tx(rio->dev, tx); + break; + case TX_READ_ACKED: rio_put_tx(rio->dev, tx); break; case TX_MSG_DONE: @@ -932,7 +962,7 @@ static int rio_handle_rx_read_ack(struct pcs_rdmaio *rio, list_for_each_entry(tx, &rio->active_txs, list) if (tx->xid == rack->xid) { list_del(&tx->list); - rio_handle_tx(rio, tx, !rack->status); + rio_handle_tx(rio, tx, !rack->status, TX_EV_READ_ACK); return 0; } @@ -1073,7 +1103,7 @@ static void rio_tx_done(struct rio_cqe *cqe, bool sync_mode) if (sync_mode) rio_put_tx(rio->dev, tx); else - rio_handle_tx(rio, tx, cqe->status == IB_WC_SUCCESS); + rio_handle_tx(rio, tx, cqe->status == IB_WC_SUCCESS, TX_EV_SEND_CQE); } static inline struct rio_cqe* rio_poll_cq(struct pcs_rdmaio *rio) @@ -1258,9 +1288,6 @@ struct pcs_rdmaio* pcs_rdma_create(int hdr_size, struct rdma_cm_id *cmid, BUG_ON(!mutex_is_locked(&ep->mutex)); - BUILD_BUG_ON((TX_WAIT_FOR_READ_ACK - TX_WAIT_FOR_TX_COMPL) != 1); - BUILD_BUG_ON((TX_MSG_DONE - TX_WAIT_FOR_READ_ACK) != 1); - if (queue_depth < RIO_QUEUE_DEPTH) queue_depth = RIO_QUEUE_DEPTH; else if (queue_depth > RIO_MAX_QUEUE_DEPTH) diff --git a/fs/fuse/kio/pcs/pcs_rdma_rw.h b/fs/fuse/kio/pcs/pcs_rdma_rw.h index c8529ed16f13..cc7a3fef4863 100644 --- a/fs/fuse/kio/pcs/pcs_rdma_rw.h +++ b/fs/fuse/kio/pcs/pcs_rdma_rw.h @@ -188,4 +188,12 @@ int pcs_rdma_msg_init(struct pcs_rdma_msg *rdma_msg, struct pcs_msg *msg, bool try_to_map); void pcs_rdma_msg_destroy(struct pcs_rdma_msg *rdma_msg); +/* + * Drop the reference to the msg being sent. + */ +static inline void pcs_rdma_msg_detach(struct pcs_rdma_msg *rdma_msg) +{ + rdma_msg->msg = NULL; +} + #endif /* _PCS_RMDA_RW_H_ */ --- base-commit: 3466ec0b2cdf9d49dbb36d7b5ed9b36dfb2fb04d change-id: 20260909-b4-vstor-141673-fix-lost-rdma-reply-7ad74eb161d3 Best regards, -- Aleksandr Kharten _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel