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