Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/cc/cc_cubic.h
Show First 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
#define CUBICFLAG_HYSTART_ENABLED 0x00000010 /* Hystart++ is enabled */ | #define CUBICFLAG_HYSTART_ENABLED 0x00000010 /* Hystart++ is enabled */ | ||||
#define CUBICFLAG_HYSTART_IN_CSS 0x00000020 /* We are in Hystart++ CSS */ | #define CUBICFLAG_HYSTART_IN_CSS 0x00000020 /* We are in Hystart++ CSS */ | ||||
/* Kernel only bits */ | /* Kernel only bits */ | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
struct cubic { | struct cubic { | ||||
/* CUBIC K in fixed point form with CUBIC_SHIFT worth of precision. */ | /* CUBIC K in fixed point form with CUBIC_SHIFT worth of precision. */ | ||||
int64_t K; | int64_t K; | ||||
/* Sum of RTT samples across an epoch in ticks. */ | /* Sum of RTT samples across an epoch in usecs. */ | ||||
int64_t sum_rtt_ticks; | int64_t sum_rtt_usecs; | ||||
/* cwnd at the most recent congestion event. */ | /* cwnd at the most recent congestion event. */ | ||||
unsigned long max_cwnd; | unsigned long max_cwnd; | ||||
/* cwnd at the previous congestion event. */ | /* cwnd at the previous congestion event. */ | ||||
unsigned long prev_max_cwnd; | unsigned long prev_max_cwnd; | ||||
/* A copy of prev_max_cwnd. Used for CC_RTO_ERR */ | /* A copy of prev_max_cwnd. Used for CC_RTO_ERR */ | ||||
unsigned long prev_max_cwnd_cp; | unsigned long prev_max_cwnd_cp; | ||||
/* various flags */ | /* various flags */ | ||||
uint32_t flags; | uint32_t flags; | ||||
/* Minimum observed rtt in ticks. */ | /* Minimum observed rtt in usecs. */ | ||||
int min_rtt_ticks; | int min_rtt_usecs; | ||||
/* Mean observed rtt between congestion epochs. */ | /* Mean observed rtt between congestion epochs. */ | ||||
int mean_rtt_ticks; | int mean_rtt_usecs; | ||||
/* ACKs since last congestion event. */ | /* ACKs since last congestion event. */ | ||||
int epoch_ack_count; | int epoch_ack_count; | ||||
/* Timestamp (in ticks) of arriving in congestion avoidance from last | /* Timestamp (in ticks) of arriving in congestion avoidance from last | ||||
* congestion event. | * congestion event. | ||||
*/ | */ | ||||
int t_last_cong; | int t_last_cong; | ||||
tuexen: Why isn't this converted? | |||||
Done Inline ActionsI am not sure if there is a high resolution timer to use for the base stack. So this is a workaround. cc: I am not sure if there is a high resolution timer to use for the base stack. So this is a… | |||||
Done Inline ActionsSecondly, cubic_data->t_last_cong as an intermediate variable is used for usecs_since_cong calculation in cubic_ack_received(). The usecs_since_cong is converted by using usec there. So I don't think we need to convert cubic_data->t_last_cong by TICKS_2_USEC(ticks). cc: Secondly, cubic_data->t_last_cong as an intermediate variable is used for usecs_since_cong… | |||||
/* Timestamp (in ticks) of a previous congestion event. Used for | /* Timestamp (in ticks) of a previous congestion event. Used for | ||||
* CC_RTO_ERR. | * CC_RTO_ERR. | ||||
*/ | */ | ||||
int t_last_cong_prev; | int t_last_cong_prev; | ||||
uint32_t css_baseline_minrtt; | uint32_t css_baseline_minrtt; | ||||
uint32_t css_current_round_minrtt; | uint32_t css_current_round_minrtt; | ||||
uint32_t css_lastround_minrtt; | uint32_t css_lastround_minrtt; | ||||
uint32_t css_rttsample_count; | uint32_t css_rttsample_count; | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* 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. | * 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 usecs_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)usecs_since_cong << CUBIC_SHIFT) - (K * hz * tick)) / | ||||
(hz * tick); | |||||
Not Done Inline ActionsShould there be a space between * and tick? tuexen: Should there be a space between `*` and `tick`? | |||||
if (cwnd > CUBED_ROOT_MAX_ULONG) | if (cwnd > CUBED_ROOT_MAX_ULONG) | ||||
return INT_MAX; | return INT_MAX; | ||||
if (cwnd < -CUBED_ROOT_MAX_ULONG) | if (cwnd < -CUBED_ROOT_MAX_ULONG) | ||||
return 0; | 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); | ||||
Show All 9 Lines | cubic_cwnd(int usecs_since_cong, unsigned long wmax, uint32_t smss, int64_t K) | ||||
/* | /* | ||||
* for negative cwnd, limiting to zero as lower bound | * for negative cwnd, limiting to zero as lower bound | ||||
*/ | */ | ||||
return (lmax(0,cwnd)); | 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 usecs 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. | ||||
* It is left here for reference. | * It is left here for reference. | ||||
* | |||||
* XXX: Not used | |||||
*/ | */ | ||||
static __inline unsigned long | static __inline unsigned long | ||||
reno_cwnd(int ticks_since_cong, int rtt_ticks, unsigned long wmax, | reno_cwnd(int usecs_since_cong, int rtt_usecs, unsigned long wmax, | ||||
uint32_t smss) | uint32_t smss) | ||||
{ | { | ||||
/* | /* | ||||
* For NewReno, beta = 0.5, therefore: W_tcp(t) = wmax*0.5 + t/RTT | * For NewReno, beta = 0.5, therefore: W_tcp(t) = wmax*0.5 + t/RTT | ||||
* W_tcp(t) deals with cwnd/wmax in pkts, so because our cwnd is in | * W_tcp(t) deals with cwnd/wmax in pkts, so because our cwnd is in | ||||
* bytes, we have to multiply by smss. | * bytes, we have to multiply by smss. | ||||
*/ | */ | ||||
return (((wmax * RENO_BETA) + (((ticks_since_cong * smss) | return (((wmax * RENO_BETA) + (((usecs_since_cong * smss) | ||||
<< CUBIC_SHIFT) / rtt_ticks)) >> CUBIC_SHIFT); | << CUBIC_SHIFT) / rtt_usecs)) >> CUBIC_SHIFT); | ||||
} | } | ||||
/* | /* | ||||
* Compute an approximation of the "TCP friendly" cwnd some number of ticks | * Compute an approximation of the "TCP friendly" cwnd some number of usecs | ||||
* after a congestion event that is designed to yield the same average cwnd as | * after a congestion event that is designed to yield the same average cwnd as | ||||
* NewReno while using CUBIC's beta of 0.7. RTT should be the average RTT | * NewReno while using CUBIC's beta of 0.7. RTT should be the average RTT | ||||
* estimate for the path measured over the previous congestion epoch and wmax is | * estimate for the path measured over the previous congestion epoch and wmax is | ||||
* 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 usecs_since_cong, int rtt_usecs, unsigned long wmax, | ||||
uint32_t smss) | uint32_t smss) | ||||
{ | { | ||||
/* Equation 4 of I-D. */ | /* Equation 4 of I-D. */ | ||||
return (((wmax * CUBIC_BETA) + | return (((wmax * CUBIC_BETA) + | ||||
(((THREE_X_PT3 * (unsigned long)ticks_since_cong * | (((THREE_X_PT3 * (unsigned long)usecs_since_cong * | ||||
(unsigned long)smss) << CUBIC_SHIFT) / (TWO_SUB_PT3 * rtt_ticks))) | (unsigned long)smss) << CUBIC_SHIFT) / (TWO_SUB_PT3 * rtt_usecs))) | ||||
>> CUBIC_SHIFT); | >> CUBIC_SHIFT); | ||||
} | } | ||||
#endif /* _NETINET_CC_CUBIC_H_ */ | #endif /* _NETINET_CC_CUBIC_H_ */ |
Why isn't this converted?