NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-i386/38935: x86 bus_dmamap_sync() should use memory barrier



On Thu, Jun 12, 2008 at 11:50:03AM +0000, Manuel Bouyer wrote:
>  [...]
>  >  
>  >  I think x86_lfence() without any if() would be enough. Does it solve the
>  >  problem for you?
>  
>  As a load can occurs before a store hit memory, I think we need
>  x86_mfence() for all write cases, in fact. Assuming mfence and lfence really
>  prevent speculative loads.

Attached is the patch I'm using now.

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: x86/bus_dma.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/bus_dma.c,v
retrieving revision 1.44
diff -u -r1.44 bus_dma.c
--- x86/bus_dma.c       13 Jun 2008 09:53:46 -0000      1.44
+++ x86/bus_dma.c       18 Jun 2008 19:44:15 -0000
@@ -722,7 +722,7 @@
         */
        if (len == 0 || cookie == NULL ||
            (cookie->id_flags & X86_DMA_IS_BOUNCING) == 0)
-               return;
+               goto end;
 
        switch (cookie->id_buftype) {
        case X86_DMA_BUFTYPE_LINEAR:
@@ -844,6 +844,21 @@
                printf("unknown buffer type %d\n", cookie->id_buftype);
                panic("_bus_dmamap_sync");
        }
+end:
+       if (ops & (BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTWRITE)) {
+               /*
+                * from the memory POV a load can be reordered before a store
+                * (a load can fetch data from the write buffers, before
+                * data hits the cache or memory), a mfence avoids it.
+                */
+               x86_mfence();
+       } else if (ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_POSTREAD)) {
+               /*
+                * all past reads should have completed at before this point,
+                * and futur reads should not have started yet.
+                */
+               x86_lfence();
+       }
 }
 
 /*


Home | Main Index | Thread Index | Old Index