Page MenuHomeFreeBSD

D59454.diff
No OneTemporary

D59454.diff

diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -3620,9 +3620,7 @@
INP_WLOCK_ASSERT(tptoinpcb(tp));
- TCPSTAT_INC(tcps_rttupdated);
- if (tp->t_rttupdated < UCHAR_MAX)
- tp->t_rttupdated++;
+ tcp_rttupdated(tp);
#ifdef STATS
stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT,
imax(0, rtt * 1000 / hz));
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -6352,9 +6352,7 @@
tp->t_srtt = rtt_ticks << TCP_RTT_SHIFT;
tp->t_rttvar = rtt_ticks << (TCP_RTTVAR_SHIFT - 1);
}
- KMOD_TCPSTAT_INC(tcps_rttupdated);
- if (tp->t_rttupdated < UCHAR_MAX)
- tp->t_rttupdated++;
+ tcp_rttupdated(tp);
#ifdef STATS
stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, imax(0, rtt_ticks));
#endif
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -8618,9 +8618,7 @@
tp->t_rttvar = rtt >> 1;
}
rack->rc_srtt_measure_made = 1;
- KMOD_TCPSTAT_INC(tcps_rttupdated);
- if (tp->t_rttupdated < UCHAR_MAX)
- tp->t_rttupdated++;
+ tcp_rttupdated(tp);
#ifdef STATS
if (rack_stats_gets_ms_rtt == 0) {
/* Send in the microsecond rtt used for rxt timeout purposes */
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2407,14 +2407,9 @@
void
tcp_discardcb(struct tcpcb *tp)
{
- struct inpcb *inp = tptoinpcb(tp);
- struct socket *so = tptosocket(tp);
struct mbuf *m;
-#ifdef INET6
- bool isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
-#endif
- INP_WLOCK_ASSERT(inp);
+ INP_WLOCK_ASSERT(tptoinpcb(tp));
MPASS(!callout_active(&tp->t_callout));
MPASS(TAILQ_EMPTY(&tp->snd_holes));
@@ -2463,61 +2458,7 @@
#ifdef TCP_BLACKBOX
tcp_log_tcpcbfini(tp);
#endif
-
- /*
- * If we got enough samples through the srtt filter,
- * save the rtt and rttvar in the routing entry.
- * 'Enough' is arbitrarily defined as 4 rtt samples.
- * 4 samples is enough for the srtt filter to converge
- * to within enough % of the correct value; fewer samples
- * and we could save a bogus rtt. The danger is not high
- * as tcp quickly recovers from everything.
- * XXX: Works very well but needs some more statistics!
- *
- * XXXRRS: Updating must be after the stack fini() since
- * that may be converting some internal representation of
- * say srtt etc into the general one used by other stacks.
- */
- if (tp->t_rttupdated >= 4) {
- uint32_t ssthresh;
-
- /*
- * Update the ssthresh always when the conditions below
- * are satisfied. This gives us better new start value
- * for the congestion avoidance for new connections.
- * ssthresh is only set if packet loss occurred on a session.
- */
- ssthresh = tp->snd_ssthresh;
- if (ssthresh != 0 && ssthresh < so->so_snd.sb_hiwat / 2) {
- /*
- * convert the limit from user data bytes to
- * packets then to packet data bytes.
- */
- ssthresh = (ssthresh + tp->t_maxseg / 2) / tp->t_maxseg;
- if (ssthresh < 2)
- ssthresh = 2;
- ssthresh *= (tp->t_maxseg +
-#ifdef INET6
- (isipv6 ? sizeof (struct ip6_hdr) +
- sizeof (struct tcphdr) :
-#endif
- sizeof (struct tcpiphdr)
-#ifdef INET6
- )
-#endif
- );
- } else
- ssthresh = 0;
- tcp_hc_update(&inp->inp_inc, &(struct tcp_hc_metrics){
- .hc_ssthresh = ssthresh,
- .hc_rtt = tp->t_srtt,
- .hc_rttvar = tp->t_rttvar,
- .hc_cwnd = tp->snd_cwnd,
- .hc_sendpipe = so->so_snd.sb_hiwat,
- .hc_recvpipe = so->so_rcv.sb_hiwat,
- });
- }
-
+ tcp_rttupdated(tp);
refcount_release(&tp->t_fb->tfb_refcnt);
}
@@ -2575,6 +2516,77 @@
return (tp);
}
+void
+tcp_rttupdated(struct tcpcb *tp)
+{
+ const struct inpcb *inp = tptoinpcb(tp);
+ const struct socket *so = tptosocket(tp);
+#ifdef INET6
+ bool isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
+#endif
+ uint32_t ssthresh;
+
+ INP_WLOCK_ASSERT(tptoinpcb(tp));
+
+ TCPSTAT_INC(tcps_rttupdated);
+
+ /*
+ * If we got enough samples through the srtt filter,
+ * save the rtt and rttvar in the routing entry.
+ * 'Enough' is arbitrarily defined as 4 rtt samples.
+ * 4 samples is enough for the srtt filter to converge
+ * to within enough % of the correct value; fewer samples
+ * and we could save a bogus rtt. The danger is not high
+ * as tcp quickly recovers from everything.
+ *
+ * XXXAO 2003: Works very well but needs some more statistics!
+ * XXXGL: shouldn't we reset to UCHAR_MAX/2 on reaching UCHAR_MAX?
+ * Or just extend it to at least 16-bit?
+ */
+ if (__predict_false(tp->t_rttupdated == UCHAR_MAX))
+ return;
+
+ if (tp->t_state == TCPS_ESTABLISHED && (++tp->t_rttupdated & 3) != 0)
+ return;
+
+ /*
+ * Update the ssthresh always when the conditions below
+ * are satisfied. This gives us better new start value
+ * for the congestion avoidance for new connections.
+ * ssthresh is only set if packet loss occurred on a session.
+ */
+ ssthresh = tp->snd_ssthresh;
+ if (ssthresh != 0 && ssthresh < so->so_snd.sb_hiwat / 2) {
+ /*
+ * convert the limit from user data bytes to
+ * packets then to packet data bytes.
+ */
+ ssthresh = (ssthresh + tp->t_maxseg / 2) / tp->t_maxseg;
+ if (ssthresh < 2)
+ ssthresh = 2;
+ ssthresh *= (tp->t_maxseg +
+#ifdef INET6
+ (isipv6 ? sizeof (struct ip6_hdr) +
+ sizeof (struct tcphdr) :
+#endif
+ sizeof (struct tcpiphdr)
+#ifdef INET6
+ )
+#endif
+ );
+ } else
+ ssthresh = 0;
+
+ tcp_hc_update(&inp->inp_inc, &(struct tcp_hc_metrics){
+ .hc_ssthresh = ssthresh,
+ .hc_rtt = tp->t_srtt,
+ .hc_rttvar = tp->t_rttvar,
+ .hc_cwnd = tp->snd_cwnd,
+ .hc_sendpipe = so->so_snd.sb_hiwat,
+ .hc_recvpipe = so->so_rcv.sb_hiwat,
+ });
+};
+
/*
* Notify a tcp user of an asynchronous error;
* store error as soft error, but wake up user
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1526,6 +1526,7 @@
uint32_t tcp_hc_getmtu(const struct in_conninfo *);
void tcp_hc_updatemtu(const struct in_conninfo *, uint32_t);
void tcp_hc_update(const struct in_conninfo *, struct tcp_hc_metrics *);
+void tcp_rttupdated(struct tcpcb *);
void cc_after_idle(struct tcpcb *tp);
extern struct protosw tcp_protosw; /* shared for TOE */

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 7, 12:27 AM (7 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38440925
Default Alt Text
D59454.diff (6 KB)

Event Timeline