Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F95780557
D32966.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D32966.diff
View Options
Index: sys/netinet/tcp_subr.c
===================================================================
--- sys/netinet/tcp_subr.c
+++ sys/netinet/tcp_subr.c
@@ -2384,11 +2384,6 @@
tcp_discardcb(struct tcpcb *tp)
{
struct inpcb *inp = tp->t_inpcb;
- struct socket *so = inp->inp_socket;
-#ifdef INET6
- int isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
-#endif /* INET6 */
- int released __unused;
INP_WLOCK_ASSERT(inp);
@@ -2450,121 +2445,100 @@
CC_ALGO(tp) = NULL;
inp->inp_ppcb = NULL;
if (tp->t_timers->tt_draincnt == 0) {
- /* We own the last reference on tcpcb, let's free it. */
+ bool released __diagused;
+
+ released = tcp_freecb(tp);
+ KASSERT(!released, ("%s: inp %p should not have been released "
+ "here", __func__, inp));
+ }
+}
+
+bool
+tcp_freecb(struct tcpcb *tp)
+{
+ struct inpcb *inp = tp->t_inpcb;
+ struct socket *so = inp->inp_socket;
+#ifdef INET6
+ bool isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
+#endif
+
+ INP_WLOCK_ASSERT(inp);
+ MPASS(tp->t_timers->tt_draincnt == 0);
+
+ /* We own the last reference on tcpcb, let's free it. */
#ifdef TCP_BLACKBOX
- tcp_log_tcpcbfini(tp);
+ tcp_log_tcpcbfini(tp);
#endif
- TCPSTATES_DEC(tp->t_state);
- if (tp->t_fb->tfb_tcp_fb_fini)
- (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
+ TCPSTATES_DEC(tp->t_state);
+ if (tp->t_fb->tfb_tcp_fb_fini)
+ (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
+ /*
+ * 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.
+ * Lets also at least protect against the so being NULL
+ * as RW stated below.
+ */
+ if ((tp->t_rttupdated >= 4) && (so != NULL)) {
+ struct hc_metrics_lite metrics;
+ uint32_t ssthresh;
+
+ bzero(&metrics, sizeof(metrics));
/*
- * 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!
+ * 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.
*
- * 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.
- * Lets also at least protect against the so being NULL
- * as RW stated below.
+ * XXXRW: 'so' may be NULL here, and/or socket buffer may be
+ * being torn down. Ideally this code would not use 'so'.
*/
- if ((tp->t_rttupdated >= 4) && (so != NULL)) {
- struct hc_metrics_lite metrics;
- uint32_t ssthresh;
-
- bzero(&metrics, sizeof(metrics));
+ ssthresh = tp->snd_ssthresh;
+ if (ssthresh != 0 && ssthresh < so->so_snd.sb_hiwat / 2) {
/*
- * 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.
- *
- * XXXRW: 'so' may be NULL here, and/or socket buffer may be
- * being torn down. Ideally this code would not use 'so'.
+ * convert the limit from user data bytes to
+ * packets then to packet data bytes.
*/
- 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 +
+ 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) :
+ (isipv6 ? sizeof (struct ip6_hdr) +
+ sizeof (struct tcphdr) :
#endif
- sizeof (struct tcpiphdr)
+ sizeof (struct tcpiphdr)
#ifdef INET6
- )
+ )
#endif
- );
- } else
- ssthresh = 0;
- metrics.rmx_ssthresh = ssthresh;
+ );
+ } else
+ ssthresh = 0;
+ metrics.rmx_ssthresh = ssthresh;
- metrics.rmx_rtt = tp->t_srtt;
- metrics.rmx_rttvar = tp->t_rttvar;
- metrics.rmx_cwnd = tp->snd_cwnd;
- metrics.rmx_sendpipe = 0;
- metrics.rmx_recvpipe = 0;
+ metrics.rmx_rtt = tp->t_srtt;
+ metrics.rmx_rttvar = tp->t_rttvar;
+ metrics.rmx_cwnd = tp->snd_cwnd;
+ metrics.rmx_sendpipe = 0;
+ metrics.rmx_recvpipe = 0;
- tcp_hc_update(&inp->inp_inc, &metrics);
- }
- refcount_release(&tp->t_fb->tfb_refcnt);
- tp->t_inpcb = NULL;
- uma_zfree(V_tcpcb_zone, tp);
- released = in_pcbrele_wlocked(inp);
- KASSERT(!released, ("%s: inp %p should not have been released "
- "here", __func__, inp));
+ tcp_hc_update(&inp->inp_inc, &metrics);
}
-}
-void
-tcp_timer_discard(void *ptp)
-{
- struct inpcb *inp;
- struct tcpcb *tp;
- struct epoch_tracker et;
+ refcount_release(&tp->t_fb->tfb_refcnt);
+ uma_zfree(V_tcpcb_zone, tp);
- tp = (struct tcpcb *)ptp;
- CURVNET_SET(tp->t_vnet);
- NET_EPOCH_ENTER(et);
- inp = tp->t_inpcb;
- KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL",
- __func__, tp));
- INP_WLOCK(inp);
- KASSERT((tp->t_timers->tt_flags & TT_STOPPED) != 0,
- ("%s: tcpcb has to be stopped here", __func__));
- tp->t_timers->tt_draincnt--;
- if (tp->t_timers->tt_draincnt == 0) {
- /* We own the last reference on this tcpcb, let's free it. */
-#ifdef TCP_BLACKBOX
- tcp_log_tcpcbfini(tp);
-#endif
- TCPSTATES_DEC(tp->t_state);
- if (tp->t_fb->tfb_tcp_fb_fini)
- (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
- refcount_release(&tp->t_fb->tfb_refcnt);
- tp->t_inpcb = NULL;
- uma_zfree(V_tcpcb_zone, tp);
- if (in_pcbrele_wlocked(inp)) {
- NET_EPOCH_EXIT(et);
- CURVNET_RESTORE();
- return;
- }
- }
- INP_WUNLOCK(inp);
- NET_EPOCH_EXIT(et);
- CURVNET_RESTORE();
+ return (in_pcbrele_wlocked(inp));
}
/*
Index: sys/netinet/tcp_timer.h
===================================================================
--- sys/netinet/tcp_timer.h
+++ sys/netinet/tcp_timer.h
@@ -217,7 +217,6 @@
void tcp_timer_init(void);
void tcp_timer_2msl(void *xtp);
-void tcp_timer_discard(void *);
struct tcptw *
tcp_tw_2msl_scan(int reuse); /* XXX temporary? */
void tcp_timer_keep(void *xtp);
Index: sys/netinet/tcp_timer.c
===================================================================
--- sys/netinet/tcp_timer.c
+++ sys/netinet/tcp_timer.c
@@ -1075,6 +1075,29 @@
}
}
+static void
+tcp_timer_discard(void *ptp)
+{
+ struct inpcb *inp;
+ struct tcpcb *tp;
+ struct epoch_tracker et;
+
+ tp = (struct tcpcb *)ptp;
+ CURVNET_SET(tp->t_vnet);
+ NET_EPOCH_ENTER(et);
+ inp = tp->t_inpcb;
+ KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL",
+ __func__, tp));
+ INP_WLOCK(inp);
+ KASSERT((tp->t_timers->tt_flags & TT_STOPPED) != 0,
+ ("%s: tcpcb has to be stopped here", __func__));
+ if (--tp->t_timers->tt_draincnt > 0 ||
+ tcp_freecb(tp) == false)
+ INP_WUNLOCK(inp);
+ NET_EPOCH_EXIT(et);
+ CURVNET_RESTORE();
+}
+
void
tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
{
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -967,6 +967,7 @@
struct tcpcb *
tcp_close(struct tcpcb *);
void tcp_discardcb(struct tcpcb *);
+bool tcp_freecb(struct tcpcb *);
void tcp_twstart(struct tcpcb *);
void tcp_twclose(struct tcptw *, int);
void tcp_ctlinput(int, struct sockaddr *, void *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Sep 23, 2:31 PM (21 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12551221
Default Alt Text
D32966.diff (8 KB)
Attached To
Mode
D32966: Add tcp_freecb() - single place to free tcpcb.
Attached
Detach File
Event Timeline
Log In to Comment