mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
[TCP]: TCP Compound quad root function
The original code did a 64 bit divide directly, which won't work on 32 bit platforms. Rather than doing a 64 bit square root twice, just implement a 4th root function in one pass using Newton's method. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f890f92104
commit
a4ed258495
@ -52,8 +52,6 @@
|
||||
|
||||
#define TCP_COMPOUND_ALPHA 3U
|
||||
#define TCP_COMPOUND_BETA 1U
|
||||
#define TCP_COMPOUND_KAPPA_POW 3
|
||||
#define TCP_COMPOUND_KAPPA_NSQRT 2
|
||||
#define TCP_COMPOUND_GAMMA 30
|
||||
#define TCP_COMPOUND_ZETA 1
|
||||
|
||||
@ -156,6 +154,58 @@ static void tcp_compound_state(struct sock *sk, u8 ca_state)
|
||||
vegas_disable(sk);
|
||||
}
|
||||
|
||||
|
||||
/* 64bit divisor, dividend and result. dynamic precision */
|
||||
static inline u64 div64_64(u64 dividend, u64 divisor)
|
||||
{
|
||||
u32 d = divisor;
|
||||
|
||||
if (divisor > 0xffffffffULL) {
|
||||
unsigned int shift = fls(divisor >> 32);
|
||||
|
||||
d = divisor >> shift;
|
||||
dividend >>= shift;
|
||||
}
|
||||
|
||||
/* avoid 64 bit division if possible */
|
||||
if (dividend >> 32)
|
||||
do_div(dividend, d);
|
||||
else
|
||||
dividend = (u32) dividend / d;
|
||||
|
||||
return dividend;
|
||||
}
|
||||
|
||||
/* calculate the quartic root of "a" using Newton-Raphson */
|
||||
static u32 qroot(u64 a)
|
||||
{
|
||||
u32 x, x1;
|
||||
|
||||
/* Initial estimate is based on:
|
||||
* qrt(x) = exp(log(x) / 4)
|
||||
*/
|
||||
x = 1u << (fls64(a) >> 2);
|
||||
|
||||
/*
|
||||
* Iteration based on:
|
||||
* 3
|
||||
* x = ( 3 * x + a / x ) / 4
|
||||
* k+1 k k
|
||||
*/
|
||||
do {
|
||||
u64 x3 = x;
|
||||
|
||||
x1 = x;
|
||||
x3 *= x;
|
||||
x3 *= x;
|
||||
|
||||
x = (3 * x + (u32) div64_64(a, x3)) / 4;
|
||||
} while (abs(x1 - x) > 1);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If the connection is idle and we are restarting,
|
||||
* 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,
|
||||
dwnd = vegas->dwnd;
|
||||
|
||||
if (diff < (TCP_COMPOUND_GAMMA << V_PARAM_SHIFT)) {
|
||||
u32 i, j, x, x2;
|
||||
u64 v;
|
||||
u32 x;
|
||||
|
||||
v = 1;
|
||||
|
||||
for (i = 0; i < TCP_COMPOUND_KAPPA_POW; i++)
|
||||
v *= old_wnd;
|
||||
|
||||
for (i = 0; i < TCP_COMPOUND_KAPPA_NSQRT; i++) {
|
||||
x = 1;
|
||||
for (j = 0; j < 200; j++) {
|
||||
x2 = (x + v / x) / 2;
|
||||
|
||||
if (x2 == x || !x2)
|
||||
break;
|
||||
|
||||
x = x2;
|
||||
}
|
||||
v = x;
|
||||
}
|
||||
|
||||
x = (u32) v >> TCP_COMPOUND_ALPHA;
|
||||
|
||||
/*
|
||||
* The TCP Compound paper describes the choice
|
||||
* of "k" determines the agressiveness,
|
||||
* ie. slope of the response function.
|
||||
*
|
||||
* For same value as HSTCP would be 0.8
|
||||
* but for computaional reasons, both the
|
||||
* original authors and this implementation
|
||||
* use 0.75.
|
||||
*/
|
||||
v = old_wnd;
|
||||
x = qroot(v * v * v) >> TCP_COMPOUND_ALPHA;
|
||||
if (x > 1)
|
||||
dwnd = x - 1;
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user