diff options
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r-- | net/sunrpc/xprt.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 8313960cac52..ea244b29138b 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -680,6 +680,20 @@ out: | |||
680 | spin_unlock_bh(&xprt->transport_lock); | 680 | spin_unlock_bh(&xprt->transport_lock); |
681 | } | 681 | } |
682 | 682 | ||
683 | static bool | ||
684 | xprt_has_timer(const struct rpc_xprt *xprt) | ||
685 | { | ||
686 | return xprt->idle_timeout != 0; | ||
687 | } | ||
688 | |||
689 | static void | ||
690 | xprt_schedule_autodisconnect(struct rpc_xprt *xprt) | ||
691 | __must_hold(&xprt->transport_lock) | ||
692 | { | ||
693 | if (list_empty(&xprt->recv) && xprt_has_timer(xprt)) | ||
694 | mod_timer(&xprt->timer, xprt->last_used + xprt->idle_timeout); | ||
695 | } | ||
696 | |||
683 | static void | 697 | static void |
684 | xprt_init_autodisconnect(unsigned long data) | 698 | xprt_init_autodisconnect(unsigned long data) |
685 | { | 699 | { |
@@ -688,6 +702,8 @@ xprt_init_autodisconnect(unsigned long data) | |||
688 | spin_lock(&xprt->transport_lock); | 702 | spin_lock(&xprt->transport_lock); |
689 | if (!list_empty(&xprt->recv)) | 703 | if (!list_empty(&xprt->recv)) |
690 | goto out_abort; | 704 | goto out_abort; |
705 | /* Reset xprt->last_used to avoid connect/autodisconnect cycling */ | ||
706 | xprt->last_used = jiffies; | ||
691 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) | 707 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) |
692 | goto out_abort; | 708 | goto out_abort; |
693 | spin_unlock(&xprt->transport_lock); | 709 | spin_unlock(&xprt->transport_lock); |
@@ -725,6 +741,7 @@ void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie) | |||
725 | goto out; | 741 | goto out; |
726 | xprt->snd_task =NULL; | 742 | xprt->snd_task =NULL; |
727 | xprt->ops->release_xprt(xprt, NULL); | 743 | xprt->ops->release_xprt(xprt, NULL); |
744 | xprt_schedule_autodisconnect(xprt); | ||
728 | out: | 745 | out: |
729 | spin_unlock_bh(&xprt->transport_lock); | 746 | spin_unlock_bh(&xprt->transport_lock); |
730 | wake_up_bit(&xprt->state, XPRT_LOCKED); | 747 | wake_up_bit(&xprt->state, XPRT_LOCKED); |
@@ -888,11 +905,6 @@ static void xprt_timer(struct rpc_task *task) | |||
888 | spin_unlock_bh(&xprt->transport_lock); | 905 | spin_unlock_bh(&xprt->transport_lock); |
889 | } | 906 | } |
890 | 907 | ||
891 | static inline int xprt_has_timer(struct rpc_xprt *xprt) | ||
892 | { | ||
893 | return xprt->idle_timeout != 0; | ||
894 | } | ||
895 | |||
896 | /** | 908 | /** |
897 | * xprt_prepare_transmit - reserve the transport before sending a request | 909 | * xprt_prepare_transmit - reserve the transport before sending a request |
898 | * @task: RPC task about to send a request | 910 | * @task: RPC task about to send a request |
@@ -1280,9 +1292,7 @@ void xprt_release(struct rpc_task *task) | |||
1280 | if (!list_empty(&req->rq_list)) | 1292 | if (!list_empty(&req->rq_list)) |
1281 | list_del(&req->rq_list); | 1293 | list_del(&req->rq_list); |
1282 | xprt->last_used = jiffies; | 1294 | xprt->last_used = jiffies; |
1283 | if (list_empty(&xprt->recv) && xprt_has_timer(xprt)) | 1295 | xprt_schedule_autodisconnect(xprt); |
1284 | mod_timer(&xprt->timer, | ||
1285 | xprt->last_used + xprt->idle_timeout); | ||
1286 | spin_unlock_bh(&xprt->transport_lock); | 1296 | spin_unlock_bh(&xprt->transport_lock); |
1287 | if (req->rq_buffer) | 1297 | if (req->rq_buffer) |
1288 | xprt->ops->buf_free(req->rq_buffer); | 1298 | xprt->ops->buf_free(req->rq_buffer); |