aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_compound.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_compound.c')
-rw-r--r--net/ipv4/tcp_compound.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/net/ipv4/tcp_compound.c b/net/ipv4/tcp_compound.c
index 8c1ebfb7659e..ec68cb8081c1 100644
--- a/net/ipv4/tcp_compound.c
+++ b/net/ipv4/tcp_compound.c
@@ -52,8 +52,6 @@
52 52
53#define TCP_COMPOUND_ALPHA 3U 53#define TCP_COMPOUND_ALPHA 3U
54#define TCP_COMPOUND_BETA 1U 54#define TCP_COMPOUND_BETA 1U
55#define TCP_COMPOUND_KAPPA_POW 3
56#define TCP_COMPOUND_KAPPA_NSQRT 2
57#define TCP_COMPOUND_GAMMA 30 55#define TCP_COMPOUND_GAMMA 30
58#define TCP_COMPOUND_ZETA 1 56#define TCP_COMPOUND_ZETA 1
59 57
@@ -156,6 +154,58 @@ static void tcp_compound_state(struct sock *sk, u8 ca_state)
156 vegas_disable(sk); 154 vegas_disable(sk);
157} 155}
158 156
157
158/* 64bit divisor, dividend and result. dynamic precision */
159static inline u64 div64_64(u64 dividend, u64 divisor)
160{
161 u32 d = divisor;
162
163 if (divisor > 0xffffffffULL) {
164 unsigned int shift = fls(divisor >> 32);
165
166 d = divisor >> shift;
167 dividend >>= shift;
168 }
169
170 /* avoid 64 bit division if possible */
171 if (dividend >> 32)
172 do_div(dividend, d);
173 else
174 dividend = (u32) dividend / d;
175
176 return dividend;
177}
178
179/* calculate the quartic root of "a" using Newton-Raphson */
180static u32 qroot(u64 a)
181{
182 u32 x, x1;
183
184 /* Initial estimate is based on:
185 * qrt(x) = exp(log(x) / 4)
186 */
187 x = 1u << (fls64(a) >> 2);
188
189 /*
190 * Iteration based on:
191 * 3
192 * x = ( 3 * x + a / x ) / 4
193 * k+1 k k
194 */
195 do {
196 u64 x3 = x;
197
198 x1 = x;
199 x3 *= x;
200 x3 *= x;
201
202 x = (3 * x + (u32) div64_64(a, x3)) / 4;
203 } while (abs(x1 - x) > 1);
204
205 return x;
206}
207
208
159/* 209/*
160 * If the connection is idle and we are restarting, 210 * If the connection is idle and we are restarting,
161 * then we don't want to do any Vegas calculations 211 * then we don't want to do any Vegas calculations
@@ -304,29 +354,21 @@ static void tcp_compound_cong_avoid(struct sock *sk, u32 ack,
304 dwnd = vegas->dwnd; 354 dwnd = vegas->dwnd;
305 355
306 if (diff < (TCP_COMPOUND_GAMMA << V_PARAM_SHIFT)) { 356 if (diff < (TCP_COMPOUND_GAMMA << V_PARAM_SHIFT)) {
307 u32 i, j, x, x2;
308 u64 v; 357 u64 v;
309 358 u32 x;
310 v = 1; 359
311 360 /*
312 for (i = 0; i < TCP_COMPOUND_KAPPA_POW; i++) 361 * The TCP Compound paper describes the choice
313 v *= old_wnd; 362 * of "k" determines the agressiveness,
314 363 * ie. slope of the response function.
315 for (i = 0; i < TCP_COMPOUND_KAPPA_NSQRT; i++) { 364 *
316 x = 1; 365 * For same value as HSTCP would be 0.8
317 for (j = 0; j < 200; j++) { 366 * but for computaional reasons, both the
318 x2 = (x + v / x) / 2; 367 * original authors and this implementation
319 368 * use 0.75.
320 if (x2 == x || !x2) 369 */
321 break; 370 v = old_wnd;
322 371 x = qroot(v * v * v) >> TCP_COMPOUND_ALPHA;
323 x = x2;
324 }
325 v = x;
326 }
327
328 x = (u32) v >> TCP_COMPOUND_ALPHA;
329
330 if (x > 1) 372 if (x > 1)
331 dwnd = x - 1; 373 dwnd = x - 1;
332 else 374 else