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