aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2017-06-23 17:18:08 -0400
committerJ. Bruce Fields <bfields@redhat.com>2017-06-28 14:21:44 -0400
commit2d6491a56c76f2d6c22aaa710e2a4d04ad41529b (patch)
tree2ca744381b0491d7c908d1004658e7a8bf16971d
parentca5c76aba7502d52a6019358ec04bd4d734037d7 (diff)
svcrdma: Don't account for Receive queue "starvation"
>From what I can tell, calling ->recvfrom when there is no work to do is a normal part of operation. This is the only way svc_recv can tell when there is no more data ready to receive on the transport. Neither the TCP nor the UDP transport implementations have a "starve" metric. The cost of receive starvation accounting is bumping an atomic, which results in extra (IMO unnecessary) bus traffic between CPU sockets, while holding a spin lock. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index b48089314f85..1452bd02d857 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -844,9 +844,9 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
844 struct svc_xprt *xprt = rqstp->rq_xprt; 844 struct svc_xprt *xprt = rqstp->rq_xprt;
845 struct svcxprt_rdma *rdma_xprt = 845 struct svcxprt_rdma *rdma_xprt =
846 container_of(xprt, struct svcxprt_rdma, sc_xprt); 846 container_of(xprt, struct svcxprt_rdma, sc_xprt);
847 struct svc_rdma_op_ctxt *ctxt = NULL; 847 struct svc_rdma_op_ctxt *ctxt;
848 struct rpcrdma_msg *rmsgp; 848 struct rpcrdma_msg *rmsgp;
849 int ret = 0; 849 int ret;
850 850
851 dprintk("svcrdma: rqstp=%p\n", rqstp); 851 dprintk("svcrdma: rqstp=%p\n", rqstp);
852 852
@@ -863,21 +863,13 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
863 struct svc_rdma_op_ctxt, list); 863 struct svc_rdma_op_ctxt, list);
864 list_del(&ctxt->list); 864 list_del(&ctxt->list);
865 } else { 865 } else {
866 atomic_inc(&rdma_stat_rq_starve); 866 /* No new incoming requests, terminate the loop */
867 clear_bit(XPT_DATA, &xprt->xpt_flags); 867 clear_bit(XPT_DATA, &xprt->xpt_flags);
868 ctxt = NULL; 868 spin_unlock(&rdma_xprt->sc_rq_dto_lock);
869 return 0;
869 } 870 }
870 spin_unlock(&rdma_xprt->sc_rq_dto_lock); 871 spin_unlock(&rdma_xprt->sc_rq_dto_lock);
871 if (!ctxt) { 872
872 /* This is the EAGAIN path. The svc_recv routine will
873 * return -EAGAIN, the nfsd thread will go to call into
874 * svc_recv again and we shouldn't be on the active
875 * transport list
876 */
877 if (test_bit(XPT_CLOSE, &xprt->xpt_flags))
878 goto defer;
879 goto out;
880 }
881 dprintk("svcrdma: processing ctxt=%p on xprt=%p, rqstp=%p\n", 873 dprintk("svcrdma: processing ctxt=%p on xprt=%p, rqstp=%p\n",
882 ctxt, rdma_xprt, rqstp); 874 ctxt, rdma_xprt, rqstp);
883 atomic_inc(&rdma_stat_recv); 875 atomic_inc(&rdma_stat_recv);
@@ -920,7 +912,6 @@ complete:
920 + rqstp->rq_arg.page_len 912 + rqstp->rq_arg.page_len
921 + rqstp->rq_arg.tail[0].iov_len; 913 + rqstp->rq_arg.tail[0].iov_len;
922 svc_rdma_put_context(ctxt, 0); 914 svc_rdma_put_context(ctxt, 0);
923 out:
924 dprintk("svcrdma: ret=%d, rq_arg.len=%u, " 915 dprintk("svcrdma: ret=%d, rq_arg.len=%u, "
925 "rq_arg.head[0].iov_base=%p, rq_arg.head[0].iov_len=%zd\n", 916 "rq_arg.head[0].iov_base=%p, rq_arg.head[0].iov_len=%zd\n",
926 ret, rqstp->rq_arg.len, 917 ret, rqstp->rq_arg.len,