commit b5315fecc8f99e12e8a37733089dc1486a5d733a Author: Ryan Stone Date: Mon Nov 20 11:25:21 2017 Don't use 9KB clusters in e1000 and plug a leak Allocating 9KB clusters stresses the physmem allocator, and under memory pressure this can cause cluster allocation to consume so much CPU that other parts of the system become starved of CPU. Instead only allocate 4KB clusters and pass mbuf chains up the stack. rxeof() builds up an mbuf chain in rxr->fmp while it works on receiving a packet that is split across multiple descriptors. If the interface is re-initialized while it is part-way through building up such a chain, we need to free the mbuf chain to prevent it from leaking. diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 036de0eb24e8..ae82bce11239 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1416,10 +1416,8 @@ em_init_locked(struct adapter *adapter) */ if (adapter->hw.mac.max_frame_size <= 2048) adapter->rx_mbuf_sz = MCLBYTES; - else if (adapter->hw.mac.max_frame_size <= 4096) - adapter->rx_mbuf_sz = MJUMPAGESIZE; else - adapter->rx_mbuf_sz = MJUM9BYTES; + adapter->rx_mbuf_sz = MJUMPAGESIZE; /* Prepare receive descriptors and buffers */ if (em_setup_receive_structures(adapter)) { @@ -4408,6 +4406,10 @@ em_setup_receive_ring(struct rx_ring *rxr) } } + m_freem(rxr->fmp); + rxr->fmp = NULL; + rxr->lmp = NULL; + /* Now replenish the mbufs */ for (int j = 0; j != adapter->num_rx_desc; ++j) { rxbuf = &rxr->rx_buffers[j]; @@ -4555,6 +4557,10 @@ em_free_receive_buffers(struct rx_ring *rxr) rxr->next_to_refresh = 0; } + m_freem(rxr->fmp); + rxr->fmp = NULL; + rxr->lmp = NULL; + if (rxr->rxtag != NULL) { bus_dma_tag_destroy(rxr->rxtag); rxr->rxtag = NULL; diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 3c1ffa4de0a7..07ee574cd160 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -1324,10 +1324,8 @@ igb_init_locked(struct adapter *adapter) */ if (adapter->max_frame_size <= 2048) adapter->rx_mbuf_sz = MCLBYTES; - else if (adapter->max_frame_size <= 4096) - adapter->rx_mbuf_sz = MJUMPAGESIZE; else - adapter->rx_mbuf_sz = MJUM9BYTES; + adapter->rx_mbuf_sz = MJUMPAGESIZE; /* Prepare receive descriptors and buffers */ if (igb_setup_receive_structures(adapter)) { @@ -4479,6 +4477,7 @@ skip_head: rxr->rx_split_packets = 0; rxr->rx_bytes = 0; + m_freem(rxr->fmp); rxr->fmp = NULL; rxr->lmp = NULL;