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 | |||||