Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/cc/cc_dctcp.c
Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <netinet/tcp.h> | #include <netinet/tcp.h> | ||||
#include <netinet/tcp_seq.h> | #include <netinet/tcp_seq.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> | ||||
#define MAX_ALPHA_VALUE 1024 | #define DCTCP_SHIFT 10 | ||||
#define MAX_ALPHA_VALUE 1<<DCTCP_SHIFT | |||||
tuexen: Please add parentheses around the expression. | |||||
VNET_DEFINE_STATIC(uint32_t, dctcp_alpha) = 0; | VNET_DEFINE_STATIC(uint32_t, dctcp_alpha) = 0; | ||||
#define V_dctcp_alpha VNET(dctcp_alpha) | #define V_dctcp_alpha VNET(dctcp_alpha) | ||||
VNET_DEFINE_STATIC(uint32_t, dctcp_shift_g) = 4; | VNET_DEFINE_STATIC(uint32_t, dctcp_shift_g) = 4; | ||||
#define V_dctcp_shift_g VNET(dctcp_shift_g) | #define V_dctcp_shift_g VNET(dctcp_shift_g) | ||||
VNET_DEFINE_STATIC(uint32_t, dctcp_slowstart) = 0; | VNET_DEFINE_STATIC(uint32_t, dctcp_slowstart) = 0; | ||||
#define V_dctcp_slowstart VNET(dctcp_slowstart) | #define V_dctcp_slowstart VNET(dctcp_slowstart) | ||||
struct dctcp { | struct dctcp { | ||||
int bytes_ecn; /* # of marked bytes during a RTT */ | uint32_t bytes_ecn; /* # of marked bytes during a RTT */ | ||||
int bytes_total; /* # of acked bytes during a RTT */ | uint32_t bytes_total; /* # of acked bytes during a RTT */ | ||||
int alpha; /* the fraction of marked bytes */ | int alpha; /* the fraction of marked bytes */ | ||||
int ce_prev; /* CE state of the last segment */ | int ce_prev; /* CE state of the last segment */ | ||||
int save_sndnxt; /* end sequence number of the current window */ | tcp_seq save_sndnxt; /* end sequence number of the current window */ | ||||
int ece_curr; /* ECE flag in this segment */ | int ece_curr; /* ECE flag in this segment */ | ||||
int ece_prev; /* ECE flag in the last segment */ | int ece_prev; /* ECE flag in the last segment */ | ||||
uint32_t num_cong_events; /* # of congestion events */ | uint32_t num_cong_events; /* # of congestion events */ | ||||
}; | }; | ||||
static MALLOC_DEFINE(M_dctcp, "dctcp data", | static MALLOC_DEFINE(M_dctcp, "dctcp data", | ||||
"Per connection data required for the dctcp algorithm"); | "Per connection data required for the dctcp algorithm"); | ||||
static void dctcp_ack_received(struct cc_var *ccv, uint16_t type); | static void dctcp_ack_received(struct cc_var *ccv, uint16_t type); | ||||
static void dctcp_after_idle(struct cc_var *ccv); | static void dctcp_after_idle(struct cc_var *ccv); | ||||
static void dctcp_cb_destroy(struct cc_var *ccv); | static void dctcp_cb_destroy(struct cc_var *ccv); | ||||
▲ Show 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | dctcp_update_alpha(struct cc_var *ccv) | ||||
struct dctcp *dctcp_data; | struct dctcp *dctcp_data; | ||||
int alpha_prev; | int alpha_prev; | ||||
dctcp_data = ccv->cc_data; | dctcp_data = ccv->cc_data; | ||||
alpha_prev = dctcp_data->alpha; | alpha_prev = dctcp_data->alpha; | ||||
dctcp_data->bytes_total = max(dctcp_data->bytes_total, 1); | dctcp_data->bytes_total = max(dctcp_data->bytes_total, 1); | ||||
/* | /* | ||||
* Update alpha: alpha = (1 - g) * alpha + g * F. | * Update alpha: alpha = (1 - g) * alpha + g * M. | ||||
Done Inline ActionsTo be consistent with the RFC, please also replace the 'F' with the 'M'. cc: To be consistent with the RFC, please also replace the 'F' with the 'M'. | |||||
Done Inline ActionsDone. (RFC8257, page 7) rscheff: Done. (RFC8257, page 7) | |||||
* Here: | * Here: | ||||
* g is weight factor | * g is weight factor | ||||
* recommaded to be set to 1/16 | * recommaded to be set to 1/16 | ||||
* small g = slow convergence between competitive DCTCP flows | * small g = slow convergence between competitive DCTCP flows | ||||
* large g = impacts low utilization of bandwidth at switches | * large g = impacts low utilization of bandwidth at switches | ||||
* F is fraction of marked segments in last RTT | * M is fraction of marked segments in last RTT | ||||
* updated every RTT | * updated every RTT | ||||
* Alpha must be round to 0 - MAX_ALPHA_VALUE. | * Alpha must be round to 0 - MAX_ALPHA_VALUE. | ||||
*/ | */ | ||||
dctcp_data->alpha = min(alpha_prev - (alpha_prev >> V_dctcp_shift_g) + | dctcp_data->alpha = ulmin(alpha_prev - (alpha_prev >> V_dctcp_shift_g) + | ||||
(dctcp_data->bytes_ecn << (10 - V_dctcp_shift_g)) / | ((uint64_t)dctcp_data->bytes_ecn << (DCTCP_SHIFT - V_dctcp_shift_g)) / | ||||
dctcp_data->bytes_total, MAX_ALPHA_VALUE); | dctcp_data->bytes_total, MAX_ALPHA_VALUE); | ||||
/* Initialize internal parameters for next alpha calculation */ | /* Initialize internal parameters for next alpha calculation */ | ||||
dctcp_data->bytes_ecn = 0; | dctcp_data->bytes_ecn = 0; | ||||
dctcp_data->bytes_total = 0; | dctcp_data->bytes_total = 0; | ||||
dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); | dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); | ||||
} | } | ||||
static int | static int | ||||
dctcp_alpha_handler(SYSCTL_HANDLER_ARGS) | dctcp_alpha_handler(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
uint32_t new; | uint32_t new; | ||||
int error; | int error; | ||||
new = V_dctcp_alpha; | new = V_dctcp_alpha; | ||||
error = sysctl_handle_int(oidp, &new, 0, req); | error = sysctl_handle_int(oidp, &new, 0, req); | ||||
if (error == 0 && req->newptr != NULL) { | if (error == 0 && req->newptr != NULL) { | ||||
if (new > 1) | if ((new < 0) || (new > MAX_ALPHA_VALUE)) | ||||
Done Inline Actionsnew is declared as uint32_t. So it can't be negative. tuexen: `new` is declared as `uint32_t`. So it can't be negative.
Either remove the check (and catch… | |||||
Done Inline ActionsChecked the SYSCTL utility functions; apparently, with the CTLTYPE_UINT, negative input strings are discarded there, so no need to check here again. The handler is only called once these basic checks succeed. Thus removing the check for negatives here. rscheff: Checked the SYSCTL utility functions; apparently, with the CTLTYPE_UINT, negative input strings… | |||||
error = EINVAL; | error = EINVAL; | ||||
else { | |||||
if (new > MAX_ALPHA_VALUE) | |||||
V_dctcp_alpha = MAX_ALPHA_VALUE; | |||||
else | else | ||||
V_dctcp_alpha = new; | V_dctcp_alpha = new; | ||||
} | } | ||||
} | |||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
dctcp_shift_g_handler(SYSCTL_HANDLER_ARGS) | dctcp_shift_g_handler(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
uint32_t new; | uint32_t new; | ||||
int error; | int error; | ||||
new = V_dctcp_shift_g; | new = V_dctcp_shift_g; | ||||
error = sysctl_handle_int(oidp, &new, 0, req); | error = sysctl_handle_int(oidp, &new, 0, req); | ||||
if (error == 0 && req->newptr != NULL) { | if (error == 0 && req->newptr != NULL) { | ||||
if (new > 1) | if ((new < 0) || (new > DCTCP_SHIFT)) | ||||
Done Inline ActionsSame as in dctcp_alpha_handler(). tuexen: Same as in `dctcp_alpha_handler()`. | |||||
error = EINVAL; | error = EINVAL; | ||||
else | else | ||||
V_dctcp_shift_g = new; | V_dctcp_shift_g = new; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
dctcp_slowstart_handler(SYSCTL_HANDLER_ARGS) | dctcp_slowstart_handler(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
uint32_t new; | uint32_t new; | ||||
int error; | int error; | ||||
new = V_dctcp_slowstart; | new = V_dctcp_slowstart; | ||||
error = sysctl_handle_int(oidp, &new, 0, req); | error = sysctl_handle_int(oidp, &new, 0, req); | ||||
if (error == 0 && req->newptr != NULL) { | if (error == 0 && req->newptr != NULL) { | ||||
if (new > 1) | if ((new < 0) || (new > 1)) | ||||
Done Inline ActionsSame as in dctcp_alpha_handler(). tuexen: Same as in `dctcp_alpha_handler()`. | |||||
error = EINVAL; | error = EINVAL; | ||||
else | else | ||||
V_dctcp_slowstart = new; | V_dctcp_slowstart = new; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_DECL(_net_inet_tcp_cc_dctcp); | SYSCTL_DECL(_net_inet_tcp_cc_dctcp); | ||||
SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, dctcp, CTLFLAG_RW, NULL, | SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, dctcp, CTLFLAG_RW, NULL, | ||||
"dctcp congestion control related settings"); | "dctcp congestion control related settings"); | ||||
SYSCTL_PROC(_net_inet_tcp_cc_dctcp, OID_AUTO, alpha, | SYSCTL_PROC(_net_inet_tcp_cc_dctcp, OID_AUTO, alpha, | ||||
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, &VNET_NAME(dctcp_alpha), 0, | CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, &VNET_NAME(dctcp_alpha), 0, | ||||
&dctcp_alpha_handler, | &dctcp_alpha_handler, | ||||
"IU", "dctcp alpha parameter"); | "IU", "dctcp alpha parameter at start of session"); | ||||
SYSCTL_PROC(_net_inet_tcp_cc_dctcp, OID_AUTO, shift_g, | SYSCTL_PROC(_net_inet_tcp_cc_dctcp, OID_AUTO, shift_g, | ||||
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, &VNET_NAME(dctcp_shift_g), 4, | CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, &VNET_NAME(dctcp_shift_g), 4, | ||||
&dctcp_shift_g_handler, | &dctcp_shift_g_handler, | ||||
"IU", "dctcp shift parameter"); | "IU", "dctcp shift parameter"); | ||||
SYSCTL_PROC(_net_inet_tcp_cc_dctcp, OID_AUTO, slowstart, | SYSCTL_PROC(_net_inet_tcp_cc_dctcp, OID_AUTO, slowstart, | ||||
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, &VNET_NAME(dctcp_slowstart), 0, | CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, &VNET_NAME(dctcp_slowstart), 0, | ||||
&dctcp_slowstart_handler, | &dctcp_slowstart_handler, | ||||
"IU", "half CWND reduction after the first slow start"); | "IU", "half CWND reduction after the first slow start"); | ||||
DECLARE_CC_MODULE(dctcp, &dctcp_cc_algo); | DECLARE_CC_MODULE(dctcp, &dctcp_cc_algo); |
Please add parentheses around the expression.