Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/cc/cc_cubic.h
Show All 35 Lines | |||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#ifndef _NETINET_CC_CUBIC_H_ | #ifndef _NETINET_CC_CUBIC_H_ | ||||
#define _NETINET_CC_CUBIC_H_ | #define _NETINET_CC_CUBIC_H_ | ||||
#include <sys/limits.h> | |||||
/* Number of bits of precision for fixed point math calcs. */ | /* Number of bits of precision for fixed point math calcs. */ | ||||
#define CUBIC_SHIFT 8 | #define CUBIC_SHIFT 8 | ||||
#define CUBIC_SHIFT_4 32 | #define CUBIC_SHIFT_4 32 | ||||
/* 0.5 << CUBIC_SHIFT. */ | /* 0.5 << CUBIC_SHIFT. */ | ||||
#define RENO_BETA 128 | #define RENO_BETA 128 | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | cubic_k(unsigned long wmax_pkts) | ||||
/* Multiply by 2^p to undo the rebasing of s from above. */ | /* Multiply by 2^p to undo the rebasing of s from above. */ | ||||
return (K <<= p); | return (K <<= p); | ||||
} | } | ||||
/* | /* | ||||
* Compute the new cwnd value using an implementation of eqn 1 from the I-D. | * Compute the new cwnd value using an implementation of eqn 1 from the I-D. | ||||
* Thanks to Kip Macy for help debugging this function. | * Thanks to Kip Macy for help debugging this function. | ||||
* | |||||
* XXXLAS: Characterise bounds for overflow. | |||||
*/ | */ | ||||
static __inline unsigned long | static __inline unsigned long | ||||
cubic_cwnd(int ticks_since_cong, unsigned long wmax, uint32_t smss, int64_t K) | cubic_cwnd(int ticks_since_cong, unsigned long wmax, uint32_t smss, int64_t K) | ||||
{ | { | ||||
int64_t cwnd; | int64_t cwnd; | ||||
/* K is in fixed point form with CUBIC_SHIFT worth of precision. */ | /* K is in fixed point form with CUBIC_SHIFT worth of precision. */ | ||||
/* t - K, with CUBIC_SHIFT worth of precision. */ | /* t - K, with CUBIC_SHIFT worth of precision. */ | ||||
cwnd = ((int64_t)(ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz; | cwnd = ((int64_t)(ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz; | ||||
/* moved this calculation up because it cannot overflow or underflow */ | |||||
cwnd *= CUBIC_C_FACTOR * smss; | |||||
if (cwnd > 2097151) /* 2^21 cubed is long max */ | |||||
return INT_MAX; | |||||
if (cwnd < -2097152) /* -2^21 cubed is long min */ | |||||
return smss; | |||||
/* (t - K)^3, with CUBIC_SHIFT^3 worth of precision. */ | /* (t - K)^3, with CUBIC_SHIFT^3 worth of precision. */ | ||||
cwnd *= (cwnd * cwnd); | cwnd *= (cwnd * cwnd); | ||||
/* | /* | ||||
* C(t - K)^3 + wmax | * C(t - K)^3 + wmax | ||||
* The down shift by CUBIC_SHIFT_4 is because cwnd has 4 lots of | * The down shift by CUBIC_SHIFT_4 is because cwnd has 4 lots of | ||||
* CUBIC_SHIFT included in the value. 3 from the cubing of cwnd above, | * CUBIC_SHIFT included in the value. 3 from the cubing of cwnd above, | ||||
* and an extra from multiplying through by CUBIC_C_FACTOR. | * and an extra from multiplying through by CUBIC_C_FACTOR. | ||||
* | |||||
* The original formula was this: | |||||
* cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax; | |||||
* | |||||
* CUBIC_C_FACTOR and smss factors were moved up to an earlier | |||||
* calculation to simplify overflow and underflow detection. | |||||
*/ | */ | ||||
cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax; | cwnd = (cwnd >> CUBIC_SHIFT_4) + wmax; | ||||
if (cwnd < 0) | |||||
return 1; | |||||
return ((unsigned long)cwnd); | return ((unsigned long)cwnd); | ||||
} | } | ||||
/* | /* | ||||
* Compute an approximation of the NewReno cwnd some number of ticks after a | * Compute an approximation of the NewReno cwnd some number of ticks after a | ||||
* congestion event. RTT should be the average RTT estimate for the path | * congestion event. RTT should be the average RTT estimate for the path | ||||
* measured over the previous congestion epoch and wmax is the value of cwnd at | * measured over the previous congestion epoch and wmax is the value of cwnd at | ||||
Show All 36 Lines |