diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2010-05-21 15:27:26 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-05-21 15:27:26 -0400 |
commit | ee9a3607fb03e804ddf624544105f4e34260c380 (patch) | |
tree | ce41b6e0fa10982a306f6c142a92dbf3c9961284 /net/sunrpc/xprt.c | |
parent | b492e95be0ae672922f4734acf3f5d35c30be948 (diff) | |
parent | d515e86e639890b33a09390d062b0831664f04a2 (diff) |
Merge branch 'master' into for-2.6.35
Conflicts:
fs/ext3/fsync.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r-- | net/sunrpc/xprt.c | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 42f09ade0044..3fc325399ee4 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/interrupt.h> | 43 | #include <linux/interrupt.h> |
44 | #include <linux/workqueue.h> | 44 | #include <linux/workqueue.h> |
45 | #include <linux/net.h> | 45 | #include <linux/net.h> |
46 | #include <linux/ktime.h> | ||
46 | 47 | ||
47 | #include <linux/sunrpc/clnt.h> | 48 | #include <linux/sunrpc/clnt.h> |
48 | #include <linux/sunrpc/metrics.h> | 49 | #include <linux/sunrpc/metrics.h> |
@@ -62,7 +63,6 @@ | |||
62 | * Local functions | 63 | * Local functions |
63 | */ | 64 | */ |
64 | static void xprt_request_init(struct rpc_task *, struct rpc_xprt *); | 65 | static void xprt_request_init(struct rpc_task *, struct rpc_xprt *); |
65 | static inline void do_xprt_reserve(struct rpc_task *); | ||
66 | static void xprt_connect_status(struct rpc_task *task); | 66 | static void xprt_connect_status(struct rpc_task *task); |
67 | static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); | 67 | static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); |
68 | 68 | ||
@@ -711,12 +711,16 @@ void xprt_connect(struct rpc_task *task) | |||
711 | if (task->tk_rqstp) | 711 | if (task->tk_rqstp) |
712 | task->tk_rqstp->rq_bytes_sent = 0; | 712 | task->tk_rqstp->rq_bytes_sent = 0; |
713 | 713 | ||
714 | task->tk_timeout = xprt->connect_timeout; | 714 | task->tk_timeout = task->tk_rqstp->rq_timeout; |
715 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status); | 715 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status); |
716 | |||
717 | if (test_bit(XPRT_CLOSING, &xprt->state)) | ||
718 | return; | ||
719 | if (xprt_test_and_set_connecting(xprt)) | ||
720 | return; | ||
716 | xprt->stat.connect_start = jiffies; | 721 | xprt->stat.connect_start = jiffies; |
717 | xprt->ops->connect(task); | 722 | xprt->ops->connect(task); |
718 | } | 723 | } |
719 | return; | ||
720 | } | 724 | } |
721 | 725 | ||
722 | static void xprt_connect_status(struct rpc_task *task) | 726 | static void xprt_connect_status(struct rpc_task *task) |
@@ -771,25 +775,19 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid) | |||
771 | } | 775 | } |
772 | EXPORT_SYMBOL_GPL(xprt_lookup_rqst); | 776 | EXPORT_SYMBOL_GPL(xprt_lookup_rqst); |
773 | 777 | ||
774 | /** | 778 | static void xprt_update_rtt(struct rpc_task *task) |
775 | * xprt_update_rtt - update an RPC client's RTT state after receiving a reply | ||
776 | * @task: RPC request that recently completed | ||
777 | * | ||
778 | */ | ||
779 | void xprt_update_rtt(struct rpc_task *task) | ||
780 | { | 779 | { |
781 | struct rpc_rqst *req = task->tk_rqstp; | 780 | struct rpc_rqst *req = task->tk_rqstp; |
782 | struct rpc_rtt *rtt = task->tk_client->cl_rtt; | 781 | struct rpc_rtt *rtt = task->tk_client->cl_rtt; |
783 | unsigned timer = task->tk_msg.rpc_proc->p_timer; | 782 | unsigned timer = task->tk_msg.rpc_proc->p_timer; |
783 | long m = usecs_to_jiffies(ktime_to_us(req->rq_rtt)); | ||
784 | 784 | ||
785 | if (timer) { | 785 | if (timer) { |
786 | if (req->rq_ntrans == 1) | 786 | if (req->rq_ntrans == 1) |
787 | rpc_update_rtt(rtt, timer, | 787 | rpc_update_rtt(rtt, timer, m); |
788 | (long)jiffies - req->rq_xtime); | ||
789 | rpc_set_timeo(rtt, timer, req->rq_ntrans - 1); | 788 | rpc_set_timeo(rtt, timer, req->rq_ntrans - 1); |
790 | } | 789 | } |
791 | } | 790 | } |
792 | EXPORT_SYMBOL_GPL(xprt_update_rtt); | ||
793 | 791 | ||
794 | /** | 792 | /** |
795 | * xprt_complete_rqst - called when reply processing is complete | 793 | * xprt_complete_rqst - called when reply processing is complete |
@@ -807,7 +805,9 @@ void xprt_complete_rqst(struct rpc_task *task, int copied) | |||
807 | task->tk_pid, ntohl(req->rq_xid), copied); | 805 | task->tk_pid, ntohl(req->rq_xid), copied); |
808 | 806 | ||
809 | xprt->stat.recvs++; | 807 | xprt->stat.recvs++; |
810 | task->tk_rtt = (long)jiffies - req->rq_xtime; | 808 | req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime); |
809 | if (xprt->ops->timer != NULL) | ||
810 | xprt_update_rtt(task); | ||
811 | 811 | ||
812 | list_del_init(&req->rq_list); | 812 | list_del_init(&req->rq_list); |
813 | req->rq_private_buf.len = copied; | 813 | req->rq_private_buf.len = copied; |
@@ -906,7 +906,7 @@ void xprt_transmit(struct rpc_task *task) | |||
906 | return; | 906 | return; |
907 | 907 | ||
908 | req->rq_connect_cookie = xprt->connect_cookie; | 908 | req->rq_connect_cookie = xprt->connect_cookie; |
909 | req->rq_xtime = jiffies; | 909 | req->rq_xtime = ktime_get(); |
910 | status = xprt->ops->send_request(task); | 910 | status = xprt->ops->send_request(task); |
911 | if (status != 0) { | 911 | if (status != 0) { |
912 | task->tk_status = status; | 912 | task->tk_status = status; |
@@ -935,7 +935,7 @@ void xprt_transmit(struct rpc_task *task) | |||
935 | spin_unlock_bh(&xprt->transport_lock); | 935 | spin_unlock_bh(&xprt->transport_lock); |
936 | } | 936 | } |
937 | 937 | ||
938 | static inline void do_xprt_reserve(struct rpc_task *task) | 938 | static void xprt_alloc_slot(struct rpc_task *task) |
939 | { | 939 | { |
940 | struct rpc_xprt *xprt = task->tk_xprt; | 940 | struct rpc_xprt *xprt = task->tk_xprt; |
941 | 941 | ||
@@ -955,6 +955,16 @@ static inline void do_xprt_reserve(struct rpc_task *task) | |||
955 | rpc_sleep_on(&xprt->backlog, task, NULL); | 955 | rpc_sleep_on(&xprt->backlog, task, NULL); |
956 | } | 956 | } |
957 | 957 | ||
958 | static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) | ||
959 | { | ||
960 | memset(req, 0, sizeof(*req)); /* mark unused */ | ||
961 | |||
962 | spin_lock(&xprt->reserve_lock); | ||
963 | list_add(&req->rq_list, &xprt->free); | ||
964 | rpc_wake_up_next(&xprt->backlog); | ||
965 | spin_unlock(&xprt->reserve_lock); | ||
966 | } | ||
967 | |||
958 | /** | 968 | /** |
959 | * xprt_reserve - allocate an RPC request slot | 969 | * xprt_reserve - allocate an RPC request slot |
960 | * @task: RPC task requesting a slot allocation | 970 | * @task: RPC task requesting a slot allocation |
@@ -968,13 +978,13 @@ void xprt_reserve(struct rpc_task *task) | |||
968 | 978 | ||
969 | task->tk_status = -EIO; | 979 | task->tk_status = -EIO; |
970 | spin_lock(&xprt->reserve_lock); | 980 | spin_lock(&xprt->reserve_lock); |
971 | do_xprt_reserve(task); | 981 | xprt_alloc_slot(task); |
972 | spin_unlock(&xprt->reserve_lock); | 982 | spin_unlock(&xprt->reserve_lock); |
973 | } | 983 | } |
974 | 984 | ||
975 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) | 985 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) |
976 | { | 986 | { |
977 | return xprt->xid++; | 987 | return (__force __be32)xprt->xid++; |
978 | } | 988 | } |
979 | 989 | ||
980 | static inline void xprt_init_xid(struct rpc_xprt *xprt) | 990 | static inline void xprt_init_xid(struct rpc_xprt *xprt) |
@@ -1006,14 +1016,10 @@ void xprt_release(struct rpc_task *task) | |||
1006 | { | 1016 | { |
1007 | struct rpc_xprt *xprt; | 1017 | struct rpc_xprt *xprt; |
1008 | struct rpc_rqst *req; | 1018 | struct rpc_rqst *req; |
1009 | int is_bc_request; | ||
1010 | 1019 | ||
1011 | if (!(req = task->tk_rqstp)) | 1020 | if (!(req = task->tk_rqstp)) |
1012 | return; | 1021 | return; |
1013 | 1022 | ||
1014 | /* Preallocated backchannel request? */ | ||
1015 | is_bc_request = bc_prealloc(req); | ||
1016 | |||
1017 | xprt = req->rq_xprt; | 1023 | xprt = req->rq_xprt; |
1018 | rpc_count_iostats(task); | 1024 | rpc_count_iostats(task); |
1019 | spin_lock_bh(&xprt->transport_lock); | 1025 | spin_lock_bh(&xprt->transport_lock); |
@@ -1027,21 +1033,16 @@ void xprt_release(struct rpc_task *task) | |||
1027 | mod_timer(&xprt->timer, | 1033 | mod_timer(&xprt->timer, |
1028 | xprt->last_used + xprt->idle_timeout); | 1034 | xprt->last_used + xprt->idle_timeout); |
1029 | spin_unlock_bh(&xprt->transport_lock); | 1035 | spin_unlock_bh(&xprt->transport_lock); |
1030 | if (!bc_prealloc(req)) | 1036 | if (req->rq_buffer) |
1031 | xprt->ops->buf_free(req->rq_buffer); | 1037 | xprt->ops->buf_free(req->rq_buffer); |
1032 | task->tk_rqstp = NULL; | 1038 | task->tk_rqstp = NULL; |
1033 | if (req->rq_release_snd_buf) | 1039 | if (req->rq_release_snd_buf) |
1034 | req->rq_release_snd_buf(req); | 1040 | req->rq_release_snd_buf(req); |
1035 | 1041 | ||
1036 | dprintk("RPC: %5u release request %p\n", task->tk_pid, req); | 1042 | dprintk("RPC: %5u release request %p\n", task->tk_pid, req); |
1037 | if (likely(!is_bc_request)) { | 1043 | if (likely(!bc_prealloc(req))) |
1038 | memset(req, 0, sizeof(*req)); /* mark unused */ | 1044 | xprt_free_slot(xprt, req); |
1039 | 1045 | else | |
1040 | spin_lock(&xprt->reserve_lock); | ||
1041 | list_add(&req->rq_list, &xprt->free); | ||
1042 | rpc_wake_up_next(&xprt->backlog); | ||
1043 | spin_unlock(&xprt->reserve_lock); | ||
1044 | } else | ||
1045 | xprt_free_bc_request(req); | 1046 | xprt_free_bc_request(req); |
1046 | } | 1047 | } |
1047 | 1048 | ||