This source file includes following definitions.
- rxrpc_rto_min_us
- __rxrpc_set_rto
- rxrpc_bound_rto
- rxrpc_rtt_estimator
- rxrpc_set_rto
- rxrpc_ack_update_rtt
- rxrpc_peer_add_rtt
- rxrpc_get_rto_backoff
- rxrpc_peer_init_rtt
1
2
3
4
5
6
7
8
9
10
11 #include <linux/net.h>
12 #include "ar-internal.h"
13
14 #define RXRPC_RTO_MAX ((unsigned)(120 * HZ))
15 #define RXRPC_TIMEOUT_INIT ((unsigned)(1*HZ))
16 #define rxrpc_jiffies32 ((u32)jiffies)
17 #define rxrpc_min_rtt_wlen 300
18
19 static u32 rxrpc_rto_min_us(struct rxrpc_peer *peer)
20 {
21 return 200;
22 }
23
24 static u32 __rxrpc_set_rto(const struct rxrpc_peer *peer)
25 {
26 return _usecs_to_jiffies((peer->srtt_us >> 3) + peer->rttvar_us);
27 }
28
29 static u32 rxrpc_bound_rto(u32 rto)
30 {
31 return min(rto, RXRPC_RTO_MAX);
32 }
33
34
35
36
37
38
39
40
41
42
43
44 static void rxrpc_rtt_estimator(struct rxrpc_peer *peer, long sample_rtt_us)
45 {
46 long m = sample_rtt_us;
47 u32 srtt = peer->srtt_us;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 if (srtt != 0) {
66 m -= (srtt >> 3);
67 srtt += m;
68 if (m < 0) {
69 m = -m;
70 m -= (peer->mdev_us >> 2);
71
72
73
74
75
76
77
78
79 if (m > 0)
80 m >>= 3;
81 } else {
82 m -= (peer->mdev_us >> 2);
83 }
84
85 peer->mdev_us += m;
86 if (peer->mdev_us > peer->mdev_max_us) {
87 peer->mdev_max_us = peer->mdev_us;
88 if (peer->mdev_max_us > peer->rttvar_us)
89 peer->rttvar_us = peer->mdev_max_us;
90 }
91 } else {
92
93 srtt = m << 3;
94 peer->mdev_us = m << 1;
95 peer->rttvar_us = max(peer->mdev_us, rxrpc_rto_min_us(peer));
96 peer->mdev_max_us = peer->rttvar_us;
97 }
98
99 peer->srtt_us = max(1U, srtt);
100 }
101
102
103
104
105
106 static void rxrpc_set_rto(struct rxrpc_peer *peer)
107 {
108 u32 rto;
109
110
111
112
113
114
115
116
117 rto = __rxrpc_set_rto(peer);
118
119
120
121
122
123
124
125
126
127
128 peer->rto_j = rxrpc_bound_rto(rto);
129 }
130
131 static void rxrpc_ack_update_rtt(struct rxrpc_peer *peer, long rtt_us)
132 {
133 if (rtt_us < 0)
134 return;
135
136
137 rxrpc_rtt_estimator(peer, rtt_us);
138 rxrpc_set_rto(peer);
139
140
141 peer->backoff = 0;
142 }
143
144
145
146
147
148 void rxrpc_peer_add_rtt(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why,
149 rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial,
150 ktime_t send_time, ktime_t resp_time)
151 {
152 struct rxrpc_peer *peer = call->peer;
153 s64 rtt_us;
154
155 rtt_us = ktime_to_us(ktime_sub(resp_time, send_time));
156 if (rtt_us < 0)
157 return;
158
159 spin_lock(&peer->rtt_input_lock);
160 rxrpc_ack_update_rtt(peer, rtt_us);
161 if (peer->rtt_count < 3)
162 peer->rtt_count++;
163 spin_unlock(&peer->rtt_input_lock);
164
165 trace_rxrpc_rtt_rx(call, why, send_serial, resp_serial,
166 peer->srtt_us >> 3, peer->rto_j);
167 }
168
169
170
171
172
173 unsigned long rxrpc_get_rto_backoff(struct rxrpc_peer *peer, bool retrans)
174 {
175 u64 timo_j;
176 u8 backoff = READ_ONCE(peer->backoff);
177
178 timo_j = peer->rto_j;
179 timo_j <<= backoff;
180 if (retrans && timo_j * 2 <= RXRPC_RTO_MAX)
181 WRITE_ONCE(peer->backoff, backoff + 1);
182
183 if (timo_j < 1)
184 timo_j = 1;
185
186 return timo_j;
187 }
188
189 void rxrpc_peer_init_rtt(struct rxrpc_peer *peer)
190 {
191 peer->rto_j = RXRPC_TIMEOUT_INIT;
192 peer->mdev_us = jiffies_to_usecs(RXRPC_TIMEOUT_INIT);
193 peer->backoff = 0;
194
195 }