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
This commit is contained in:
parent
03f33e912d
commit
a26fef3a21
@ -233,23 +233,28 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
|
|||||||
* when the zone is exhausted. Otherwise we may get stuck.
|
* when the zone is exhausted. Otherwise we may get stuck.
|
||||||
*/
|
*/
|
||||||
te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT);
|
te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT);
|
||||||
if (te == NULL && th->th_seq != tp->rcv_nxt) {
|
if (te == NULL) {
|
||||||
TCPSTAT_INC(tcps_rcvmemdrop);
|
if (th->th_seq != tp->rcv_nxt) {
|
||||||
m_freem(m);
|
TCPSTAT_INC(tcps_rcvmemdrop);
|
||||||
*tlenp = 0;
|
m_freem(m);
|
||||||
if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
|
*tlenp = 0;
|
||||||
log(LOG_DEBUG, "%s; %s: global zone limit reached, "
|
if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL,
|
||||||
"segment dropped\n", s, __func__);
|
NULL))) {
|
||||||
free(s, M_TCPLOG);
|
log(LOG_DEBUG, "%s; %s: global zone limit "
|
||||||
}
|
"reached, segment dropped\n", s, __func__);
|
||||||
return (0);
|
free(s, M_TCPLOG);
|
||||||
} else if (th->th_seq == tp->rcv_nxt) {
|
}
|
||||||
bzero(&tqs, sizeof(struct tseg_qent));
|
return (0);
|
||||||
te = &tqs;
|
} else {
|
||||||
if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
|
bzero(&tqs, sizeof(struct tseg_qent));
|
||||||
log(LOG_DEBUG, "%s; %s: global zone limit reached, "
|
te = &tqs;
|
||||||
"using stack for missing segment\n", s, __func__);
|
if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL,
|
||||||
free(s, M_TCPLOG);
|
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++;
|
tp->t_segqlen++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user