Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/sunrpc/timer.c
15109 views
1
/*
2
* linux/net/sunrpc/timer.c
3
*
4
* Estimate RPC request round trip time.
5
*
6
* Based on packet round-trip and variance estimator algorithms described
7
* in appendix A of "Congestion Avoidance and Control" by Van Jacobson
8
* and Michael J. Karels (ACM Computer Communication Review; Proceedings
9
* of the Sigcomm '88 Symposium in Stanford, CA, August, 1988).
10
*
11
* This RTT estimator is used only for RPC over datagram protocols.
12
*
13
* Copyright (C) 2002 Trond Myklebust <[email protected]>
14
*/
15
16
#include <asm/param.h>
17
18
#include <linux/types.h>
19
#include <linux/unistd.h>
20
#include <linux/module.h>
21
22
#include <linux/sunrpc/clnt.h>
23
24
#define RPC_RTO_MAX (60*HZ)
25
#define RPC_RTO_INIT (HZ/5)
26
#define RPC_RTO_MIN (HZ/10)
27
28
/**
29
* rpc_init_rtt - Initialize an RPC RTT estimator context
30
* @rt: context to initialize
31
* @timeo: initial timeout value, in jiffies
32
*
33
*/
34
void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
35
{
36
unsigned long init = 0;
37
unsigned i;
38
39
rt->timeo = timeo;
40
41
if (timeo > RPC_RTO_INIT)
42
init = (timeo - RPC_RTO_INIT) << 3;
43
for (i = 0; i < 5; i++) {
44
rt->srtt[i] = init;
45
rt->sdrtt[i] = RPC_RTO_INIT;
46
rt->ntimeouts[i] = 0;
47
}
48
}
49
EXPORT_SYMBOL_GPL(rpc_init_rtt);
50
51
/**
52
* rpc_update_rtt - Update an RPC RTT estimator context
53
* @rt: context to update
54
* @timer: timer array index (request type)
55
* @m: recent actual RTT, in jiffies
56
*
57
* NB: When computing the smoothed RTT and standard deviation,
58
* be careful not to produce negative intermediate results.
59
*/
60
void rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m)
61
{
62
long *srtt, *sdrtt;
63
64
if (timer-- == 0)
65
return;
66
67
/* jiffies wrapped; ignore this one */
68
if (m < 0)
69
return;
70
71
if (m == 0)
72
m = 1L;
73
74
srtt = (long *)&rt->srtt[timer];
75
m -= *srtt >> 3;
76
*srtt += m;
77
78
if (m < 0)
79
m = -m;
80
81
sdrtt = (long *)&rt->sdrtt[timer];
82
m -= *sdrtt >> 2;
83
*sdrtt += m;
84
85
/* Set lower bound on the variance */
86
if (*sdrtt < RPC_RTO_MIN)
87
*sdrtt = RPC_RTO_MIN;
88
}
89
EXPORT_SYMBOL_GPL(rpc_update_rtt);
90
91
/**
92
* rpc_calc_rto - Provide an estimated timeout value
93
* @rt: context to use for calculation
94
* @timer: timer array index (request type)
95
*
96
* Estimate RTO for an NFS RPC sent via an unreliable datagram. Use
97
* the mean and mean deviation of RTT for the appropriate type of RPC
98
* for frequently issued RPCs, and a fixed default for the others.
99
*
100
* The justification for doing "other" this way is that these RPCs
101
* happen so infrequently that timer estimation would probably be
102
* stale. Also, since many of these RPCs are non-idempotent, a
103
* conservative timeout is desired.
104
*
105
* getattr, lookup,
106
* read, write, commit - A+4D
107
* other - timeo
108
*/
109
unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned timer)
110
{
111
unsigned long res;
112
113
if (timer-- == 0)
114
return rt->timeo;
115
116
res = ((rt->srtt[timer] + 7) >> 3) + rt->sdrtt[timer];
117
if (res > RPC_RTO_MAX)
118
res = RPC_RTO_MAX;
119
120
return res;
121
}
122
EXPORT_SYMBOL_GPL(rpc_calc_rto);
123
124