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
This commit is contained in:
Andrew Gallatin 2020-08-31 13:53:14 +00:00
parent 2a0ce39d08
commit 796d4eb89e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=364986

View File

@ -1423,21 +1423,28 @@ m_getm2(struct mbuf *m, int len, int how, short type, int flags)
/* 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. */