> > Date: Tue, 31 Aug 2010 22:30:42 +0100
> > From: Stuart Henderson <[email protected]>
> >
> > running with this seems to help.
>
> Can you try this diff instead?
>
> Index: if_vr.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
> retrieving revision 1.105
> diff -u -p -r1.105 if_vr.c
> --- if_vr.c 19 May 2010 15:27:35 -0000 1.105
> +++ if_vr.c 31 Aug 2010 21:57:55 -0000
> @@ -1562,6 +1562,10 @@ vr_alloc_mbuf(struct vr_softc *sc, struc
> d = r->vr_ptr;
> d->vr_data = htole32(r->vr_map->dm_segs[0].ds_addr);
> d->vr_ctl = htole32(VR_RXCTL | VR_RXLEN);
> +
> + bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap, 0,
> + sc->sc_listmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
> +
> d->vr_status = htole32(VR_RXSTAT);
>
> bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap, 0,
>
#define bus_dmamap_sync(t, p, o, l, ops) \
(void)((t)->_dmamap_sync ? \
(*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
I expect it to still fail in exactly the same way, with gcc
re-organizing the writes.
Only a global function call will fix it, or, making the pointer
volatile so that operations on it are ordered.
Volatile pointers are the strong and portable way to imposing ordering.