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 | |
| 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>
| -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 | } |
