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:
parent
b916fcec4d
commit
80a2a305b2
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user