git: c349e881cf52 - main - rack, bbr: cleanup ack throttling
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 07 Aug 2024 18:28:26 UTC
The branch main has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=c349e881cf52e51ab063c098bd9b99db487b6377 commit c349e881cf52e51ab063c098bd9b99db487b6377 Author: Michael Tuexen <tuexen@FreeBSD.org> AuthorDate: 2024-08-07 18:25:53 +0000 Commit: Michael Tuexen <tuexen@FreeBSD.org> CommitDate: 2024-08-07 18:25:53 +0000 rack, bbr: cleanup ack throttling Use the variable in the TCPCB, not the one in the stack specific data structure. This simplifies the code and brings the functionality to BBR without any change. Reviewed by: Peter Lei, cc MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46068 --- sys/netinet/tcp_stacks/rack.c | 77 ++++++---------------------- sys/netinet/tcp_stacks/rack_bbr_common.c | 88 +++++++++----------------------- sys/netinet/tcp_stacks/rack_bbr_common.h | 19 +++---- sys/netinet/tcp_stacks/tcp_rack.h | 2 - 4 files changed, 47 insertions(+), 139 deletions(-) diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index ec0c6f500946..9749574fe037 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -12504,17 +12504,13 @@ rack_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so, else TCPSTAT_INC(tcps_rcvacktooold); /* Send challenge ACK. */ - __ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt); + ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val); rack->r_wanted_output = 1; return (1); } } if (SEQ_GT(th->th_ack, tp->snd_max)) { - __ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt); + ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val); rack->r_wanted_output = 1; return (1); } @@ -13795,9 +13791,7 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) - return (__ctf_process_rst(m, th, so, tp, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)); + return (ctf_process_rst(m, th, so, tp)); if ((thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->snd_una) || SEQ_GT(th->th_ack, tp->snd_max))) { @@ -13852,9 +13846,7 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } - if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)) { + if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* @@ -14043,9 +14035,7 @@ rack_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so, if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) - return (__ctf_process_rst(m, th, so, tp, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)); + return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in @@ -14064,9 +14054,7 @@ rack_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so, if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } - if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)) { + if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* @@ -14139,15 +14127,11 @@ rack_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so, { int32_t ret_val = 0; int32_t orig_tlen = tlen; - struct tcp_rack *rack; - rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) - return (__ctf_process_rst(m, th, so, tp, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)); + return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. @@ -14165,9 +14149,7 @@ rack_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so, if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } - if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)) { + if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* @@ -14269,16 +14251,12 @@ rack_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so, int32_t ret_val = 0; int32_t orig_tlen = tlen; int32_t ourfinisacked = 0; - struct tcp_rack *rack; - rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) - return (__ctf_process_rst(m, th, so, tp, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)); + return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. @@ -14296,9 +14274,7 @@ rack_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so, if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } - if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)) { + if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* @@ -14397,16 +14373,12 @@ rack_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so, int32_t ret_val = 0; int32_t orig_tlen = tlen; int32_t ourfinisacked = 0; - struct tcp_rack *rack; - rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) - return (__ctf_process_rst(m, th, so, tp, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)); + return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. @@ -14424,9 +14396,7 @@ rack_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so, if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } - if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)) { + if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* @@ -14504,16 +14474,12 @@ rack_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so, int32_t ret_val = 0; int32_t orig_tlen; int32_t ourfinisacked = 0; - struct tcp_rack *rack; - rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) - return (__ctf_process_rst(m, th, so, tp, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)); + return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. @@ -14532,9 +14498,7 @@ rack_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so, return (ret_val); } orig_tlen = tlen; - if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)) { + if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* @@ -14612,17 +14576,13 @@ rack_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so, int32_t ret_val = 0; int32_t orig_tlen = tlen; int32_t ourfinisacked = 0; - struct tcp_rack *rack; - rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); /* Reset receive buffer auto scaling when not in bulk receive mode. */ if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) - return (__ctf_process_rst(m, th, so, tp, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)); + return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. @@ -14640,9 +14600,7 @@ rack_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so, if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } - if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, - &rack->r_ctl.challenge_ack_ts, - &rack->r_ctl.challenge_ack_cnt)) { + if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* @@ -15547,7 +15505,6 @@ rack_init(struct tcpcb *tp, void **ptr) rack->r_ctl.rc_lower_rtt_us_cts = us_cts; rack->r_ctl.rc_time_of_last_probertt = us_cts; rack->r_ctl.rc_went_idle_time = us_cts; - rack->r_ctl.challenge_ack_ts = tcp_ts_getticks() - (V_tcp_ack_war_time_window + 1); rack->r_ctl.rc_time_probertt_starts = 0; rack->r_ctl.gp_rnd_thresh = rack_rnd_cnt_req & 0xff; @@ -16702,7 +16659,7 @@ rack_do_compressed_ack_processing(struct tcpcb *tp, struct socket *so, struct mb * ack is beyond the largest seq we sent. */ if ((tp->t_flags & TF_ACKNOW) == 0) { - ctf_ack_war_checks(tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt); + ctf_ack_war_checks(tp); if (tp->t_flags && TF_ACKNOW) rack->r_wanted_output = 1; } diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.c b/sys/netinet/tcp_stacks/rack_bbr_common.c index b218f449475f..150298f8413f 100644 --- a/sys/netinet/tcp_stacks/rack_bbr_common.c +++ b/sys/netinet/tcp_stacks/rack_bbr_common.c @@ -532,28 +532,19 @@ ctf_do_dropwithreset(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, } void -ctf_ack_war_checks(struct tcpcb *tp, uint32_t *ts, uint32_t *cnt) +ctf_ack_war_checks(struct tcpcb *tp) { - if ((ts != NULL) && (cnt != NULL) && - (V_tcp_ack_war_time_window > 0) && - (V_tcp_ack_war_cnt > 0)) { - /* We are possibly doing ack war prevention */ - uint32_t cts; - - /* - * We use a msec tick here which gives us - * roughly 49 days. We don't need the - * precision of a microsecond timestamp which - * would only give us hours. - */ - cts = tcp_ts_getticks(); - if (TSTMP_LT((*ts), cts)) { - /* Timestamp is in the past */ - *cnt = 0; - *ts = (cts + V_tcp_ack_war_time_window); + sbintime_t now; + + if ((V_tcp_ack_war_time_window > 0) && (V_tcp_ack_war_cnt > 0)) { + now = getsbinuptime(); + if (tp->t_challenge_ack_end < now) { + tp->t_challenge_ack_cnt = 0; + tp->t_challenge_ack_end = now + + V_tcp_ack_war_time_window * SBT_1MS; } - if (*cnt < V_tcp_ack_war_cnt) { - *cnt = (*cnt + 1); + if (tp->t_challenge_ack_cnt < V_tcp_ack_war_cnt) { + tp->t_challenge_ack_cnt++; tp->t_flags |= TF_ACKNOW; } else tp->t_flags &= ~TF_ACKNOW; @@ -568,10 +559,9 @@ ctf_ack_war_checks(struct tcpcb *tp, uint32_t *ts, uint32_t *cnt) * TCB is still valid and locked. */ int -_ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, - struct tcpcb *tp, int32_t *tlenp, - int32_t *thf, int32_t *drop_hdrlen, int32_t *ret_val, - uint32_t *ts, uint32_t *cnt) +ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, + struct tcpcb *tp, int32_t *tlenp, + int32_t *thf, int32_t *drop_hdrlen, int32_t *ret_val) { int32_t todrop; int32_t thflags; @@ -605,7 +595,7 @@ _ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, * Send an ACK to resynchronize and drop any data. * But keep on processing for RST or ACK. */ - ctf_ack_war_checks(tp, ts, cnt); + ctf_ack_war_checks(tp); todrop = tlen; KMOD_TCPSTAT_INC(tcps_rcvduppack); KMOD_TCPSTAT_ADD(tcps_rcvdupbyte, todrop); @@ -621,7 +611,7 @@ _ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, * ACK now, as the next in-sequence segment * will clear the DSACK block again */ - ctf_ack_war_checks(tp, ts, cnt); + ctf_ack_war_checks(tp); if (tp->t_flags & TF_ACKNOW) tcp_update_sack_list(tp, th->th_seq, th->th_seq + todrop); @@ -653,10 +643,10 @@ _ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, * ack. */ if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { - ctf_ack_war_checks(tp, ts, cnt); + ctf_ack_war_checks(tp); KMOD_TCPSTAT_INC(tcps_rcvwinprobe); } else { - __ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val, ts, cnt); + ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val); return (1); } } else @@ -677,7 +667,7 @@ _ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, * and valid. */ void -__ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t thflags, int32_t tlen, int32_t *ret_val, uint32_t *ts, uint32_t *cnt) +ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t thflags, int32_t tlen, int32_t *ret_val) { /* * Generate an ACK dropping incoming segment if it occupies sequence @@ -701,7 +691,7 @@ __ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32 return; } else *ret_val = 0; - ctf_ack_war_checks(tp, ts, cnt); + ctf_ack_war_checks(tp); if (m) m_freem(m); } @@ -720,8 +710,8 @@ ctf_do_drop(struct mbuf *m, struct tcpcb *tp) } int -__ctf_process_rst(struct mbuf *m, struct tcphdr *th, struct socket *so, - struct tcpcb *tp, uint32_t *ts, uint32_t *cnt) +ctf_process_rst(struct mbuf *m, struct tcphdr *th, struct socket *so, + struct tcpcb *tp) { /* * RFC5961 Section 3.2 @@ -768,40 +758,8 @@ __ctf_process_rst(struct mbuf *m, struct tcphdr *th, struct socket *so, dropped = 1; ctf_do_drop(m, tp); } else { - int send_challenge; - KMOD_TCPSTAT_INC(tcps_badrst); - if ((ts != NULL) && (cnt != NULL) && - (V_tcp_ack_war_time_window > 0) && - (V_tcp_ack_war_cnt > 0)) { - /* We are possibly preventing an ack-rst war prevention */ - uint32_t cts; - - /* - * We use a msec tick here which gives us - * roughly 49 days. We don't need the - * precision of a microsecond timestamp which - * would only give us hours. - */ - cts = tcp_ts_getticks(); - if (TSTMP_LT((*ts), cts)) { - /* Timestamp is in the past */ - *cnt = 0; - *ts = (cts + V_tcp_ack_war_time_window); - } - if (*cnt < V_tcp_ack_war_cnt) { - *cnt = (*cnt + 1); - send_challenge = 1; - } else - send_challenge = 0; - } else - send_challenge = 1; - if (send_challenge) { - /* Send challenge ACK. */ - tcp_respond(tp, mtod(m, void *), th, m, - tp->rcv_nxt, tp->snd_nxt, TH_ACK); - tp->last_ack_sent = tp->rcv_nxt; - } + tcp_send_challenge_ack(tp, th, m); } } else { m_freem(m); diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.h b/sys/netinet/tcp_stacks/rack_bbr_common.h index 9e5fbe675a3a..6a8a056d89b0 100644 --- a/sys/netinet/tcp_stacks/rack_bbr_common.h +++ b/sys/netinet/tcp_stacks/rack_bbr_common.h @@ -89,19 +89,15 @@ int ctf_do_queued_segments(struct tcpcb *tp, int have_pkt); uint32_t ctf_outstanding(struct tcpcb *tp); uint32_t ctf_flight_size(struct tcpcb *tp, uint32_t rc_sacked); int -_ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, +ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t *tlenp, - int32_t *thf, int32_t *drop_hdrlen, int32_t *ret_val, - uint32_t *ts, uint32_t *cnt); -void ctf_ack_war_checks(struct tcpcb *tp, uint32_t *ts, uint32_t *cnt); -#define ctf_drop_checks(a, b, c, d, e, f, g, h) _ctf_drop_checks(a, b, c, d, e, f, g, h, NULL, NULL) + int32_t *thf, int32_t *drop_hdrlen, int32_t *ret_val); +void ctf_ack_war_checks(struct tcpcb *tp); void -__ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, +ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t thflags, int32_t tlen, - int32_t *ret_val, uint32_t *ts, uint32_t *cnt); - -#define ctf_do_dropafterack(a, b, c, d, e, f) __ctf_do_dropafterack(a, b, c, d, e, f, NULL, NULL) + int32_t *ret_val); void ctf_do_dropwithreset(struct mbuf *m, struct tcpcb *tp, @@ -110,9 +106,8 @@ void ctf_do_drop(struct mbuf *m, struct tcpcb *tp); int -__ctf_process_rst(struct mbuf *m, struct tcphdr *th, - struct socket *so, struct tcpcb *tp, uint32_t *ts, uint32_t *cnt); -#define ctf_process_rst(m, t, s, p) __ctf_process_rst(m, t, s, p, NULL, NULL) +ctf_process_rst(struct mbuf *m, struct tcphdr *th, + struct socket *so, struct tcpcb *tp); void ctf_challenge_ack(struct mbuf *m, struct tcphdr *th, diff --git a/sys/netinet/tcp_stacks/tcp_rack.h b/sys/netinet/tcp_stacks/tcp_rack.h index ae766272bf30..a64791a9887b 100644 --- a/sys/netinet/tcp_stacks/tcp_rack.h +++ b/sys/netinet/tcp_stacks/tcp_rack.h @@ -553,8 +553,6 @@ struct rack_control { uint32_t rc_last_timeout_snduna; uint32_t last_tlp_acked_start; uint32_t last_tlp_acked_end; - uint32_t challenge_ack_ts; - uint32_t challenge_ack_cnt; uint32_t rc_min_to; /* Socket option value Lock(a) */ uint32_t rc_pkt_delay; /* Socket option value Lock(a) */ uint32_t persist_lost_ends;