Skip to content

Commit a937693

Browse files
committed
svcrdma: Add back svcxprt_rdma::sc_read_complete_q
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 <chuck.lever@oracle.com>
1 parent 4d9d69d commit a937693

3 files changed

Lines changed: 38 additions & 1 deletion

File tree

include/linux/sunrpc/svc_rdma.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ struct svcxprt_rdma {
9898
u32 sc_pending_recvs;
9999
u32 sc_recv_batch;
100100
struct list_head sc_rq_dto_q;
101+
struct list_head sc_read_complete_q;
101102
spinlock_t sc_rq_dto_lock;
102103
struct ib_qp *sc_qp;
103104
struct ib_cq *sc_rq_cq;

net/sunrpc/xprtrdma/svc_rdma_recvfrom.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ void svc_rdma_flush_recv_queues(struct svcxprt_rdma *rdma)
382382
{
383383
struct svc_rdma_recv_ctxt *ctxt;
384384

385+
while ((ctxt = svc_rdma_next_recv_ctxt(&rdma->sc_read_complete_q))) {
386+
list_del(&ctxt->rc_list);
387+
svc_rdma_recv_ctxt_put(rdma, ctxt);
388+
}
385389
while ((ctxt = svc_rdma_next_recv_ctxt(&rdma->sc_rq_dto_q))) {
386390
list_del(&ctxt->rc_list);
387391
svc_rdma_recv_ctxt_put(rdma, ctxt);
@@ -763,6 +767,30 @@ static bool svc_rdma_is_reverse_direction_reply(struct svc_xprt *xprt,
763767
return true;
764768
}
765769

770+
static noinline void svc_rdma_read_complete(struct svc_rqst *rqstp,
771+
struct svc_rdma_recv_ctxt *ctxt)
772+
{
773+
int i;
774+
775+
/* Transfer the Read chunk pages into @rqstp.rq_pages, replacing
776+
* the rq_pages that were already allocated for this rqstp.
777+
*/
778+
release_pages(rqstp->rq_respages, ctxt->rc_page_count);
779+
for (i = 0; i < ctxt->rc_page_count; i++)
780+
rqstp->rq_pages[i] = ctxt->rc_pages[i];
781+
782+
/* Update @rqstp's result send buffer to start after the
783+
* last page in the RDMA Read payload.
784+
*/
785+
rqstp->rq_respages = &rqstp->rq_pages[ctxt->rc_page_count];
786+
rqstp->rq_next_page = rqstp->rq_respages + 1;
787+
788+
/* Prevent svc_rdma_recv_ctxt_put() from releasing the
789+
* pages in ctxt::rc_pages a second time.
790+
*/
791+
ctxt->rc_page_count = 0;
792+
}
793+
766794
/**
767795
* svc_rdma_recvfrom - Receive an RPC call
768796
* @rqstp: request structure into which to receive an RPC Call
@@ -807,8 +835,14 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
807835

808836
rqstp->rq_xprt_ctxt = NULL;
809837

810-
ctxt = NULL;
811838
spin_lock(&rdma_xprt->sc_rq_dto_lock);
839+
ctxt = svc_rdma_next_recv_ctxt(&rdma_xprt->sc_read_complete_q);
840+
if (ctxt) {
841+
list_del(&ctxt->rc_list);
842+
spin_unlock_bh(&rdma_xprt->sc_rq_dto_lock);
843+
svc_rdma_read_complete(rqstp, ctxt);
844+
goto complete;
845+
}
812846
ctxt = svc_rdma_next_recv_ctxt(&rdma_xprt->sc_rq_dto_q);
813847
if (ctxt)
814848
list_del(&ctxt->rc_list);
@@ -846,6 +880,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
846880
goto out_readfail;
847881
}
848882

883+
complete:
849884
rqstp->rq_xprt_ctxt = ctxt;
850885
rqstp->rq_prot = IPPROTO_MAX;
851886
svc_xprt_copy_addrs(rqstp, xprt);

net/sunrpc/xprtrdma/svc_rdma_transport.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ static struct svcxprt_rdma *svc_rdma_create_xprt(struct svc_serv *serv,
137137
svc_xprt_init(net, &svc_rdma_class, &cma_xprt->sc_xprt, serv);
138138
INIT_LIST_HEAD(&cma_xprt->sc_accept_q);
139139
INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q);
140+
INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q);
140141
init_llist_head(&cma_xprt->sc_send_ctxts);
141142
init_llist_head(&cma_xprt->sc_recv_ctxts);
142143
init_llist_head(&cma_xprt->sc_rw_ctxts);

0 commit comments

Comments
 (0)