diff -r 4ea51bc8a05d -r 4a99aed41584 sys/dev/cxgbe/adapter.h --- a/sys/dev/cxgbe/adapter.h Mon Jun 29 18:06:47 2015 -0700 +++ b/sys/dev/cxgbe/adapter.h Thu Jul 02 14:57:05 2015 -0700 @@ -326,6 +326,9 @@ struct tx_desc { struct tx_sdesc { struct mbuf *m; /* m_nextpkt linked chain of frames */ uint8_t desc_used; /* # of hardware descriptors used by the WR */ +#if 1 + uint8_t header_mbuf[MSIZE] __aligned(256); +#endif }; diff -r 4ea51bc8a05d -r 4a99aed41584 sys/dev/cxgbe/t4_sge.c --- a/sys/dev/cxgbe/t4_sge.c Mon Jun 29 18:06:47 2015 -0700 +++ b/sys/dev/cxgbe/t4_sge.c Thu Jul 02 14:57:05 2015 -0700 @@ -2450,10 +2450,10 @@ eth_tx(struct mp_ring *r, u_int cidx, u_ total += txp.npkt; remaining -= txp.npkt; } else { + ETHER_BPF_MTAP(ifp, m0); + n = write_txpkt_wr(txq, (void *)wr, m0, available); total++; remaining--; - n = write_txpkt_wr(txq, (void *)wr, m0, available); - ETHER_BPF_MTAP(ifp, m0); } MPASS(n >= 1 && n <= available && n <= SGE_MAX_WR_NDESC); @@ -4060,6 +4060,17 @@ write_txpkt_wr(struct sge_txq *txq, stru txsd = &txq->sdesc[eq->pidx]; txsd->m = m0; txsd->desc_used = ndesc; +#if 1 + /* + * Save a copy of the entire mbuf and then zero out the headers to catch + * others that try and use this mbuf. + */ + bcopy(m0, &txsd->header_mbuf[0], MSIZE); + if (m0->m_flags & M_EXT) + bzero(m0, MSIZE); + else + bzero(m0, offsetof(struct mbuf, m_pktdat[0])); +#endif return (ndesc); } @@ -4240,6 +4251,13 @@ write_txpkts_wr(struct sge_txq *txq, str txsd = &txq->sdesc[eq->pidx]; txsd->m = m0; txsd->desc_used = ndesc; +#if 1 + bcopy(m0, &txsd->header_mbuf[0], MSIZE); + if (m0->m_flags & M_EXT) + bzero(m0, MSIZE); + else + bzero(m0, offsetof(struct mbuf, m_pktdat[0])); +#endif return (ndesc); } @@ -4451,6 +4469,10 @@ reclaim_tx_descs(struct sge_txq *txq, u_ txsd = &txq->sdesc[eq->cidx]; ndesc = txsd->desc_used; +#if 1 + bcopy(&txsd->header_mbuf[0], txsd->m, MSIZE); +#endif + /* Firmware doesn't return "partial" credits. */ KASSERT(can_reclaim >= ndesc, ("%s: unexpected number of credits: %d, %d",