Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/cc/cc_vegas.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#include <sys/queue.h> | #include <sys/queue.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_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> | ||||
#include <netinet/khelp/h_ertt.h> | #include <netinet/khelp/h_ertt.h> | ||||
/* | /* | ||||
* Private signal type for rate based congestion signal. | * Private signal type for rate based congestion signal. | ||||
* See <netinet/cc.h> for appropriate bit-range to use for private signals. | * See <netinet/cc.h> for appropriate bit-range to use for private signals. | ||||
*/ | */ | ||||
#define CC_VEGAS_RATE 0x01000000 | #define CC_VEGAS_RATE 0x01000000 | ||||
static void vegas_ack_received(struct cc_var *ccv, uint16_t ack_type); | static void vegas_ack_received(struct cc_var *ccv, uint16_t ack_type); | ||||
static void vegas_cb_destroy(struct cc_var *ccv); | static void vegas_cb_destroy(struct cc_var *ccv); | ||||
static int vegas_cb_init(struct cc_var *ccv); | static int vegas_cb_init(struct cc_var *ccv, void *ptr); | ||||
static void vegas_cong_signal(struct cc_var *ccv, uint32_t signal_type); | static void vegas_cong_signal(struct cc_var *ccv, uint32_t signal_type); | ||||
static void vegas_conn_init(struct cc_var *ccv); | static void vegas_conn_init(struct cc_var *ccv); | ||||
static int vegas_mod_init(void); | static int vegas_mod_init(void); | ||||
static size_t vegas_data_sz(void); | |||||
struct vegas { | struct vegas { | ||||
int slow_start_toggle; | int slow_start_toggle; | ||||
}; | }; | ||||
static int32_t ertt_id; | static int32_t ertt_id; | ||||
VNET_DEFINE_STATIC(uint32_t, vegas_alpha) = 1; | VNET_DEFINE_STATIC(uint32_t, vegas_alpha) = 1; | ||||
VNET_DEFINE_STATIC(uint32_t, vegas_beta) = 3; | VNET_DEFINE_STATIC(uint32_t, vegas_beta) = 3; | ||||
#define V_vegas_alpha VNET(vegas_alpha) | #define V_vegas_alpha VNET(vegas_alpha) | ||||
#define V_vegas_beta VNET(vegas_beta) | #define V_vegas_beta VNET(vegas_beta) | ||||
static MALLOC_DEFINE(M_VEGAS, "vegas data", | |||||
"Per connection data required for the Vegas congestion control algorithm"); | |||||
struct cc_algo vegas_cc_algo = { | struct cc_algo vegas_cc_algo = { | ||||
.name = "vegas", | .name = "vegas", | ||||
.ack_received = vegas_ack_received, | .ack_received = vegas_ack_received, | ||||
.cb_destroy = vegas_cb_destroy, | .cb_destroy = vegas_cb_destroy, | ||||
.cb_init = vegas_cb_init, | .cb_init = vegas_cb_init, | ||||
.cong_signal = vegas_cong_signal, | .cong_signal = vegas_cong_signal, | ||||
.conn_init = vegas_conn_init, | .conn_init = vegas_conn_init, | ||||
.mod_init = vegas_mod_init | .mod_init = vegas_mod_init, | ||||
.cc_data_sz = vegas_data_sz, | |||||
.after_idle = newreno_cc_after_idle, | |||||
.post_recovery = newreno_cc_post_recovery, | |||||
}; | }; | ||||
/* | /* | ||||
* The vegas window adjustment is done once every RTT, as indicated by the | * The vegas window adjustment is done once every RTT, as indicated by the | ||||
* ERTT_NEW_MEASUREMENT flag. This flag is reset once the new measurment data | * ERTT_NEW_MEASUREMENT flag. This flag is reset once the new measurment data | ||||
* has been used. | * has been used. | ||||
*/ | */ | ||||
static void | static void | ||||
Show All 32 Lines | if (e_t->minrtt && e_t->markedpkt_rtt) { | ||||
vegas_cong_signal(ccv, CC_VEGAS_RATE); | vegas_cong_signal(ccv, CC_VEGAS_RATE); | ||||
vegas_data->slow_start_toggle = 0; | vegas_data->slow_start_toggle = 0; | ||||
} | } | ||||
} | } | ||||
e_t->flags &= ~ERTT_NEW_MEASUREMENT; | e_t->flags &= ~ERTT_NEW_MEASUREMENT; | ||||
} | } | ||||
if (vegas_data->slow_start_toggle) | if (vegas_data->slow_start_toggle) | ||||
newreno_cc_algo.ack_received(ccv, ack_type); | newreno_cc_ack_received(ccv, ack_type); | ||||
} | } | ||||
static void | static void | ||||
vegas_cb_destroy(struct cc_var *ccv) | vegas_cb_destroy(struct cc_var *ccv) | ||||
{ | { | ||||
free(ccv->cc_data, M_VEGAS); | free(ccv->cc_data, M_CC_MEM); | ||||
} | } | ||||
static size_t | |||||
vegas_data_sz(void) | |||||
{ | |||||
return (sizeof(struct vegas)); | |||||
} | |||||
static int | static int | ||||
vegas_cb_init(struct cc_var *ccv) | vegas_cb_init(struct cc_var *ccv, void *ptr) | ||||
{ | { | ||||
struct vegas *vegas_data; | struct vegas *vegas_data; | ||||
vegas_data = malloc(sizeof(struct vegas), M_VEGAS, M_NOWAIT); | INP_WLOCK_ASSERT(ccv->ccvc.tcp->t_inpcb); | ||||
if (ptr == NULL) { | |||||
vegas_data = malloc(sizeof(struct vegas), M_CC_MEM, M_NOWAIT); | |||||
if (vegas_data == NULL) | if (vegas_data == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} else | |||||
vegas_data = ptr; | |||||
vegas_data->slow_start_toggle = 1; | vegas_data->slow_start_toggle = 1; | ||||
ccv->cc_data = vegas_data; | ccv->cc_data = vegas_data; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
Show All 20 Lines | if (!IN_RECOVERY(CCV(ccv, t_flags))) { | ||||
CCV(ccv, snd_cwnd) - CCV(ccv, t_maxseg)); | CCV(ccv, snd_cwnd) - CCV(ccv, t_maxseg)); | ||||
if (CCV(ccv, snd_cwnd) < CCV(ccv, snd_ssthresh)) | if (CCV(ccv, snd_cwnd) < CCV(ccv, snd_ssthresh)) | ||||
/* Exit slow start. */ | /* Exit slow start. */ | ||||
CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd); | CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd); | ||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
newreno_cc_algo.cong_signal(ccv, signal_type); | newreno_cc_cong_signal(ccv, signal_type); | ||||
} | } | ||||
if (IN_RECOVERY(CCV(ccv, t_flags)) && !presignalrecov) | if (IN_RECOVERY(CCV(ccv, t_flags)) && !presignalrecov) | ||||
vegas_data->slow_start_toggle = | vegas_data->slow_start_toggle = | ||||
(CCV(ccv, snd_cwnd) < CCV(ccv, snd_ssthresh)) ? 1 : 0; | (CCV(ccv, snd_cwnd) < CCV(ccv, snd_ssthresh)) ? 1 : 0; | ||||
} | } | ||||
static void | static void | ||||
vegas_conn_init(struct cc_var *ccv) | vegas_conn_init(struct cc_var *ccv) | ||||
{ | { | ||||
struct vegas *vegas_data; | struct vegas *vegas_data; | ||||
vegas_data = ccv->cc_data; | vegas_data = ccv->cc_data; | ||||
vegas_data->slow_start_toggle = 1; | vegas_data->slow_start_toggle = 1; | ||||
} | } | ||||
static int | static int | ||||
vegas_mod_init(void) | vegas_mod_init(void) | ||||
{ | { | ||||
ertt_id = khelp_get_id("ertt"); | ertt_id = khelp_get_id("ertt"); | ||||
if (ertt_id <= 0) { | if (ertt_id <= 0) { | ||||
printf("%s: h_ertt module not found\n", __func__); | printf("%s: h_ertt module not found\n", __func__); | ||||
return (ENOENT); | return (ENOENT); | ||||
} | } | ||||
vegas_cc_algo.after_idle = newreno_cc_algo.after_idle; | |||||
vegas_cc_algo.post_recovery = newreno_cc_algo.post_recovery; | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
vegas_alpha_handler(SYSCTL_HANDLER_ARGS) | vegas_alpha_handler(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int error; | int error; | ||||
uint32_t new; | uint32_t new; | ||||
Show All 39 Lines | SYSCTL_PROC(_net_inet_tcp_cc_vegas, OID_AUTO, alpha, | ||||
"vegas alpha, specified as number of \"buffers\" (0 < alpha < beta)"); | "vegas alpha, specified as number of \"buffers\" (0 < alpha < beta)"); | ||||
SYSCTL_PROC(_net_inet_tcp_cc_vegas, OID_AUTO, beta, | SYSCTL_PROC(_net_inet_tcp_cc_vegas, OID_AUTO, beta, | ||||
CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
&VNET_NAME(vegas_beta), 3, &vegas_beta_handler, "IU", | &VNET_NAME(vegas_beta), 3, &vegas_beta_handler, "IU", | ||||
"vegas beta, specified as number of \"buffers\" (0 < alpha < beta)"); | "vegas beta, specified as number of \"buffers\" (0 < alpha < beta)"); | ||||
DECLARE_CC_MODULE(vegas, &vegas_cc_algo); | DECLARE_CC_MODULE(vegas, &vegas_cc_algo); | ||||
MODULE_VERSION(vegas, 1); | MODULE_VERSION(vegas, 2); | ||||
MODULE_DEPEND(vegas, ertt, 1, 1, 1); | MODULE_DEPEND(vegas, ertt, 1, 1, 1); |