From e11c9783e1451f4113af370c21ed6afffd1316d8 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Tue, 31 Dec 2019 16:15:47 +0000 Subject: [PATCH] Fix delayed ACK generation for DCTCP. Submitted by: Richard Scheffenegger Reviewed by: chengc@netapp.com, rgrimes@, tuexen@ Differential Revision: https://reviews.freebsd.org/D22644 --- sys/netinet/cc/cc_dctcp.c | 39 ++++++++++++++++++--------------------- sys/netinet/tcp_input.c | 9 +++------ 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c index 8fa5444fd705..4e143eb45551 100644 --- a/sys/netinet/cc/cc_dctcp.c +++ b/sys/netinet/cc/cc_dctcp.c @@ -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; + } } /* diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index fe4db44ba2c3..f5189c7d36da 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -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; + } } }