svn commit: r228016 - head/sys/netinet

Lawrence Stewart lstewart at FreeBSD.org
Sun Nov 27 02:32:09 UTC 2011


Author: lstewart
Date: Sun Nov 27 02:32:08 2011
New Revision: 228016
URL: http://svn.freebsd.org/changeset/base/228016

Log:
  Plug a TCP reassembly UMA zone leak introduced in r226113 by only using the
  backup stack queue entry when the zone is exhausted, otherwise we leak a zone
  allocation each time we plug a hole in the reassembly queue.
  
  Reported by:	many on freebsd-stable@ (thread: "TCP Reassembly Issues")
  Tested by:	many on freebsd-stable@ (thread: "TCP Reassembly Issues")
  Reviewed by:	bz (very brief sanity check)
  MFC after:	3 days

Modified:
  head/sys/netinet/tcp_reass.c

Modified: head/sys/netinet/tcp_reass.c
==============================================================================
--- head/sys/netinet/tcp_reass.c	Sun Nov 27 00:09:59 2011	(r228015)
+++ head/sys/netinet/tcp_reass.c	Sun Nov 27 02:32:08 2011	(r228016)
@@ -233,23 +233,28 @@ tcp_reass(struct tcpcb *tp, struct tcphd
 	 * when the zone is exhausted. Otherwise we may get stuck.
 	 */
 	te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT);
-	if (te == NULL && th->th_seq != tp->rcv_nxt) {
-		TCPSTAT_INC(tcps_rcvmemdrop);
-		m_freem(m);
-		*tlenp = 0;
-		if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
-			log(LOG_DEBUG, "%s; %s: global zone limit reached, "
-			    "segment dropped\n", s, __func__);
-			free(s, M_TCPLOG);
-		}
-		return (0);
-	} else if (th->th_seq == tp->rcv_nxt) {
-		bzero(&tqs, sizeof(struct tseg_qent));
-		te = &tqs;
-		if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
-			log(LOG_DEBUG, "%s; %s: global zone limit reached, "
-			    "using stack for missing segment\n", s, __func__);
-			free(s, M_TCPLOG);
+	if (te == NULL) {
+		if (th->th_seq != tp->rcv_nxt) {
+			TCPSTAT_INC(tcps_rcvmemdrop);
+			m_freem(m);
+			*tlenp = 0;
+			if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL,
+			    NULL))) {
+				log(LOG_DEBUG, "%s; %s: global zone limit "
+				    "reached, segment dropped\n", s, __func__);
+				free(s, M_TCPLOG);
+			}
+			return (0);
+		} else {
+			bzero(&tqs, sizeof(struct tseg_qent));
+			te = &tqs;
+			if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL,
+			    NULL))) {
+				log(LOG_DEBUG,
+				    "%s; %s: global zone limit reached, using "
+				    "stack for missing segment\n", s, __func__);
+				free(s, M_TCPLOG);
+			}
 		}
 	}
 	tp->t_segqlen++;


More information about the svn-src-all mailing list