Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/cc/cc_htcp.c
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/socketvar.h> | #include <sys/socketvar.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <net/route.h> | |||||
#include <net/route/nhop.h> | |||||
#include <netinet/in_pcb.h> | |||||
#include <netinet/tcp.h> | #include <netinet/tcp.h> | ||||
#include <netinet/tcp_seq.h> | #include <netinet/tcp_seq.h> | ||||
#include <netinet/tcp_timer.h> | #include <netinet/tcp_timer.h> | ||||
#include <netinet/tcp_var.h> | #include <netinet/tcp_var.h> | ||||
#include <netinet/cc/cc.h> | #include <netinet/cc/cc.h> | ||||
#include <netinet/cc/cc_module.h> | #include <netinet/cc/cc_module.h> | ||||
/* Fixed point math shifts. */ | /* Fixed point math shifts. */ | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
((\ | ((\ | ||||
(16) + \ | (16) + \ | ||||
((160 * (diff)) / hz) + \ | ((160 * (diff)) / hz) + \ | ||||
(((diff) / hz) * (((diff) << HTCP_ALPHA_INC_SHIFT) / (4 * hz))) \ | (((diff) / hz) * (((diff) << HTCP_ALPHA_INC_SHIFT) / (4 * hz))) \ | ||||
) >> HTCP_ALPHA_INC_SHIFT) | ) >> HTCP_ALPHA_INC_SHIFT) | ||||
static void htcp_ack_received(struct cc_var *ccv, uint16_t type); | static void htcp_ack_received(struct cc_var *ccv, uint16_t type); | ||||
static void htcp_cb_destroy(struct cc_var *ccv); | static void htcp_cb_destroy(struct cc_var *ccv); | ||||
static int htcp_cb_init(struct cc_var *ccv); | static int htcp_cb_init(struct cc_var *ccv, void *ptr); | ||||
static void htcp_cong_signal(struct cc_var *ccv, uint32_t type); | static void htcp_cong_signal(struct cc_var *ccv, uint32_t type); | ||||
static int htcp_mod_init(void); | static int htcp_mod_init(void); | ||||
static void htcp_post_recovery(struct cc_var *ccv); | static void htcp_post_recovery(struct cc_var *ccv); | ||||
static void htcp_recalc_alpha(struct cc_var *ccv); | static void htcp_recalc_alpha(struct cc_var *ccv); | ||||
static void htcp_recalc_beta(struct cc_var *ccv); | static void htcp_recalc_beta(struct cc_var *ccv); | ||||
static void htcp_record_rtt(struct cc_var *ccv); | static void htcp_record_rtt(struct cc_var *ccv); | ||||
static void htcp_ssthresh_update(struct cc_var *ccv); | static void htcp_ssthresh_update(struct cc_var *ccv); | ||||
static size_t htcp_data_sz(void); | |||||
struct htcp { | struct htcp { | ||||
/* cwnd before entering cong recovery. */ | /* cwnd before entering cong recovery. */ | ||||
unsigned long prev_cwnd; | unsigned long prev_cwnd; | ||||
/* cwnd additive increase parameter. */ | /* cwnd additive increase parameter. */ | ||||
int alpha; | int alpha; | ||||
/* cwnd multiplicative decrease parameter. */ | /* cwnd multiplicative decrease parameter. */ | ||||
int beta; | int beta; | ||||
Show All 14 Lines | |||||
static int htcp_max_diff = INT_MAX / ((1 << HTCP_ALPHA_INC_SHIFT) * 10); | static int htcp_max_diff = INT_MAX / ((1 << HTCP_ALPHA_INC_SHIFT) * 10); | ||||
/* Per-netstack vars. */ | /* Per-netstack vars. */ | ||||
VNET_DEFINE_STATIC(u_int, htcp_adaptive_backoff) = 0; | VNET_DEFINE_STATIC(u_int, htcp_adaptive_backoff) = 0; | ||||
VNET_DEFINE_STATIC(u_int, htcp_rtt_scaling) = 0; | VNET_DEFINE_STATIC(u_int, htcp_rtt_scaling) = 0; | ||||
#define V_htcp_adaptive_backoff VNET(htcp_adaptive_backoff) | #define V_htcp_adaptive_backoff VNET(htcp_adaptive_backoff) | ||||
#define V_htcp_rtt_scaling VNET(htcp_rtt_scaling) | #define V_htcp_rtt_scaling VNET(htcp_rtt_scaling) | ||||
static MALLOC_DEFINE(M_HTCP, "htcp data", | |||||
"Per connection data required for the HTCP congestion control algorithm"); | |||||
struct cc_algo htcp_cc_algo = { | struct cc_algo htcp_cc_algo = { | ||||
.name = "htcp", | .name = "htcp", | ||||
.ack_received = htcp_ack_received, | .ack_received = htcp_ack_received, | ||||
.cb_destroy = htcp_cb_destroy, | .cb_destroy = htcp_cb_destroy, | ||||
.cb_init = htcp_cb_init, | .cb_init = htcp_cb_init, | ||||
.cong_signal = htcp_cong_signal, | .cong_signal = htcp_cong_signal, | ||||
.mod_init = htcp_mod_init, | .mod_init = htcp_mod_init, | ||||
.post_recovery = htcp_post_recovery, | .post_recovery = htcp_post_recovery, | ||||
.cc_data_sz = htcp_data_sz, | |||||
.after_idle = newreno_cc_after_idle, | |||||
}; | }; | ||||
static void | static void | ||||
htcp_ack_received(struct cc_var *ccv, uint16_t type) | htcp_ack_received(struct cc_var *ccv, uint16_t type) | ||||
{ | { | ||||
struct htcp *htcp_data; | struct htcp *htcp_data; | ||||
htcp_data = ccv->cc_data; | htcp_data = ccv->cc_data; | ||||
Show All 12 Lines | if (type == CC_ACK && !IN_RECOVERY(CCV(ccv, t_flags)) && | ||||
htcp_recalc_alpha(ccv); | htcp_recalc_alpha(ccv); | ||||
/* | /* | ||||
* Use the logic in NewReno ack_received() for slow start and | * Use the logic in NewReno ack_received() for slow start and | ||||
* for the first HTCP_DELTA_L ticks after either the flow starts | * for the first HTCP_DELTA_L ticks after either the flow starts | ||||
* or a congestion event (when alpha equals 1). | * or a congestion event (when alpha equals 1). | ||||
*/ | */ | ||||
if (htcp_data->alpha == 1 || | if (htcp_data->alpha == 1 || | ||||
CCV(ccv, snd_cwnd) <= CCV(ccv, snd_ssthresh)) | CCV(ccv, snd_cwnd) <= CCV(ccv, snd_ssthresh)) | ||||
newreno_cc_algo.ack_received(ccv, type); | newreno_cc_ack_received(ccv, type); | ||||
else { | else { | ||||
if (V_tcp_do_rfc3465) { | if (V_tcp_do_rfc3465) { | ||||
/* Increment cwnd by alpha segments. */ | /* Increment cwnd by alpha segments. */ | ||||
CCV(ccv, snd_cwnd) += htcp_data->alpha * | CCV(ccv, snd_cwnd) += htcp_data->alpha * | ||||
CCV(ccv, t_maxseg); | CCV(ccv, t_maxseg); | ||||
ccv->flags &= ~CCF_ABC_SENTAWND; | ccv->flags &= ~CCF_ABC_SENTAWND; | ||||
} else | } else | ||||
/* | /* | ||||
* Increment cwnd by alpha/cwnd segments to | * Increment cwnd by alpha/cwnd segments to | ||||
* approximate an increase of alpha segments | * approximate an increase of alpha segments | ||||
* per RTT. | * per RTT. | ||||
*/ | */ | ||||
CCV(ccv, snd_cwnd) += (((htcp_data->alpha << | CCV(ccv, snd_cwnd) += (((htcp_data->alpha << | ||||
HTCP_SHIFT) / (CCV(ccv, snd_cwnd) / | HTCP_SHIFT) / (CCV(ccv, snd_cwnd) / | ||||
CCV(ccv, t_maxseg))) * CCV(ccv, t_maxseg)) | CCV(ccv, t_maxseg))) * CCV(ccv, t_maxseg)) | ||||
>> HTCP_SHIFT; | >> HTCP_SHIFT; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
htcp_cb_destroy(struct cc_var *ccv) | htcp_cb_destroy(struct cc_var *ccv) | ||||
{ | { | ||||
free(ccv->cc_data, M_HTCP); | free(ccv->cc_data, M_CC_MEM); | ||||
} | } | ||||
static size_t | |||||
htcp_data_sz(void) | |||||
{ | |||||
return(sizeof(struct htcp)); | |||||
} | |||||
static int | static int | ||||
htcp_cb_init(struct cc_var *ccv) | htcp_cb_init(struct cc_var *ccv, void *ptr) | ||||
{ | { | ||||
struct htcp *htcp_data; | struct htcp *htcp_data; | ||||
htcp_data = malloc(sizeof(struct htcp), M_HTCP, M_NOWAIT); | INP_WLOCK_ASSERT(ccv->ccvc.tcp->t_inpcb); | ||||
if (ptr == NULL) { | |||||
htcp_data = malloc(sizeof(struct htcp), M_CC_MEM, M_NOWAIT); | |||||
if (htcp_data == NULL) | if (htcp_data == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} else | |||||
htcp_data = ptr; | |||||
/* Init some key variables with sensible defaults. */ | /* Init some key variables with sensible defaults. */ | ||||
htcp_data->alpha = HTCP_INIT_ALPHA; | htcp_data->alpha = HTCP_INIT_ALPHA; | ||||
htcp_data->beta = HTCP_MINBETA; | htcp_data->beta = HTCP_MINBETA; | ||||
htcp_data->maxrtt = TCPTV_SRTTBASE; | htcp_data->maxrtt = TCPTV_SRTTBASE; | ||||
htcp_data->minrtt = TCPTV_SRTTBASE; | htcp_data->minrtt = TCPTV_SRTTBASE; | ||||
htcp_data->prev_cwnd = 0; | htcp_data->prev_cwnd = 0; | ||||
htcp_data->t_last_cong = ticks; | htcp_data->t_last_cong = ticks; | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | if (CCV(ccv, t_rxtshift) >= 2) | ||||
htcp_data->t_last_cong = ticks; | htcp_data->t_last_cong = ticks; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
htcp_mod_init(void) | htcp_mod_init(void) | ||||
{ | { | ||||
htcp_cc_algo.after_idle = newreno_cc_algo.after_idle; | |||||
/* | /* | ||||
* HTCP_RTT_REF is defined in ms, and t_srtt in the tcpcb is stored in | * HTCP_RTT_REF is defined in ms, and t_srtt in the tcpcb is stored in | ||||
* units of TCP_RTT_SCALE*hz. Scale HTCP_RTT_REF to be in the same units | * units of TCP_RTT_SCALE*hz. Scale HTCP_RTT_REF to be in the same units | ||||
* as t_srtt. | * as t_srtt. | ||||
*/ | */ | ||||
htcp_rtt_ref = (HTCP_RTT_REF * TCP_RTT_SCALE * hz) / 1000; | htcp_rtt_ref = (HTCP_RTT_REF * TCP_RTT_SCALE * hz) / 1000; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Perform any necessary tasks before we exit congestion recovery. | * Perform any necessary tasks before we exit congestion recovery. | ||||
*/ | */ | ||||
static void | static void | ||||
htcp_post_recovery(struct cc_var *ccv) | htcp_post_recovery(struct cc_var *ccv) | ||||
▲ Show 20 Lines • Show All 176 Lines • ▼ Show 20 Lines | |||||
SYSCTL_UINT(_net_inet_tcp_cc_htcp, OID_AUTO, adaptive_backoff, | SYSCTL_UINT(_net_inet_tcp_cc_htcp, OID_AUTO, adaptive_backoff, | ||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(htcp_adaptive_backoff), 0, | CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(htcp_adaptive_backoff), 0, | ||||
"enable H-TCP adaptive backoff"); | "enable H-TCP adaptive backoff"); | ||||
SYSCTL_UINT(_net_inet_tcp_cc_htcp, OID_AUTO, rtt_scaling, | SYSCTL_UINT(_net_inet_tcp_cc_htcp, OID_AUTO, rtt_scaling, | ||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(htcp_rtt_scaling), 0, | CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(htcp_rtt_scaling), 0, | ||||
"enable H-TCP RTT scaling"); | "enable H-TCP RTT scaling"); | ||||
DECLARE_CC_MODULE(htcp, &htcp_cc_algo); | DECLARE_CC_MODULE(htcp, &htcp_cc_algo); | ||||
MODULE_VERSION(htcp, 1); | MODULE_VERSION(htcp, 2); |