diff options
author | Chuck Lever <cel@netapp.com> | 2005-08-25 19:25:52 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-09-23 12:38:41 -0400 |
commit | 46c0ee8bc4ad3743de05e8b8b20201df44dcb6d3 (patch) | |
tree | 6b2993ff1cefb69cc3cc40c3605d088ea2af3c98 /net/sunrpc/xprt.c | |
parent | 49e9a89086b3cae784a4868ca852863e4f4ea3fe (diff) |
[PATCH] RPC: separate xprt_timer implementations
Allow transports to hook the retransmit timer interrupt. Some transports
calculate their congestion window here so that a retransmit timeout has
immediate effect on the congestion window.
Test-plan:
Use WAN simulation to cause sporadic bursty packet loss. Look for significant
regression in performance or client stability.
Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r-- | net/sunrpc/xprt.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index e92ea99dd31..ffc595592af 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -289,16 +289,19 @@ __xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req) | |||
289 | __xprt_lock_write_next_cong(xprt); | 289 | __xprt_lock_write_next_cong(xprt); |
290 | } | 290 | } |
291 | 291 | ||
292 | /* | 292 | /** |
293 | * Adjust RPC congestion window | 293 | * xprt_adjust_cwnd - adjust transport congestion window |
294 | * @task: recently completed RPC request used to adjust window | ||
295 | * @result: result code of completed RPC request | ||
296 | * | ||
294 | * We use a time-smoothed congestion estimator to avoid heavy oscillation. | 297 | * We use a time-smoothed congestion estimator to avoid heavy oscillation. |
295 | */ | 298 | */ |
296 | static void | 299 | void xprt_adjust_cwnd(struct rpc_task *task, int result) |
297 | xprt_adjust_cwnd(struct rpc_xprt *xprt, int result) | ||
298 | { | 300 | { |
299 | unsigned long cwnd; | 301 | struct rpc_rqst *req = task->tk_rqstp; |
302 | struct rpc_xprt *xprt = task->tk_xprt; | ||
303 | unsigned long cwnd = xprt->cwnd; | ||
300 | 304 | ||
301 | cwnd = xprt->cwnd; | ||
302 | if (result >= 0 && cwnd <= xprt->cong) { | 305 | if (result >= 0 && cwnd <= xprt->cong) { |
303 | /* The (cwnd >> 1) term makes sure | 306 | /* The (cwnd >> 1) term makes sure |
304 | * the result gets rounded properly. */ | 307 | * the result gets rounded properly. */ |
@@ -314,6 +317,7 @@ xprt_adjust_cwnd(struct rpc_xprt *xprt, int result) | |||
314 | dprintk("RPC: cong %ld, cwnd was %ld, now %ld\n", | 317 | dprintk("RPC: cong %ld, cwnd was %ld, now %ld\n", |
315 | xprt->cong, xprt->cwnd, cwnd); | 318 | xprt->cong, xprt->cwnd, cwnd); |
316 | xprt->cwnd = cwnd; | 319 | xprt->cwnd = cwnd; |
320 | __xprt_put_cong(xprt, req); | ||
317 | } | 321 | } |
318 | 322 | ||
319 | /** | 323 | /** |
@@ -602,8 +606,7 @@ void xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied) | |||
602 | /* Adjust congestion window */ | 606 | /* Adjust congestion window */ |
603 | if (!xprt->nocong) { | 607 | if (!xprt->nocong) { |
604 | unsigned timer = task->tk_msg.rpc_proc->p_timer; | 608 | unsigned timer = task->tk_msg.rpc_proc->p_timer; |
605 | xprt_adjust_cwnd(xprt, copied); | 609 | xprt_adjust_cwnd(task, copied); |
606 | __xprt_put_cong(xprt, req); | ||
607 | if (timer) { | 610 | if (timer) { |
608 | if (req->rq_ntrans == 1) | 611 | if (req->rq_ntrans == 1) |
609 | rpc_update_rtt(clnt->cl_rtt, timer, | 612 | rpc_update_rtt(clnt->cl_rtt, timer, |
@@ -640,27 +643,19 @@ void xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied) | |||
640 | return; | 643 | return; |
641 | } | 644 | } |
642 | 645 | ||
643 | /* | 646 | static void xprt_timer(struct rpc_task *task) |
644 | * RPC receive timeout handler. | ||
645 | */ | ||
646 | static void | ||
647 | xprt_timer(struct rpc_task *task) | ||
648 | { | 647 | { |
649 | struct rpc_rqst *req = task->tk_rqstp; | 648 | struct rpc_rqst *req = task->tk_rqstp; |
650 | struct rpc_xprt *xprt = req->rq_xprt; | 649 | struct rpc_xprt *xprt = req->rq_xprt; |
651 | 650 | ||
652 | spin_lock(&xprt->transport_lock); | 651 | dprintk("RPC: %4d xprt_timer\n", task->tk_pid); |
653 | if (req->rq_received) | ||
654 | goto out; | ||
655 | |||
656 | xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT); | ||
657 | __xprt_put_cong(xprt, req); | ||
658 | 652 | ||
659 | dprintk("RPC: %4d xprt_timer (%s request)\n", | 653 | spin_lock(&xprt->transport_lock); |
660 | task->tk_pid, req ? "pending" : "backlogged"); | 654 | if (!req->rq_received) { |
661 | 655 | if (xprt->ops->timer) | |
662 | task->tk_status = -ETIMEDOUT; | 656 | xprt->ops->timer(task); |
663 | out: | 657 | task->tk_status = -ETIMEDOUT; |
658 | } | ||
664 | task->tk_timeout = 0; | 659 | task->tk_timeout = 0; |
665 | rpc_wake_up_task(task); | 660 | rpc_wake_up_task(task); |
666 | spin_unlock(&xprt->transport_lock); | 661 | spin_unlock(&xprt->transport_lock); |