Date: Mon, 6 Aug 2018 17:36:58 +0000 (UTC) From: "Jonathan T. Looney" <jtl@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r337384 - in head: share/man/man4 sys/netinet Message-ID: <201808061736.w76Hawt5009582@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jtl Date: Mon Aug 6 17:36:57 2018 New Revision: 337384 URL: https://svnweb.freebsd.org/changeset/base/337384 Log: Address concerns about CPU usage while doing TCP reassembly. Currently, the per-queue limit is a function of the receive buffer size and the MSS. In certain cases (such as connections with large receive buffers), the per-queue segment limit can be quite large. Because we process segments as a linked list, large queues may not perform acceptably. The better long-term solution is to make the queue more efficient. But, in the short-term, we can provide a way for a system administrator to set the maximum queue size. We set the default queue limit to 100. This is an effort to balance performance with a sane resource limit. Depending on their environment, goals, etc., an administrator may choose to modify this limit in either direction. Reviewed by: jhb Approved by: so Security: FreeBSD-SA-18:08.tcp Security: CVE-2018-6922 Modified: head/share/man/man4/tcp.4 head/sys/netinet/tcp_reass.c Modified: head/share/man/man4/tcp.4 ============================================================================== --- head/share/man/man4/tcp.4 Mon Aug 6 17:21:20 2018 (r337383) +++ head/share/man/man4/tcp.4 Mon Aug 6 17:36:57 2018 (r337384) @@ -445,6 +445,20 @@ no reseeding will occur. Reseeding should not be necessary, and will break .Dv TIME_WAIT recycling for a few minutes. +.It Va reass.cursegments +The current total number of segments present in all reassembly queues. +.It Va reass.maxsegments +The maximum limit on the total number of segments across all reassembly +queues. +The limit can be adjusted as a tunable. +.It Va reass.maxqueuelen +The maximum number of segments allowed in each reassembly queue. +By default, the system chooses a limit based on each TCP connection's +receive buffer size and maximum segment size (MSS). +The actual limit applied to a session's reassembly queue will be the lower of +the system-calculated automatic limit and the user-specified +.Va reass.maxqueuelen +limit. .It Va rexmit_min , rexmit_slop Adjust the retransmit timer calculation for .Tn TCP . Modified: head/sys/netinet/tcp_reass.c ============================================================================== --- head/sys/netinet/tcp_reass.c Mon Aug 6 17:21:20 2018 (r337383) +++ head/sys/netinet/tcp_reass.c Mon Aug 6 17:36:57 2018 (r337384) @@ -91,6 +91,11 @@ SYSCTL_UMA_CUR(_net_inet_tcp_reass, OID_AUTO, cursegme &tcp_reass_zone, "Global number of TCP Segments currently in Reassembly Queue"); +static u_int tcp_reass_maxqueuelen = 100; +SYSCTL_UINT(_net_inet_tcp_reass, OID_AUTO, maxqueuelen, CTLFLAG_RWTUN, + &tcp_reass_maxqueuelen, 0, + "Maximum number of TCP Segments per Reassembly Queue"); + /* Initialize TCP reassembly queue */ static void tcp_reass_zone_change(void *tag) @@ -170,6 +175,10 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tl * socket receive buffer determines our advertised window and grows * automatically when socket buffer autotuning is enabled. Use it as the * basis for our queue limit. + * + * However, allow the user to specify a ceiling for the number of + * segments in each queue. + * * Always let the missing segment through which caused this queue. * NB: Access to the socket buffer is left intentionally unlocked as we * can tolerate stale information here. @@ -180,7 +189,8 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tl * is understood. */ if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && - tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { + tp->t_segqlen >= min((so->so_rcv.sb_hiwat / tp->t_maxseg) + 1, + tcp_reass_maxqueuelen)) { TCPSTAT_INC(tcps_rcvreassfull); *tlenp = 0; if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808061736.w76Hawt5009582>