Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/cc/cc_dctcp.c
Show First 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | if (CCV(ccv, t_flags) & TF_ECN_PERMIT) { | ||||
if (IN_CONGRECOVERY(CCV(ccv, t_flags))) { | if (IN_CONGRECOVERY(CCV(ccv, t_flags))) { | ||||
EXIT_CONGRECOVERY(CCV(ccv, t_flags)); | EXIT_CONGRECOVERY(CCV(ccv, t_flags)); | ||||
newreno_cc_algo.ack_received(ccv, type); | newreno_cc_algo.ack_received(ccv, type); | ||||
ENTER_CONGRECOVERY(CCV(ccv, t_flags)); | ENTER_CONGRECOVERY(CCV(ccv, t_flags)); | ||||
} else | } else | ||||
newreno_cc_algo.ack_received(ccv, type); | newreno_cc_algo.ack_received(ccv, type); | ||||
if (type == CC_DUPACK) | if (type == CC_DUPACK) | ||||
//XXRMS: todo: use sacked data? | |||||
bytes_acked = CCV(ccv, t_maxseg); | bytes_acked = CCV(ccv, t_maxseg); | ||||
rscheff: remove white space at line126 in the D20550 patch before submission | |||||
rscheffAuthorUnsubmitted Done Inline Actionsrscheff: Leaving whitespace, as that separates different ack types.
using sacked data (CCV(ccv… | |||||
if (type == CC_ACK) | if (type == CC_ACK) | ||||
bytes_acked = ccv->bytes_this_ack; | bytes_acked = ccv->bytes_this_ack; | ||||
/* Update total bytes. */ | /* Update total bytes. */ | ||||
dctcp_data->bytes_total += bytes_acked; | dctcp_data->bytes_total += bytes_acked; | ||||
/* Update total marked bytes. */ | /* Update total marked bytes. */ | ||||
if (dctcp_data->ece_curr) { | if (dctcp_data->ece_curr) { | ||||
//XXRMS: For fluid-model DCTCP, update | |||||
//cwnd here during for RTT fairness | |||||
if (!dctcp_data->ece_prev | if (!dctcp_data->ece_prev | ||||
&& bytes_acked > CCV(ccv, t_maxseg)) { | && bytes_acked > CCV(ccv, t_maxseg)) { | ||||
dctcp_data->bytes_ecn += | dctcp_data->bytes_ecn += | ||||
(bytes_acked - CCV(ccv, t_maxseg)); | (bytes_acked - CCV(ccv, t_maxseg)); | ||||
} else | } else | ||||
dctcp_data->bytes_ecn += bytes_acked; | dctcp_data->bytes_ecn += bytes_acked; | ||||
dctcp_data->ece_prev = 1; | dctcp_data->ece_prev = 1; | ||||
} else { | } else { | ||||
Show All 17 Lines | if (CCV(ccv, t_flags) & TF_ECN_PERMIT) { | ||||
newreno_cc_algo.ack_received(ccv, type); | newreno_cc_algo.ack_received(ccv, type); | ||||
} | } | ||||
static void | static void | ||||
dctcp_after_idle(struct cc_var *ccv) | dctcp_after_idle(struct cc_var *ccv) | ||||
{ | { | ||||
struct dctcp *dctcp_data; | struct dctcp *dctcp_data; | ||||
if (CCV(ccv, t_flags) & TF_ECN_PERMIT) { | |||||
dctcp_data = ccv->cc_data; | dctcp_data = ccv->cc_data; | ||||
/* Initialize internal parameters after idle time */ | /* Initialize internal parameters after idle time */ | ||||
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); | ||||
dctcp_data->alpha = V_dctcp_alpha; | dctcp_data->alpha = V_dctcp_alpha; | ||||
dctcp_data->ece_curr = 0; | dctcp_data->ece_curr = 0; | ||||
dctcp_data->ece_prev = 0; | dctcp_data->ece_prev = 0; | ||||
dctcp_data->num_cong_events = 0; | dctcp_data->num_cong_events = 0; | ||||
} | |||||
dctcp_cc_algo.after_idle = newreno_cc_algo.after_idle; | newreno_cc_algo.after_idle(ccv); | ||||
} | } | ||||
static void | static void | ||||
dctcp_cb_destroy(struct cc_var *ccv) | dctcp_cb_destroy(struct cc_var *ccv) | ||||
{ | { | ||||
free(ccv->cc_data, M_dctcp); | free(ccv->cc_data, M_dctcp); | ||||
} | } | ||||
Show All 34 Lines | |||||
/* | /* | ||||
* Perform any necessary tasks before we enter congestion recovery. | * Perform any necessary tasks before we enter congestion recovery. | ||||
*/ | */ | ||||
static void | static void | ||||
dctcp_cong_signal(struct cc_var *ccv, uint32_t type) | dctcp_cong_signal(struct cc_var *ccv, uint32_t type) | ||||
{ | { | ||||
struct dctcp *dctcp_data; | struct dctcp *dctcp_data; | ||||
u_int win, mss; | u_int cwin, mss; | ||||
if (CCV(ccv, t_flags) & TF_ECN_PERMIT) { | |||||
dctcp_data = ccv->cc_data; | dctcp_data = ccv->cc_data; | ||||
win = CCV(ccv, snd_cwnd); | cwin = CCV(ccv, snd_cwnd); | ||||
mss = CCV(ccv, t_maxseg); | mss = CCV(ccv, t_maxseg); | ||||
switch (type) { | switch (type) { | ||||
case CC_NDUPACK: | case CC_NDUPACK: | ||||
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { | if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { | ||||
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { | if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { | ||||
CCV(ccv, snd_ssthresh) = mss * | CCV(ccv, snd_ssthresh) = | ||||
max(win / 2 / mss, 2); | max(cwin / 2, 2 * mss); | ||||
dctcp_data->num_cong_events++; | dctcp_data->num_cong_events++; | ||||
} else { | } else { | ||||
/* cwnd has already updated as congestion | /* cwnd has already updated as congestion | ||||
* recovery. Reverse cwnd value using | * recovery. Reverse cwnd value using | ||||
* snd_cwnd_prev and recalculate snd_ssthresh | * snd_cwnd_prev and recalculate snd_ssthresh | ||||
*/ | */ | ||||
win = CCV(ccv, snd_cwnd_prev); | cwin = CCV(ccv, snd_cwnd_prev); | ||||
CCV(ccv, snd_ssthresh) = | CCV(ccv, snd_ssthresh) = | ||||
max(win / 2 / mss, 2) * mss; | max(cwin / 2, 2 * mss); | ||||
} | } | ||||
ENTER_RECOVERY(CCV(ccv, t_flags)); | ENTER_RECOVERY(CCV(ccv, t_flags)); | ||||
} | } | ||||
break; | break; | ||||
case CC_ECN: | case CC_ECN: | ||||
/* | /* | ||||
* Save current snd_cwnd when the host encounters both | * Save current snd_cwnd when the host encounters both | ||||
* congestion recovery and fast recovery. | * congestion recovery and fast recovery. | ||||
*/ | */ | ||||
CCV(ccv, snd_cwnd_prev) = win; | CCV(ccv, snd_cwnd_prev) = cwin; | ||||
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { | if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { | ||||
if (V_dctcp_slowstart && | if (V_dctcp_slowstart && | ||||
dctcp_data->num_cong_events++ == 0) { | dctcp_data->num_cong_events++ == 0) { | ||||
CCV(ccv, snd_ssthresh) = | CCV(ccv, snd_ssthresh) = | ||||
mss * max(win / 2 / mss, 2); | max(win / 2, 2 * mss); | ||||
dctcp_data->alpha = MAX_ALPHA_VALUE; | dctcp_data->alpha = MAX_ALPHA_VALUE; | ||||
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); | ||||
} else | } else | ||||
CCV(ccv, snd_ssthresh) = max((win - ((win * | CCV(ccv, snd_ssthresh) = | ||||
dctcp_data->alpha) >> 11)) / mss, 2) * mss; | max((cwin - (((uint64_t)cwin * | ||||
dctcp_data->alpha) >> (DCTCP_SHIFT+1))), | |||||
2 * mss); | |||||
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); | CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); | ||||
ENTER_CONGRECOVERY(CCV(ccv, t_flags)); | ENTER_CONGRECOVERY(CCV(ccv, t_flags)); | ||||
} | } | ||||
dctcp_data->ece_curr = 1; | dctcp_data->ece_curr = 1; | ||||
break; | break; | ||||
case CC_RTO: | case CC_RTO: | ||||
if (CCV(ccv, t_flags) & TF_ECN_PERMIT) { | |||||
CCV(ccv, t_flags) |= TF_ECN_SND_CWR; | CCV(ccv, t_flags) |= TF_ECN_SND_CWR; | ||||
dctcp_update_alpha(ccv); | dctcp_update_alpha(ccv); | ||||
dctcp_data->save_sndnxt += CCV(ccv, t_maxseg); | dctcp_data->save_sndnxt += CCV(ccv, t_maxseg); | ||||
dctcp_data->num_cong_events++; | dctcp_data->num_cong_events++; | ||||
} | |||||
break; | break; | ||||
} | } | ||||
} else | |||||
newreno_cc_algo.newreno_cong_signal(ccv, type); | |||||
Not Done Inline ActionsThis should read newreno_cc_algo.cong_signal(ccv, type); tuexen: This should read
```
newreno_cc_algo.cong_signal(ccv, type);
``` | |||||
} | } | ||||
static void | static void | ||||
dctcp_conn_init(struct cc_var *ccv) | dctcp_conn_init(struct cc_var *ccv) | ||||
{ | { | ||||
struct dctcp *dctcp_data; | struct dctcp *dctcp_data; | ||||
dctcp_data = ccv->cc_data; | dctcp_data = ccv->cc_data; | ||||
if (CCV(ccv, t_flags) & TF_ECN_PERMIT) | if (CCV(ccv, t_flags) & TF_ECN_PERMIT) | ||||
dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); | dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); | ||||
} | } | ||||
/* | /* | ||||
* Perform any necessary tasks before we exit congestion recovery. | * Perform any necessary tasks before we exit congestion recovery. | ||||
*/ | */ | ||||
static void | static void | ||||
dctcp_post_recovery(struct cc_var *ccv) | dctcp_post_recovery(struct cc_var *ccv) | ||||
{ | { | ||||
dctcp_cc_algo.post_recovery = newreno_cc_algo.post_recovery; | newreno_cc_algo.post_recovery(ccv); | ||||
if (CCV(ccv, t_flags) & TF_ECN_PERMIT) | if (CCV(ccv, t_flags) & TF_ECN_PERMIT) | ||||
dctcp_update_alpha(ccv); | dctcp_update_alpha(ccv); | ||||
} | } | ||||
/* | /* | ||||
* Execute an additional ECN processing using ECN field in IP header and the CWR | * Execute an additional ECN processing using ECN field in IP header and the CWR | ||||
* bit in TCP header. | * bit in TCP header. | ||||
Show All 9 Lines | dctcp_ecnpkt_handler(struct cc_var *ccv) | ||||
uint32_t ccflag; | uint32_t ccflag; | ||||
int delay_ack; | int delay_ack; | ||||
dctcp_data = ccv->cc_data; | dctcp_data = ccv->cc_data; | ||||
ccflag = ccv->flags; | ccflag = ccv->flags; | ||||
delay_ack = 1; | delay_ack = 1; | ||||
/* | /* | ||||
* DCTCP responses an ACK immediately when the CE state | * DCTCP responds with an ACK immediately when the CE state | ||||
* in between this segment and the last segment is not same. | * in between this segment and the last segment has changed. | ||||
*/ | */ | ||||
if (ccflag & CCF_IPHDR_CE) { | if (ccflag & CCF_IPHDR_CE) { | ||||
if (!dctcp_data->ce_prev && (ccflag & CCF_DELACK)) | if (!dctcp_data->ce_prev && (ccflag & CCF_DELACK)) | ||||
delay_ack = 0; | delay_ack = 0; | ||||
dctcp_data->ce_prev = 1; | dctcp_data->ce_prev = 1; | ||||
CCV(ccv, t_flags) |= TF_ECN_SND_ECE; | CCV(ccv, t_flags) |= TF_ECN_SND_ECE; | ||||
} else { | } else { | ||||
if (dctcp_data->ce_prev && (ccflag & CCF_DELACK)) | if (dctcp_data->ce_prev && (ccflag & CCF_DELACK)) | ||||
delay_ack = 0; | delay_ack = 0; | ||||
dctcp_data->ce_prev = 0; | dctcp_data->ce_prev = 0; | ||||
CCV(ccv, t_flags) &= ~TF_ECN_SND_ECE; | CCV(ccv, t_flags) &= ~TF_ECN_SND_ECE; | ||||
} | } | ||||
/* DCTCP sets delayed ack when this segment sets the CWR flag. */ | /* DCTCP sets delayed ack when this segment sets the CWR flag. */ | ||||
if ((ccflag & CCF_DELACK) && (ccflag & CCF_TCPHDR_CWR)) | if ((ccflag & CCF_DELACK) && (ccflag & CCF_TCPHDR_CWR)) | ||||
delay_ack = 1; | delay_ack = 1; | ||||
if (delay_ack == 0) | if (delay_ack == 0) | ||||
ccv->flags |= CCF_ACKNOW; | ccv->flags |= CCF_ACKNOW; | ||||
else | |||||
rscheffAuthorUnsubmitted Done Inline ActionsMidorI: remove a change at line353 in the D20550 patch. If I understand correctly, it does not affect performance R: If other parts of the code decided to send out an ACK right away (e.g. leaving zero-window episodes), we should not clear the ACKNOW flag here. rscheff: MidorI: remove a change at line353 in the D20550 patch. If I understand correctly, it does not… | |||||
ccv->flags &= ~CCF_ACKNOW; | |||||
} | } | ||||
/* | /* | ||||
* Update the fraction of marked bytes represented as 'alpha'. | * Update the fraction of marked bytes represented as 'alpha'. | ||||
* Also initialize several internal parameters at the end of this function. | * Also initialize several internal parameters at the end of this function. | ||||
*/ | */ | ||||
static void | static void | ||||
dctcp_update_alpha(struct cc_var *ccv) | dctcp_update_alpha(struct cc_var *ccv) | ||||
▲ Show 20 Lines • Show All 107 Lines • Show Last 20 Lines |
remove white space at line126 in the D20550 patch before submission