diff options
author | Neil Brown <neilb@suse.de> | 2010-03-01 00:51:14 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2010-05-03 08:33:00 -0400 |
commit | b48fa6b99100dc7772af3cd276035fcec9719ceb (patch) | |
tree | 415dba87c6c5de0ab85a8493f864838f4f3cc005 /net/sunrpc | |
parent | 26c0c75e69265961e891ed80b38fb62a548ab371 (diff) |
sunrpc: centralise most calls to svc_xprt_received
svc_xprt_received must be called when ->xpo_recvfrom has finished
receiving a message, so that the XPT_BUSY flag will be cleared and
if necessary, requeued for further work.
This call is currently made in each ->xpo_recvfrom function, often
from multiple different points. In each case it is the earliest point
on a particular path where it is known that the protection provided by
XPT_BUSY is no longer needed.
However there are (still) some error paths which do not call
svc_xprt_received, and requiring each ->xpo_recvfrom to make the call
does not encourage robustness.
So: move the svc_xprt_received call to be made just after the
call to ->xpo_recvfrom(), and move it of the various ->xpo_recvfrom
methods.
This means that it may not be called at the earliest possible instant,
but this is unlikely to be a measurable performance issue.
Note that there are still other calls to svc_xprt_received as it is
also needed when an xprt is newly created.
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 4 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 15 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 3 |
3 files changed, 4 insertions, 18 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index c334f5413c60..75f9aa2eb089 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -743,8 +743,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
743 | if (rqstp->rq_deferred) { | 743 | if (rqstp->rq_deferred) { |
744 | svc_xprt_received(xprt); | 744 | svc_xprt_received(xprt); |
745 | len = svc_deferred_recv(rqstp); | 745 | len = svc_deferred_recv(rqstp); |
746 | } else | 746 | } else { |
747 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | 747 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); |
748 | svc_xprt_received(xprt); | ||
749 | } | ||
748 | dprintk("svc: got len=%d\n", len); | 750 | dprintk("svc: got len=%d\n", len); |
749 | } | 751 | } |
750 | 752 | ||
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index a29f259204e6..a33892733643 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -547,7 +547,6 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
547 | dprintk("svc: recvfrom returned error %d\n", -err); | 547 | dprintk("svc: recvfrom returned error %d\n", -err); |
548 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 548 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
549 | } | 549 | } |
550 | svc_xprt_received(&svsk->sk_xprt); | ||
551 | return -EAGAIN; | 550 | return -EAGAIN; |
552 | } | 551 | } |
553 | len = svc_addr_len(svc_addr(rqstp)); | 552 | len = svc_addr_len(svc_addr(rqstp)); |
@@ -562,11 +561,6 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
562 | svsk->sk_sk->sk_stamp = skb->tstamp; | 561 | svsk->sk_sk->sk_stamp = skb->tstamp; |
563 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ | 562 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ |
564 | 563 | ||
565 | /* | ||
566 | * Maybe more packets - kick another thread ASAP. | ||
567 | */ | ||
568 | svc_xprt_received(&svsk->sk_xprt); | ||
569 | |||
570 | len = skb->len - sizeof(struct udphdr); | 564 | len = skb->len - sizeof(struct udphdr); |
571 | rqstp->rq_arg.len = len; | 565 | rqstp->rq_arg.len = len; |
572 | 566 | ||
@@ -917,7 +911,6 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
917 | if (len < want) { | 911 | if (len < want) { |
918 | dprintk("svc: short recvfrom while reading record " | 912 | dprintk("svc: short recvfrom while reading record " |
919 | "length (%d of %d)\n", len, want); | 913 | "length (%d of %d)\n", len, want); |
920 | svc_xprt_received(&svsk->sk_xprt); | ||
921 | goto err_again; /* record header not complete */ | 914 | goto err_again; /* record header not complete */ |
922 | } | 915 | } |
923 | 916 | ||
@@ -953,7 +946,6 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
953 | if (len < svsk->sk_reclen) { | 946 | if (len < svsk->sk_reclen) { |
954 | dprintk("svc: incomplete TCP record (%d of %d)\n", | 947 | dprintk("svc: incomplete TCP record (%d of %d)\n", |
955 | len, svsk->sk_reclen); | 948 | len, svsk->sk_reclen); |
956 | svc_xprt_received(&svsk->sk_xprt); | ||
957 | goto err_again; /* record not complete */ | 949 | goto err_again; /* record not complete */ |
958 | } | 950 | } |
959 | len = svsk->sk_reclen; | 951 | len = svsk->sk_reclen; |
@@ -961,14 +953,11 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
961 | 953 | ||
962 | return len; | 954 | return len; |
963 | error: | 955 | error: |
964 | if (len == -EAGAIN) { | 956 | if (len == -EAGAIN) |
965 | dprintk("RPC: TCP recv_record got EAGAIN\n"); | 957 | dprintk("RPC: TCP recv_record got EAGAIN\n"); |
966 | svc_xprt_received(&svsk->sk_xprt); | ||
967 | } | ||
968 | return len; | 958 | return len; |
969 | err_delete: | 959 | err_delete: |
970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 960 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
971 | svc_xprt_received(&svsk->sk_xprt); | ||
972 | err_again: | 961 | err_again: |
973 | return -EAGAIN; | 962 | return -EAGAIN; |
974 | } | 963 | } |
@@ -1110,7 +1099,6 @@ out: | |||
1110 | svsk->sk_tcplen = 0; | 1099 | svsk->sk_tcplen = 0; |
1111 | 1100 | ||
1112 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); | 1101 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); |
1113 | svc_xprt_received(&svsk->sk_xprt); | ||
1114 | if (serv->sv_stats) | 1102 | if (serv->sv_stats) |
1115 | serv->sv_stats->nettcpcnt++; | 1103 | serv->sv_stats->nettcpcnt++; |
1116 | 1104 | ||
@@ -1119,7 +1107,6 @@ out: | |||
1119 | err_again: | 1107 | err_again: |
1120 | if (len == -EAGAIN) { | 1108 | if (len == -EAGAIN) { |
1121 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); | 1109 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); |
1122 | svc_xprt_received(&svsk->sk_xprt); | ||
1123 | return len; | 1110 | return len; |
1124 | } | 1111 | } |
1125 | error: | 1112 | error: |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index f92e37eb413c..0194de814933 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | |||
@@ -566,7 +566,6 @@ static int rdma_read_complete(struct svc_rqst *rqstp, | |||
566 | ret, rqstp->rq_arg.len, rqstp->rq_arg.head[0].iov_base, | 566 | ret, rqstp->rq_arg.len, rqstp->rq_arg.head[0].iov_base, |
567 | rqstp->rq_arg.head[0].iov_len); | 567 | rqstp->rq_arg.head[0].iov_len); |
568 | 568 | ||
569 | svc_xprt_received(rqstp->rq_xprt); | ||
570 | return ret; | 569 | return ret; |
571 | } | 570 | } |
572 | 571 | ||
@@ -665,7 +664,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) | |||
665 | rqstp->rq_arg.head[0].iov_len); | 664 | rqstp->rq_arg.head[0].iov_len); |
666 | rqstp->rq_prot = IPPROTO_MAX; | 665 | rqstp->rq_prot = IPPROTO_MAX; |
667 | svc_xprt_copy_addrs(rqstp, xprt); | 666 | svc_xprt_copy_addrs(rqstp, xprt); |
668 | svc_xprt_received(xprt); | ||
669 | return ret; | 667 | return ret; |
670 | 668 | ||
671 | close_out: | 669 | close_out: |
@@ -678,6 +676,5 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) | |||
678 | */ | 676 | */ |
679 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | 677 | set_bit(XPT_CLOSE, &xprt->xpt_flags); |
680 | defer: | 678 | defer: |
681 | svc_xprt_received(xprt); | ||
682 | return 0; | 679 | return 0; |
683 | } | 680 | } |