Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F170682932
D59454.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D59454.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D59454: tcp: provide tcp_rttupdated() and call it periodically
Attached
Detach File
Event Timeline
Log In to Comment