From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F13E37F006 for ; Wed, 9 Sep 2026 09:26:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788945971; cv=none; b=kPCSX4WM+zfXdBgvRPpRuPgELp7M1weHDGnDukS2MQKE4OFqIp5baiOSN+utS/sABwhJ5ToaXocY9wCCXdkBBE8V6mQRYNBwP7WM9felJIwG7p8/iNNw4/S/hAbbAzD+0qBRkUoeRHZuIAdC/EVxdbX5dlnxvr6ow4xqREfJF34= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788945971; c=relaxed/simple; bh=kDklEb3HmZ8B0IdW2kViAHKSJvuDYjEbKDAE55vLld0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U+Z+g29OHZ3fMu7Mbi29bFb45FnrT3k1lfQ0J2oq+vIOFloCcoNKUZCv23miQy9xfhwDMgMhTwNf5yGuHYK9T6Qv3BlekZ+O+rndH99fZv6kgWAklI/7/9qNyF99dOdBr9RoLiJw+ynKfYjQOB1kcQWAX7xfUkEOPTOOr/yWB90= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lROWlM8i; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lROWlM8i" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3EA2B1F00A3D; Wed, 9 Sep 2026 09:26:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788945969; bh=3s/6LmBBB6L11FNxPFQZ/NbiM7eyX25elB+SqnDRU2Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=lROWlM8iHwoWBIz4ZOEzDDM7PiBm605fvitQnyGFU4bLmzwPByLs6jfyCkNpsWhy8 mhkm1FD/wUoiM+xq5ifzxP5S1bdwp6t5+GP0j1xriGWvAY9Z9KZMEVXmE2kbmAKzvq Eh1gBwyWGJlVvPQ0snRWWAJpxCxVoAs12dVSgcMOttqJHOjYefHblGlDZieC3ov3NY aWTpwbCcLUSHVF9pV7FXBqgW/iBluQJZM9Bz+WXkpt5KHzAR/YkNCOGrPN0qPOUuOs LEGrqlWWLTYhL9M6sY3oyNEtUjmLWjo0QmqsG5nMiTLmjz4OIjHWKBvykk1GNjj3Ie YdMWIvHcGC+dQ== From: Sasha Levin To: stable@vger.kernel.org Cc: Chuck Lever , Sasha Levin Subject: [PATCH 6.6.y 3/4] svcrdma: Add back svcxprt_rdma::sc_read_complete_q Date: Wed, 9 Sep 2026 05:26:05 -0400 Message-ID: <20260909092606.1293505-3-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260909092606.1293505-1-sashal@kernel.org> References: <2026090309-wooing-reassign-9ecf@gregkh> <20260909092606.1293505-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Chuck Lever [ Upstream commit a937693a82fd2211c5e52b638959d1486a77d16a ] Having an nfsd thread waiting for an RDMA Read completion is problematic if the Read responder (ie, the client) stops responding. We need to go back to handling RDMA Reads by allowing the nfsd thread to return to the svc scheduler, then waking a second thread finish the RPC message once the Read completion fires. As a next step, add a list_head upon which completed Reads are queued. A subsequent patch will make use of this queue. Signed-off-by: Chuck Lever Stable-dep-of: 3779b7b9e7d1 ("svcrdma: Validate Read chunk positions before reconstruction") Signed-off-by: Sasha Levin --- include/linux/sunrpc/svc_rdma.h | 1 + net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 37 +++++++++++++++++++++++- net/sunrpc/xprtrdma/svc_rdma_transport.c | 1 + 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 12ffe6d43b9dc..a702a6cb2a035 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -97,6 +97,7 @@ struct svcxprt_rdma { u32 sc_pending_recvs; u32 sc_recv_batch; struct list_head sc_rq_dto_q; + struct list_head sc_read_complete_q; spinlock_t sc_rq_dto_lock; struct ib_qp *sc_qp; struct ib_cq *sc_rq_cq; diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index a6eecdc592412..fd8e1a3b86837 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -378,6 +378,10 @@ void svc_rdma_flush_recv_queues(struct svcxprt_rdma *rdma) { struct svc_rdma_recv_ctxt *ctxt; + while ((ctxt = svc_rdma_next_recv_ctxt(&rdma->sc_read_complete_q))) { + list_del(&ctxt->rc_list); + svc_rdma_recv_ctxt_put(rdma, ctxt); + } while ((ctxt = svc_rdma_next_recv_ctxt(&rdma->sc_rq_dto_q))) { list_del(&ctxt->rc_list); svc_rdma_recv_ctxt_put(rdma, ctxt); @@ -765,6 +769,30 @@ static bool svc_rdma_is_reverse_direction_reply(struct svc_xprt *xprt, return true; } +static noinline void svc_rdma_read_complete(struct svc_rqst *rqstp, + struct svc_rdma_recv_ctxt *ctxt) +{ + int i; + + /* Transfer the Read chunk pages into @rqstp.rq_pages, replacing + * the rq_pages that were already allocated for this rqstp. + */ + release_pages(rqstp->rq_respages, ctxt->rc_page_count); + for (i = 0; i < ctxt->rc_page_count; i++) + rqstp->rq_pages[i] = ctxt->rc_pages[i]; + + /* Update @rqstp's result send buffer to start after the + * last page in the RDMA Read payload. + */ + rqstp->rq_respages = &rqstp->rq_pages[ctxt->rc_page_count]; + rqstp->rq_next_page = rqstp->rq_respages + 1; + + /* Prevent svc_rdma_recv_ctxt_put() from releasing the + * pages in ctxt::rc_pages a second time. + */ + ctxt->rc_page_count = 0; +} + /** * svc_rdma_recvfrom - Receive an RPC call * @rqstp: request structure into which to receive an RPC Call @@ -809,8 +837,14 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) rqstp->rq_xprt_ctxt = NULL; - ctxt = NULL; spin_lock(&rdma_xprt->sc_rq_dto_lock); + ctxt = svc_rdma_next_recv_ctxt(&rdma_xprt->sc_read_complete_q); + if (ctxt) { + list_del(&ctxt->rc_list); + spin_unlock_bh(&rdma_xprt->sc_rq_dto_lock); + svc_rdma_read_complete(rqstp, ctxt); + goto complete; + } ctxt = svc_rdma_next_recv_ctxt(&rdma_xprt->sc_rq_dto_q); if (ctxt) list_del(&ctxt->rc_list); @@ -848,6 +882,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) goto out_readfail; } +complete: rqstp->rq_xprt_ctxt = ctxt; rqstp->rq_prot = IPPROTO_MAX; svc_xprt_copy_addrs(rqstp, xprt); diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index b8d13b522298b..90eeddc5c95f6 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -134,6 +134,7 @@ static struct svcxprt_rdma *svc_rdma_create_xprt(struct svc_serv *serv, svc_xprt_init(net, &svc_rdma_class, &cma_xprt->sc_xprt, serv); INIT_LIST_HEAD(&cma_xprt->sc_accept_q); INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q); + INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q); init_llist_head(&cma_xprt->sc_send_ctxts); init_llist_head(&cma_xprt->sc_recv_ctxts); init_llist_head(&cma_xprt->sc_rw_ctxts); -- 2.53.0