pass in pointer to m_head to re_encap because m_defrag could free the

original mbuf causing a free'd mbuf passed to bpf later and panic'ing the
system..  This should only effect jumbo frames.

MFC after:	5 days
This commit is contained in:
John-Mark Gurney 2004-09-18 18:08:28 +00:00
parent b916fcec4d
commit 80a2a305b2

View File

@ -194,7 +194,7 @@ static int re_probe (device_t);
static int re_attach (device_t);
static int re_detach (device_t);
static int re_encap (struct rl_softc *, struct mbuf *, int *);
static int re_encap (struct rl_softc *, struct mbuf **, int *);
static void re_dma_map_addr (void *, bus_dma_segment_t *, int, int);
static void re_dma_map_desc (void *, bus_dma_segment_t *, int,
@ -1843,7 +1843,7 @@ re_intr(arg)
static int
re_encap(sc, m_head, idx)
struct rl_softc *sc;
struct mbuf *m_head;
struct mbuf **m_head;
int *idx;
{
struct mbuf *m_new = NULL;
@ -1866,11 +1866,11 @@ re_encap(sc, m_head, idx)
arg.rl_flags = 0;
if (m_head->m_pkthdr.csum_flags & CSUM_IP)
if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP)
arg.rl_flags |= RL_TDESC_CMD_IPCSUM;
if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP)
arg.rl_flags |= RL_TDESC_CMD_TCPCSUM;
if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP)
arg.rl_flags |= RL_TDESC_CMD_UDPCSUM;
arg.sc = sc;
@ -1882,7 +1882,7 @@ re_encap(sc, m_head, idx)
map = sc->rl_ldata.rl_tx_dmamap[*idx];
error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map,
m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
*m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
if (error && error != EFBIG) {
printf("re%d: can't map mbuf (error %d)\n", sc->rl_unit, error);
@ -1892,11 +1892,11 @@ re_encap(sc, m_head, idx)
/* Too many segments to map, coalesce into a single mbuf */
if (error || arg.rl_maxsegs == 0) {
m_new = m_defrag(m_head, M_DONTWAIT);
m_new = m_defrag(*m_head, M_DONTWAIT);
if (m_new == NULL)
return (1);
return (ENOBUFS);
else
m_head = m_new;
*m_head = m_new;
arg.sc = sc;
arg.rl_idx = *idx;
@ -1904,7 +1904,7 @@ re_encap(sc, m_head, idx)
arg.rl_ring = sc->rl_ldata.rl_tx_list;
error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map,
m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
*m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
if (error) {
printf("re%d: can't map mbuf (error %d)\n",
sc->rl_unit, error);
@ -1921,7 +1921,7 @@ re_encap(sc, m_head, idx)
sc->rl_ldata.rl_tx_dmamap[arg.rl_idx];
sc->rl_ldata.rl_tx_dmamap[arg.rl_idx] = map;
sc->rl_ldata.rl_tx_mbuf[arg.rl_idx] = m_head;
sc->rl_ldata.rl_tx_mbuf[arg.rl_idx] = *m_head;
sc->rl_ldata.rl_tx_free -= arg.rl_maxsegs;
/*
@ -1930,7 +1930,7 @@ re_encap(sc, m_head, idx)
* transmission attempt.
*/
mtag = VLAN_OUTPUT_TAG(&sc->arpcom.ac_if, m_head);
mtag = VLAN_OUTPUT_TAG(&sc->arpcom.ac_if, *m_head);
if (mtag != NULL)
sc->rl_ldata.rl_tx_list[*idx].rl_vlanctl =
htole32(htons(VLAN_TAG_VALUE(mtag)) | RL_TDESC_VLANCTL_TAG);
@ -1983,7 +1983,7 @@ re_start_locked(ifp)
if (m_head == NULL)
break;
if (re_encap(sc, m_head, &idx)) {
if (re_encap(sc, &m_head, &idx)) {
IF_PREPEND(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;