aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c26
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
683static bool
684xprt_has_timer(const struct rpc_xprt *xprt)
685{
686 return xprt->idle_timeout != 0;
687}
688
689static void
690xprt_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
683static void 697static void
684xprt_init_autodisconnect(unsigned long data) 698xprt_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);
728out: 745out:
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
891static 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);