No regression so far.

//mxb

> On 15 dec. 2015, at 14:18, Mike Belopuhov <[email protected]> wrote:
> 
> Hi,
> 
> This has been in my tree for a while and I believe Yasuoka-san has
> tested it in the scenario where it was crashing.
> 
> m_pulldown is done here with a zero offset which means that if
> there's been no space reserved for the Ethernet header in the mbuf
> or the cluster it will allocate a new chunk of memory and return a
> new pointer that the vmx code ignores.  This can realistically
> happen only during the bpf injection.
> 
> The diff below makes sure to keep the modified chain pointer around
> and passes it back to the calling code so that it will get properly
> accounted for.  m_pulldown with a zero offset is equivalent to a
> m_pullup.
> 
> OK?
> 
> 
> diff --git sys/dev/pci/if_vmx.c sys/dev/pci/if_vmx.c
> index 055cfe1..50edb0b 100644
> --- sys/dev/pci/if_vmx.c
> +++ sys/dev/pci/if_vmx.c
> @@ -164,11 +164,11 @@ void vmxnet3_stop(struct ifnet *);
> void vmxnet3_reset(struct vmxnet3_softc *);
> int vmxnet3_init(struct vmxnet3_softc *);
> int vmxnet3_ioctl(struct ifnet *, u_long, caddr_t);
> void vmxnet3_start(struct ifnet *);
> int vmxnet3_load_mbuf(struct vmxnet3_softc *, struct vmxnet3_txring *,
> -    struct mbuf *);
> +    struct mbuf **);
> void vmxnet3_watchdog(struct ifnet *);
> void vmxnet3_media_status(struct ifnet *, struct ifmediareq *);
> int vmxnet3_media_change(struct ifnet *);
> void *vmxnet3_dma_allocmem(struct vmxnet3_softc *, u_int, u_int, bus_addr_t 
> *);
> 
> @@ -1063,11 +1063,11 @@ vmxnet3_start(struct ifnet *ifp)
> 
>               IFQ_DEQUEUE(&ifp->if_snd, m);
>               if (m == NULL)
>                       break;
> 
> -             n = vmxnet3_load_mbuf(sc, ring, m);
> +             n = vmxnet3_load_mbuf(sc, ring, &m);
>               if (n == -1) {
>                       ifp->if_oerrors++;
>                       continue;
>               }
> 
> @@ -1087,13 +1087,14 @@ vmxnet3_start(struct ifnet *ifp)
>       }
> }
> 
> int
> vmxnet3_load_mbuf(struct vmxnet3_softc *sc, struct vmxnet3_txring *ring,
> -    struct mbuf *m)
> +    struct mbuf **mp)
> {
>       struct vmxnet3_txdesc *txd, *sop;
> +     struct mbuf *n, *m = *mp;
>       bus_dmamap_t map;
>       u_int hlen = ETHER_HDR_LEN, csum_off;
>       u_int prod;
>       int gen, i;
> 
> @@ -1105,29 +1106,29 @@ vmxnet3_load_mbuf(struct vmxnet3_softc *sc, struct 
> vmxnet3_txring *ring,
>                   sc->sc_dev.dv_xname);
>               return -1;
>       }
> #endif
>       if (m->m_pkthdr.csum_flags & (M_TCP_CSUM_OUT|M_UDP_CSUM_OUT)) {
> -             struct mbuf *mp;
>               struct ip *ip;
>               int offp;
> 
>               if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT)
>                       csum_off = offsetof(struct tcphdr, th_sum);
>               else
>                       csum_off = offsetof(struct udphdr, uh_sum);
> 
> -             mp = m_pulldown(m, hlen, sizeof(*ip), &offp);
> -             if (mp == NULL)
> +             n = m_pulldown(m, hlen, sizeof(*ip), &offp);
> +             if (n == NULL)
>                       return (-1);
> 
> -             ip = (struct ip *)(mp->m_data + offp);
> +             ip = (struct ip *)(n->m_data + offp);
>               hlen += ip->ip_hl << 2;
> 
> -             mp = m_pulldown(m, 0, hlen + csum_off + 2, &offp);
> -             if (mp == NULL)
> +             *mp = m_pullup(m, hlen + csum_off + 2);
> +             if (*mp == NULL)
>                       return (-1);
> +             m = *mp;
>       }
> 
>       switch (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) {
>       case 0:
>               break;
> 

Reply via email to