Commit fa7b279e authored by Trond Myklebust's avatar Trond Myklebust

[PATCH] RPC over UDP congestion control updates [2/8]

Implement a count of the number of timeouts that have occured since
we last recorded a successful reply from the server.

For the moment this information is merely used in order to improve the
estimate of whether or not the server is down. It will be used in
patch 3/8 in order to improve the timeout backoff algorithm.
parent 77d79030
...@@ -9,10 +9,13 @@ ...@@ -9,10 +9,13 @@
#ifndef _LINUX_SUNRPC_TIMER_H #ifndef _LINUX_SUNRPC_TIMER_H
#define _LINUX_SUNRPC_TIMER_H #define _LINUX_SUNRPC_TIMER_H
#include <asm/atomic.h>
struct rpc_rtt { struct rpc_rtt {
long timeo; /* default timeout value */ long timeo; /* default timeout value */
long srtt[5]; /* smoothed round trip time << 3 */ long srtt[5]; /* smoothed round trip time << 3 */
long sdrtt[5]; /* soothed medium deviation of RTT */ long sdrtt[5]; /* soothed medium deviation of RTT */
atomic_t ntimeouts; /* Global count of the number of timeouts */
}; };
...@@ -20,4 +23,19 @@ extern void rpc_init_rtt(struct rpc_rtt *rt, long timeo); ...@@ -20,4 +23,19 @@ extern void rpc_init_rtt(struct rpc_rtt *rt, long timeo);
extern void rpc_update_rtt(struct rpc_rtt *rt, int timer, long m); extern void rpc_update_rtt(struct rpc_rtt *rt, int timer, long m);
extern long rpc_calc_rto(struct rpc_rtt *rt, int timer); extern long rpc_calc_rto(struct rpc_rtt *rt, int timer);
static inline void rpc_inc_timeo(struct rpc_rtt *rt)
{
atomic_inc(&rt->ntimeouts);
}
static inline void rpc_clear_timeo(struct rpc_rtt *rt)
{
atomic_set(&rt->ntimeouts, 0);
}
static inline int rpc_ntimeo(struct rpc_rtt *rt)
{
return atomic_read(&rt->ntimeouts);
}
#endif /* _LINUX_SUNRPC_TIMER_H */ #endif /* _LINUX_SUNRPC_TIMER_H */
...@@ -671,7 +671,7 @@ call_timeout(struct rpc_task *task) ...@@ -671,7 +671,7 @@ call_timeout(struct rpc_task *task)
rpc_exit(task, -EIO); rpc_exit(task, -EIO);
return; return;
} }
if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN)) { if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN) && rpc_ntimeo(&clnt->cl_rtt) > 7) {
task->tk_flags |= RPC_CALL_MAJORSEEN; task->tk_flags |= RPC_CALL_MAJORSEEN;
if (req) if (req)
printk(KERN_NOTICE "%s: server %s not responding, still trying\n", printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
......
...@@ -22,6 +22,7 @@ rpc_init_rtt(struct rpc_rtt *rt, long timeo) ...@@ -22,6 +22,7 @@ rpc_init_rtt(struct rpc_rtt *rt, long timeo)
rt->srtt[i] = t; rt->srtt[i] = t;
rt->sdrtt[i] = RPC_RTO_INIT; rt->sdrtt[i] = RPC_RTO_INIT;
} }
atomic_set(&rt->ntimeouts, 0);
} }
void void
......
...@@ -494,6 +494,8 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied) ...@@ -494,6 +494,8 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
if (timer) if (timer)
rpc_update_rtt(&clnt->cl_rtt, timer, (long)jiffies - req->rq_xtime); rpc_update_rtt(&clnt->cl_rtt, timer, (long)jiffies - req->rq_xtime);
} }
rpc_clear_timeo(&clnt->cl_rtt);
}
#ifdef RPC_PROFILE #ifdef RPC_PROFILE
/* Profile only reads for now */ /* Profile only reads for now */
...@@ -942,6 +944,7 @@ xprt_timer(struct rpc_task *task) ...@@ -942,6 +944,7 @@ xprt_timer(struct rpc_task *task)
if (req->rq_received) if (req->rq_received)
goto out; goto out;
req->rq_nresend++; req->rq_nresend++;
rpc_inc_timeo(&task->tk_client->cl_rtt);
xprt_adjust_cwnd(xprt, -ETIMEDOUT); xprt_adjust_cwnd(xprt, -ETIMEDOUT);
dprintk("RPC: %4d xprt_timer (%s request)\n", dprintk("RPC: %4d xprt_timer (%s request)\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment