Fix delayed ACK generation for DCTCP.

Submitted by:		Richard Scheffenegger
Reviewed by:		chengc@netapp.com, rgrimes@, tuexen@
Differential Revision:	https://reviews.freebsd.org/D22644
This commit is contained in:
Michael Tuexen 2019-12-31 16:15:47 +00:00
parent 0c80ec6dfa
commit e11c9783e1
2 changed files with 21 additions and 27 deletions

View File

@ -318,46 +318,43 @@ dctcp_post_recovery(struct cc_var *ccv)
}
/*
* Execute an additional ECN processing using ECN field in IP header and the CWR
* bit in TCP header.
*
* delay_ack == 0 - Delayed ACK disabled
* delay_ack == 1 - Delayed ACK enabled
* Execute an additional ECN processing using ECN field in IP header
* and the CWR bit in TCP header.
*/
static void
dctcp_ecnpkt_handler(struct cc_var *ccv)
{
struct dctcp *dctcp_data;
uint32_t ccflag;
int delay_ack;
int acknow;
dctcp_data = ccv->cc_data;
ccflag = ccv->flags;
delay_ack = 1;
acknow = 0;
/*
* DCTCP responds with an ACK immediately when the CE state
* in between this segment and the last segment has changed.
*/
if (ccflag & CCF_IPHDR_CE) {
if (!dctcp_data->ce_prev && (ccflag & CCF_DELACK))
delay_ack = 0;
dctcp_data->ce_prev = 1;
CCV(ccv, t_flags2) |= TF2_ECN_SND_ECE;
if (!dctcp_data->ce_prev) {
acknow = 1;
dctcp_data->ce_prev = 1;
CCV(ccv, t_flags2) |= TF2_ECN_SND_ECE;
}
} else {
if (dctcp_data->ce_prev && (ccflag & CCF_DELACK))
delay_ack = 0;
dctcp_data->ce_prev = 0;
CCV(ccv, t_flags2) &= ~TF2_ECN_SND_ECE;
if (dctcp_data->ce_prev) {
acknow = 1;
dctcp_data->ce_prev = 0;
CCV(ccv, t_flags2) &= ~TF2_ECN_SND_ECE;
}
}
/* DCTCP sets delayed ack when this segment sets the CWR flag. */
if ((ccflag & CCF_DELACK) && (ccflag & CCF_TCPHDR_CWR))
delay_ack = 1;
if (delay_ack == 0)
if ((acknow) || (ccflag & CCF_TCPHDR_CWR)) {
ccv->flags |= CCF_ACKNOW;
} else {
ccv->flags &= ~CCF_ACKNOW;
}
}
/*

View File

@ -538,15 +538,12 @@ cc_ecnpkt_handler(struct tcpcb *tp, struct tcphdr *th, uint8_t iptos)
else
tp->ccv->flags &= ~CCF_TCPHDR_CWR;
if (tp->t_flags & TF_DELACK)
tp->ccv->flags |= CCF_DELACK;
else
tp->ccv->flags &= ~CCF_DELACK;
CC_ALGO(tp)->ecnpkt_handler(tp->ccv);
if (tp->ccv->flags & CCF_ACKNOW)
if (tp->ccv->flags & CCF_ACKNOW) {
tcp_timer_activate(tp, TT_DELACK, tcp_delacktime);
tp->t_flags |= TF_ACKNOW;
}
}
}