Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/cc/cc_cubic.h
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#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 | ||||
/* ~0.7 << CUBIC_SHIFT. */ | /* ~0.7 << CUBIC_SHIFT. */ | ||||
#define CUBIC_BETA 179 | #define CUBIC_BETA 179 | ||||
/* ~0.53 << CUBIC_SHIFT: 3 * (1-beta_cubic)/(1+beta_cubic). */ | |||||
#define CUBIC_ALPHA 135 | |||||
/* 1 << CUBIC_SHIFT. */ | |||||
#define CUBIC_ALPHA_ONE 256 | |||||
/* ~0.3 << CUBIC_SHIFT. */ | /* ~0.3 << CUBIC_SHIFT. */ | ||||
#define ONE_SUB_CUBIC_BETA 77 | #define ONE_SUB_CUBIC_BETA 77 | ||||
/* 3 * ONE_SUB_CUBIC_BETA. */ | /* 3 * ONE_SUB_CUBIC_BETA. */ | ||||
#define THREE_X_PT3 231 | #define THREE_X_PT3 231 | ||||
/* (2 << CUBIC_SHIFT) - ONE_SUB_CUBIC_BETA. */ | /* (2 << CUBIC_SHIFT) - ONE_SUB_CUBIC_BETA. */ | ||||
#define TWO_SUB_PT3 435 | #define TWO_SUB_PT3 435 | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
/* 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-rfc8312bis-15". | ||||
* | * | ||||
*/ | */ | ||||
static __inline float | static __inline float | ||||
theoretical_cubic_k(double wmax_pkts) | theoretical_cubic_k(double wmax_pkts, double cwnd_epoch_pkts) | ||||
{ | { | ||||
double C; | double C; | ||||
C = 0.4; | C = 0.4; | ||||
return (pow((wmax_pkts * 0.3) / C, (1.0 / 3.0)) * pow(2, CUBIC_SHIFT)); | if (wmax_pkts <= cwnd_epoch_pkts) | ||||
return 0.0; | |||||
return (pow((wmax_pkts - cwnd_epoch_pkts) / C, (1.0 / 3.0)) * pow(2, CUBIC_SHIFT)); | |||||
} | } | ||||
static __inline unsigned long | static __inline unsigned long | ||||
theoretical_cubic_cwnd(int ticks_since_epoch, unsigned long wmax, uint32_t smss) | theoretical_cubic_cwnd(int ticks_since_epoch, unsigned long wmax, | ||||
unsigned long cwnd_epoch, uint32_t smss) | |||||
{ | { | ||||
double C, wmax_pkts; | double C, wmax_pkts, cwnd_epoch_pkts; | ||||
C = 0.4; | C = 0.4; | ||||
wmax_pkts = wmax / (double)smss; | wmax_pkts = wmax / (double)smss; | ||||
cwnd_epoch_pkts = cwnd_epoch / (double)smss; | |||||
return (smss * (wmax_pkts + | return (smss * (wmax_pkts + | ||||
(C * pow(ticks_since_epoch / (double)hz - | (C * pow(ticks_since_epoch / (double)hz - | ||||
theoretical_cubic_k(wmax_pkts) / pow(2, CUBIC_SHIFT), 3.0)))); | theoretical_cubic_k(wmax_pkts, cwnd_epoch_pkts) / pow(2, CUBIC_SHIFT), 3.0)))); | ||||
} | } | ||||
static __inline unsigned long | static __inline unsigned long | ||||
theoretical_reno_cwnd(int ticks_since_epoch, int rtt_ticks, unsigned long wmax, | theoretical_reno_cwnd(int ticks_since_epoch, int rtt_ticks, unsigned long wmax, | ||||
uint32_t smss) | uint32_t smss) | ||||
{ | { | ||||
return ((wmax * 0.5) + ((ticks_since_epoch / (float)rtt_ticks) * smss)); | return ((wmax * 0.5) + ((ticks_since_epoch / (float)rtt_ticks) * smss)); | ||||
} | } | ||||
static __inline unsigned long | static __inline unsigned long | ||||
theoretical_tf_cwnd(int ticks_since_epoch, int rtt_ticks, unsigned long wmax, | theoretical_tf_cwnd(unsigned long west, unsigned long bytes_acked, unsigned long cwnd, | ||||
uint32_t smss) | unsigned long cwnd_prior, unsigned long smss) | ||||
{ | { | ||||
return ((wmax * 0.7) + ((3 * 0.3) / (2 - 0.3) * | float cubic_alpha; | ||||
(ticks_since_epoch / (float)rtt_ticks) * smss)); | |||||
if (west >= cwnd_prior) | |||||
cubic_alpha = 1.0; | |||||
else | |||||
cubic_alpha = (3.0 * (1.0 - 0.7)) / (1.0 + 0.7); | |||||
return (west + (cubic_alpha * ((bytes_acked * smss) / (float)cwnd))); | |||||
} | } | ||||
#endif /* !_KERNEL */ | #endif /* !_KERNEL */ | ||||
/* | /* | ||||
* Compute the CUBIC K value used in the cwnd calculation, using an | * Compute the CUBIC K value used in the cwnd calculation, using an | ||||
* implementation of eqn 2 in the I-D. The method used | * implementation mentioned in Fig. 2 of draft-ietf-tcpm-rfc8312bis-15. | ||||
* here is adapted from Apple Computer Technical Report #KT-32. | * The method used here is adapted from Apple Computer Technical | ||||
* Report #KT-32. | |||||
*/ | */ | ||||
static __inline int64_t | static __inline int64_t | ||||
cubic_k(unsigned long wmax_pkts) | cubic_k(unsigned long wmax_pkts, unsigned long cwnd_epoch_pkts) | ||||
{ | { | ||||
int64_t s, K; | int64_t s, K; | ||||
uint16_t p; | uint16_t p; | ||||
K = s = 0; | K = s = 0; | ||||
p = 0; | p = 0; | ||||
/* (wmax * beta)/C with CUBIC_SHIFT worth of precision. */ | /* Handle the corner case where W_max <= cwnd_epoch */ | ||||
s = ((wmax_pkts * ONE_SUB_CUBIC_BETA) << CUBIC_SHIFT) / CUBIC_C_FACTOR; | if (wmax_pkts <= cwnd_epoch_pkts) { | ||||
return 0; | |||||
} | |||||
/* (wmax - cwnd_epoch) / C with CUBIC_SHIFT worth of precision. */ | |||||
s = ((wmax_pkts - cwnd_epoch_pkts) << (2 * CUBIC_SHIFT)) / CUBIC_C_FACTOR; | |||||
/* Rebase s to be between 1 and 1/8 with a shift of CUBIC_SHIFT. */ | /* Rebase s to be between 1 and 1/8 with a shift of CUBIC_SHIFT. */ | ||||
while (s >= 256) { | while (s >= 256) { | ||||
s >>= 3; | s >>= 3; | ||||
p++; | p++; | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 95 Lines • Show Last 20 Lines |