Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 31 Aug 2020 13:53:14 +0000 (UTC)
From:      Andrew Gallatin <gallatin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r364986 - head/sys/kern
Message-ID:  <202008311353.07VDrEoi054083@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gallatin
Date: Mon Aug 31 13:53:14 2020
New Revision: 364986
URL: https://svnweb.freebsd.org/changeset/base/364986

Log:
  make m_getm2() resilient to zone_jumbop exhaustion
  
  When the zone_jumbop is exhausted, most things using
  using sosend* (like sshd)  will eventually
  fail or hang if allocations are limited to the
  depleted jumbop zone.  This makes it imossible to
  communicate with a box which is under an attach which
  exhausts the jumbop zone.
  
  Rather than depending on the page size zone, also try cluster
  allocations to satisfy larger requests.  This allows me
  to ssh to, and serve 100Gb/s of traffic from a server which
  under attack and has had its page-sized zone exhausted.
  
  Reviewed by:	glebius, markj, rmacklem
  Sponsored by:	Netflix
  Differential Revision:	https://reviews.freebsd.org/D26150

Modified:
  head/sys/kern/kern_mbuf.c

Modified: head/sys/kern/kern_mbuf.c
==============================================================================
--- head/sys/kern/kern_mbuf.c	Mon Aug 31 12:14:20 2020	(r364985)
+++ head/sys/kern/kern_mbuf.c	Mon Aug 31 13:53:14 2020	(r364986)
@@ -1423,21 +1423,28 @@ m_getm2(struct mbuf *m, int len, int how, short type, 
 
 	/* Loop and append maximum sized mbufs to the chain tail. */
 	while (len > 0) {
-		if (len > MCLBYTES)
-			mb = m_getjcl(how, type, (flags & M_PKTHDR),
+		mb = NULL;
+		if (len > MCLBYTES) {
+			mb = m_getjcl(M_NOWAIT, type, (flags & M_PKTHDR),
 			    MJUMPAGESIZE);
-		else if (len >= MINCLSIZE)
-			mb = m_getcl(how, type, (flags & M_PKTHDR));
-		else if (flags & M_PKTHDR)
-			mb = m_gethdr(how, type);
-		else
-			mb = m_get(how, type);
 
-		/* Fail the whole operation if one mbuf can't be allocated. */
+		}
 		if (mb == NULL) {
-			if (nm != NULL)
+			if (len >= MINCLSIZE)
+				mb = m_getcl(how, type, (flags & M_PKTHDR));
+			else if (flags & M_PKTHDR)
+				mb = m_gethdr(how, type);
+			else
+				mb = m_get(how, type);
+
+			/*
+			 * Fail the whole operation if one mbuf can't be
+			 * allocated.
+			 */
+			if (mb == NULL) {
 				m_freem(nm);
-			return (NULL);
+				return (NULL);
+			}
 		}
 
 		/* Book keeping. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202008311353.07VDrEoi054083>