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>