> Date: Sun, 26 Apr 2020 18:03:20 +0200
> From: Patrick Wildt <patr...@blueri.se>
> 
> Hi,
> 
> I have a HummingBoard Pulse, which is an NXP i.MX8MQ based board
> featuring two ethernets, with the second ethernet being an em(4) on
> a PCIe controller.
> 
> I had trouble getting it to work, but realized that the issue is the
> descriptor ring coherency.  I looked into the code, tried to find if
> there are incorrect flushes, or something else, but nothing worked.
> 
> Looking at the Linux driver I realized that their descriptor rings are
> allocated coherent.  Some arm64 machines are fine with em(4), since the
> PCIe controller is coherent, but on my machine it is not.  Explicitly
> mapping the rings coherent made my machine happy, so I believe that
> maybe the way that em(4) works, we need to make sure the rings are
> coherent.
> 
> So I'd propose the following diff, which *only* makes the desciptor
> rings coherent, the packets stay cached and fast.  This allows me to
> push plenty of traffic through my machine!
> 
> This is a no-op on all x86, and on arm64-machines with coherent PCIe
> controllers.
> 
> Opinions? ok?

In principle the BUS_DMAMAP_COHERENT flag should not matter; things
should work either way.  This indicates there is something wrong in
the code here, either a missing bus_dmamap_sync() call, or a bug in
the arm64 bus_dmamp_sync() implementation.  Things are always tricky
for descriptor rings, where software and hardware are modifying the
memory contents.  Things get especially tricky when a cache line
covers multiple ring entries.  Given that ARMv8 typically has a cache
line size of 64 bytes and em(4) has descriptors of 16 bytes, that may
very well be a problem here.

That said.  BUS_DMA_COHERENT makes a lot of sense for descriptor rings
like this since otherwise you just end up doing doing lots of cache
flushes.  And I think you've spent enough time looking for the real
bug.

Quickly tested on the Ampere machine.

ok kettenis@

> diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c
> index aca6b4bb02f..27d0630bf9f 100644
> --- a/sys/dev/pci/if_em.c
> +++ b/sys/dev/pci/if_em.c
> @@ -2113,7 +2113,7 @@ em_dma_malloc(struct em_softc *sc, bus_size_t size, 
> struct em_dma_alloc *dma)
>               goto destroy;
>  
>       r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg, size,
> -         &dma->dma_vaddr, BUS_DMA_WAITOK);
> +         &dma->dma_vaddr, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
>       if (r != 0)
>               goto free;
>  
> 
> 

Reply via email to