aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-02-22 16:34:17 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-02-26 00:40:44 -0500
commit5d00837b90340af9106dcd93af75fd664c8eb87f (patch)
treef537dc84421cf150d66b630e56ea8107078c07a8 /net/sunrpc/xprt.c
parentfda1393938035559b417dd5b26b9cc293a7aee00 (diff)
SUNRPC: Run rpc timeout functions as callbacks instead of in softirqs
An audit of the current RPC timeout functions shows that they don't really ever need to run in the softirq context. As long as the softirq is able to signal that the wakeup is due to a timeout (which it can do by setting task->tk_status to -ETIMEDOUT) then the callback functions can just run as standard task->tk_callback functions (in the rpciod/process context). The only possible border-line case would be xprt_timer() for the case of UDP, when the callback is used to reduce the size of the transport congestion window. In testing, however, the effect of moving that update to a callback would appear to be minor. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 6e2772217e55..9bf118c54316 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -188,9 +188,9 @@ out_sleep:
188 task->tk_timeout = 0; 188 task->tk_timeout = 0;
189 task->tk_status = -EAGAIN; 189 task->tk_status = -EAGAIN;
190 if (req && req->rq_ntrans) 190 if (req && req->rq_ntrans)
191 rpc_sleep_on(&xprt->resend, task, NULL, NULL); 191 rpc_sleep_on(&xprt->resend, task, NULL);
192 else 192 else
193 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 193 rpc_sleep_on(&xprt->sending, task, NULL);
194 return 0; 194 return 0;
195} 195}
196EXPORT_SYMBOL_GPL(xprt_reserve_xprt); 196EXPORT_SYMBOL_GPL(xprt_reserve_xprt);
@@ -238,9 +238,9 @@ out_sleep:
238 task->tk_timeout = 0; 238 task->tk_timeout = 0;
239 task->tk_status = -EAGAIN; 239 task->tk_status = -EAGAIN;
240 if (req && req->rq_ntrans) 240 if (req && req->rq_ntrans)
241 rpc_sleep_on(&xprt->resend, task, NULL, NULL); 241 rpc_sleep_on(&xprt->resend, task, NULL);
242 else 242 else
243 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 243 rpc_sleep_on(&xprt->sending, task, NULL);
244 return 0; 244 return 0;
245} 245}
246EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong); 246EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);
@@ -453,7 +453,7 @@ void xprt_wait_for_buffer_space(struct rpc_task *task)
453 struct rpc_xprt *xprt = req->rq_xprt; 453 struct rpc_xprt *xprt = req->rq_xprt;
454 454
455 task->tk_timeout = req->rq_timeout; 455 task->tk_timeout = req->rq_timeout;
456 rpc_sleep_on(&xprt->pending, task, NULL, NULL); 456 rpc_sleep_on(&xprt->pending, task, NULL);
457} 457}
458EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space); 458EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
459 459
@@ -652,7 +652,7 @@ void xprt_connect(struct rpc_task *task)
652 task->tk_rqstp->rq_bytes_sent = 0; 652 task->tk_rqstp->rq_bytes_sent = 0;
653 653
654 task->tk_timeout = xprt->connect_timeout; 654 task->tk_timeout = xprt->connect_timeout;
655 rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); 655 rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
656 xprt->stat.connect_start = jiffies; 656 xprt->stat.connect_start = jiffies;
657 xprt->ops->connect(task); 657 xprt->ops->connect(task);
658 } 658 }
@@ -769,15 +769,17 @@ static void xprt_timer(struct rpc_task *task)
769 struct rpc_rqst *req = task->tk_rqstp; 769 struct rpc_rqst *req = task->tk_rqstp;
770 struct rpc_xprt *xprt = req->rq_xprt; 770 struct rpc_xprt *xprt = req->rq_xprt;
771 771
772 if (task->tk_status != -ETIMEDOUT)
773 return;
772 dprintk("RPC: %5u xprt_timer\n", task->tk_pid); 774 dprintk("RPC: %5u xprt_timer\n", task->tk_pid);
773 775
774 spin_lock(&xprt->transport_lock); 776 spin_lock_bh(&xprt->transport_lock);
775 if (!req->rq_received) { 777 if (!req->rq_received) {
776 if (xprt->ops->timer) 778 if (xprt->ops->timer)
777 xprt->ops->timer(task); 779 xprt->ops->timer(task);
778 task->tk_status = -ETIMEDOUT; 780 } else
779 } 781 task->tk_status = 0;
780 spin_unlock(&xprt->transport_lock); 782 spin_unlock_bh(&xprt->transport_lock);
781} 783}
782 784
783/** 785/**
@@ -862,7 +864,7 @@ void xprt_transmit(struct rpc_task *task)
862 if (!xprt_connected(xprt)) 864 if (!xprt_connected(xprt))
863 task->tk_status = -ENOTCONN; 865 task->tk_status = -ENOTCONN;
864 else if (!req->rq_received) 866 else if (!req->rq_received)
865 rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); 867 rpc_sleep_on(&xprt->pending, task, xprt_timer);
866 spin_unlock_bh(&xprt->transport_lock); 868 spin_unlock_bh(&xprt->transport_lock);
867 return; 869 return;
868 } 870 }
@@ -873,7 +875,7 @@ void xprt_transmit(struct rpc_task *task)
873 */ 875 */
874 task->tk_status = status; 876 task->tk_status = status;
875 if (status == -ECONNREFUSED) 877 if (status == -ECONNREFUSED)
876 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 878 rpc_sleep_on(&xprt->sending, task, NULL);
877} 879}
878 880
879static inline void do_xprt_reserve(struct rpc_task *task) 881static inline void do_xprt_reserve(struct rpc_task *task)
@@ -893,7 +895,7 @@ static inline void do_xprt_reserve(struct rpc_task *task)
893 dprintk("RPC: waiting for request slot\n"); 895 dprintk("RPC: waiting for request slot\n");
894 task->tk_status = -EAGAIN; 896 task->tk_status = -EAGAIN;
895 task->tk_timeout = 0; 897 task->tk_timeout = 0;
896 rpc_sleep_on(&xprt->backlog, task, NULL, NULL); 898 rpc_sleep_on(&xprt->backlog, task, NULL);
897} 899}
898 900
899/** 901/**