#include <linux/version.h>
|
#include <linux/version.h>
|
#include <linux/types.h>
|
#include <linux/types.h>
|
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
|
|
#include <linux/sunrpc/clnt.h>
|
#include <linux/sunrpc/clnt.h>
|
#include <linux/sunrpc/xprt.h>
|
#include <linux/sunrpc/xprt.h>
|
#include <linux/sunrpc/timer.h>
|
#include <linux/sunrpc/timer.h>
|
|
|
#define RPC_RTO_MAX (60*HZ)
|
#define RPC_RTO_MAX (60*HZ)
|
#define RPC_RTO_INIT (HZ/5)
|
#define RPC_RTO_INIT (HZ/5)
|
#define RPC_RTO_MIN (HZ/10)
|
#define RPC_RTO_MIN (HZ/10)
|
|
|
void
|
void
|
rpc_init_rtt(struct rpc_rtt *rt, long timeo)
|
rpc_init_rtt(struct rpc_rtt *rt, long timeo)
|
{
|
{
|
long t = (timeo - RPC_RTO_INIT) << 3;
|
long t = (timeo - RPC_RTO_INIT) << 3;
|
int i;
|
int i;
|
rt->timeo = timeo;
|
rt->timeo = timeo;
|
if (t < 0)
|
if (t < 0)
|
t = 0;
|
t = 0;
|
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
rt->srtt[i] = t;
|
rt->srtt[i] = t;
|
rt->sdrtt[i] = RPC_RTO_INIT;
|
rt->sdrtt[i] = RPC_RTO_INIT;
|
}
|
}
|
memset(rt->ntimeouts, 0, sizeof(rt->ntimeouts));
|
memset(rt->ntimeouts, 0, sizeof(rt->ntimeouts));
|
}
|
}
|
|
|
void
|
void
|
rpc_update_rtt(struct rpc_rtt *rt, int timer, long m)
|
rpc_update_rtt(struct rpc_rtt *rt, int timer, long m)
|
{
|
{
|
long *srtt, *sdrtt;
|
long *srtt, *sdrtt;
|
|
|
if (timer-- == 0)
|
if (timer-- == 0)
|
return;
|
return;
|
|
|
if (m == 0)
|
if (m == 0)
|
m = 1;
|
m = 1;
|
srtt = &rt->srtt[timer];
|
srtt = &rt->srtt[timer];
|
m -= *srtt >> 3;
|
m -= *srtt >> 3;
|
*srtt += m;
|
*srtt += m;
|
if (m < 0)
|
if (m < 0)
|
m = -m;
|
m = -m;
|
sdrtt = &rt->sdrtt[timer];
|
sdrtt = &rt->sdrtt[timer];
|
m -= *sdrtt >> 2;
|
m -= *sdrtt >> 2;
|
*sdrtt += m;
|
*sdrtt += m;
|
/* Set lower bound on the variance */
|
/* Set lower bound on the variance */
|
if (*sdrtt < RPC_RTO_MIN)
|
if (*sdrtt < RPC_RTO_MIN)
|
*sdrtt = RPC_RTO_MIN;
|
*sdrtt = RPC_RTO_MIN;
|
}
|
}
|
|
|
/*
|
/*
|
* Estimate rto for an nfs rpc sent via. an unreliable datagram.
|
* Estimate rto for an nfs rpc sent via. an unreliable datagram.
|
* Use the mean and mean deviation of rtt for the appropriate type of rpc
|
* Use the mean and mean deviation of rtt for the appropriate type of rpc
|
* for the frequent rpcs and a default for the others.
|
* for the frequent rpcs and a default for the others.
|
* The justification for doing "other" this way is that these rpcs
|
* The justification for doing "other" this way is that these rpcs
|
* happen so infrequently that timer est. would probably be stale.
|
* happen so infrequently that timer est. would probably be stale.
|
* Also, since many of these rpcs are
|
* Also, since many of these rpcs are
|
* non-idempotent, a conservative timeout is desired.
|
* non-idempotent, a conservative timeout is desired.
|
* getattr, lookup,
|
* getattr, lookup,
|
* read, write, commit - A+4D
|
* read, write, commit - A+4D
|
* other - timeo
|
* other - timeo
|
*/
|
*/
|
|
|
long
|
long
|
rpc_calc_rto(struct rpc_rtt *rt, int timer)
|
rpc_calc_rto(struct rpc_rtt *rt, int timer)
|
{
|
{
|
long res;
|
long res;
|
if (timer-- == 0)
|
if (timer-- == 0)
|
return rt->timeo;
|
return rt->timeo;
|
res = (rt->srtt[timer] >> 3) + rt->sdrtt[timer];
|
res = (rt->srtt[timer] >> 3) + rt->sdrtt[timer];
|
if (res > RPC_RTO_MAX)
|
if (res > RPC_RTO_MAX)
|
res = RPC_RTO_MAX;
|
res = RPC_RTO_MAX;
|
return res;
|
return res;
|
}
|
}
|
|
|