]> git.neil.brown.name Git - history.git/commitdiff
UDP round trip timer fix. Modify Karn's algorithm so that
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Tue, 7 Oct 2003 11:30:00 +0000 (07:30 -0400)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Tue, 7 Oct 2003 11:30:00 +0000 (07:30 -0400)
we inherit timeouts from previous requests.
This means that we lengthen the window of time during which
we accept updates to the RTO estimate if we see an update.

Scheme proposed by Brian Mancuso, but it is standard for TCP
congestion control implementations.

include/linux/sunrpc/timer.h
net/sunrpc/xprt.c

index f2f2ffc4f2cd93d9d2b40b0c3392fe5d86fc9375..1d0d3a0d64ec35e9681a3093890a54a105f3331a 100644 (file)
@@ -15,6 +15,7 @@ struct rpc_rtt {
        unsigned long timeo;    /* default timeout value */
        unsigned long srtt[5];  /* smoothed round trip time << 3 */
        unsigned long sdrtt[5]; /* smoothed medium deviation of RTT */
+       int ntimeouts[5];       /* Number of timeouts for the last request */
 };
 
 
@@ -22,4 +23,18 @@ extern void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo);
 extern void rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m);
 extern unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned timer);
 
+static inline void rpc_set_timeo(struct rpc_rtt *rt, int timer, int ntimeo)
+{
+       if (!timer)
+               return;
+       rt->ntimeouts[timer-1] = ntimeo;
+}
+
+static inline int rpc_ntimeo(struct rpc_rtt *rt, int timer)
+{
+       if (!timer)
+               return 0;
+       return rt->ntimeouts[timer-1];
+}
+
 #endif /* _LINUX_SUNRPC_TIMER_H */
index 61f4bfbecdcafb6afd0ca20e2efa8dc0d9fa2d4f..ef616fe9c56129499189d5e016a3ccd1d40b9ce0 100644 (file)
@@ -579,14 +579,14 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
 
        /* Adjust congestion window */
        if (!xprt->nocong) {
+               unsigned timer = task->tk_msg.rpc_proc->p_timer;
                xprt_adjust_cwnd(xprt, copied);
                __xprt_put_cong(xprt, req);
-               if (req->rq_ntrans == 1) {
-                       unsigned timer =
-                               task->tk_msg.rpc_proc->p_timer;
-                       if (timer)
+               if (timer) {
+                       if (req->rq_ntrans == 1)
                                rpc_update_rtt(&clnt->cl_rtt, timer,
                                                (long)jiffies - req->rq_xtime);
+                       rpc_set_timeo(&clnt->cl_rtt, timer, req->rq_ntrans - 1);
                }
        }
 
@@ -1223,8 +1223,9 @@ xprt_transmit(struct rpc_task *task)
        /* Set the task's receive timeout value */
        spin_lock_bh(&xprt->sock_lock);
        if (!xprt->nocong) {
-               task->tk_timeout = rpc_calc_rto(&clnt->cl_rtt,
-                               task->tk_msg.rpc_proc->p_timer);
+               int timer = task->tk_msg.rpc_proc->p_timer;
+               task->tk_timeout = rpc_calc_rto(&clnt->cl_rtt, timer);
+               task->tk_timeout <<= rpc_ntimeo(&clnt->cl_rtt, timer);
                task->tk_timeout <<= clnt->cl_timeout.to_retries
                        - req->rq_timeout.to_retries;
                if (task->tk_timeout > req->rq_timeout.to_maxval)