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 All 13 Lines | |||||
#define CUBIC_C_FACTOR 102 | #define CUBIC_C_FACTOR 102 | ||||
/* CUBIC fast convergence factor: (1+beta_cubic)/2. */ | /* CUBIC fast convergence factor: (1+beta_cubic)/2. */ | ||||
#define CUBIC_FC_FACTOR 217 | #define CUBIC_FC_FACTOR 217 | ||||
/* Don't trust s_rtt until this many rtt samples have been taken. */ | /* Don't trust s_rtt until this many rtt samples have been taken. */ | ||||
#define CUBIC_MIN_RTT_SAMPLES 8 | #define CUBIC_MIN_RTT_SAMPLES 8 | ||||
/* | |||||
* (2^21)^3 is long max. Dividing (2^63) by Cubic_C_factor | |||||
* and taking cube-root yields 448845 as the effective useful limit | |||||
*/ | |||||
#define CUBED_ROOT_MAX_ULONG 448845 | |||||
/* Userland only bits. */ | /* Userland only bits. */ | ||||
#ifndef _KERNEL | #ifndef _KERNEL | ||||
extern int hz; | extern int hz; | ||||
/* | /* | ||||
* Implementation based on the formulae found in the CUBIC Internet Draft | * Implementation based on the formulae found in the CUBIC Internet Draft | ||||
* "draft-ietf-tcpm-cubic-04". | * "draft-ietf-tcpm-cubic-04". | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
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; | ||||
if (cwnd > CUBED_ROOT_MAX_ULONG) | |||||
return INT_MAX; | |||||
if (cwnd < -CUBED_ROOT_MAX_ULONG) | |||||
return 0; | |||||
/* (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. | ||||
*/ | */ | ||||
cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax; | |||||
return ((unsigned long)cwnd); | cwnd = ((cwnd * CUBIC_C_FACTOR) >> CUBIC_SHIFT_4) * smss + wmax; | ||||
/* | |||||
* for negative cwnd, limiting to zero as lower bound | |||||
*/ | |||||
return (lmax(0,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 | ||||
* the last congestion event. The "TCP friendly" concept in the CUBIC I-D is | * the last congestion event. The "TCP friendly" concept in the CUBIC I-D is | ||||
* rather tricky to understand and it turns out this function is not required. | * rather tricky to understand and it turns out this function is not required. | ||||
Show All 21 Lines | |||||
* the value of cwnd at the last congestion event. | * the value of cwnd at the last congestion event. | ||||
*/ | */ | ||||
static __inline unsigned long | static __inline unsigned long | ||||
tf_cwnd(int ticks_since_cong, int rtt_ticks, unsigned long wmax, | tf_cwnd(int ticks_since_cong, int rtt_ticks, unsigned long wmax, | ||||
uint32_t smss) | uint32_t smss) | ||||
{ | { | ||||
/* Equation 4 of I-D. */ | /* Equation 4 of I-D. */ | ||||
return (((wmax * CUBIC_BETA) + (((THREE_X_PT3 * ticks_since_cong * | return (((wmax * CUBIC_BETA) + | ||||
smss) << CUBIC_SHIFT) / TWO_SUB_PT3 / rtt_ticks)) >> CUBIC_SHIFT); | (((THREE_X_PT3 * (unsigned long)ticks_since_cong * | ||||
(unsigned long)smss) << CUBIC_SHIFT) / (TWO_SUB_PT3 * rtt_ticks))) | |||||
>> CUBIC_SHIFT); | |||||
} | } | ||||
#endif /* _NETINET_CC_CUBIC_H_ */ | #endif /* _NETINET_CC_CUBIC_H_ */ |