Subject: port-i386/21665: bus_dmamap_sync needs a memory barrier
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ups@stups.com>
List: netbsd-bugs
Date: 05/25/2003 01:24:27
>Number:         21665
>Category:       port-i386
>Synopsis:       bus_dmamap_sync needs a memory barrier
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun May 25 01:25:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Stephan Uphoff
>Release:        1.6T
>Organization:
>Environment:
NetBSD giant 1.6T NetBSD 1.6T (GIANT) #17: Sat May 24 20:58:42 EDT 2003  ups@giant:/usr/home/ups/sources/build/makeobjectdirprefix/usr/home/ups/sources/src/sys/arch/i386/compile/GIANT i386

>Description:

The macro bus_dmamap_sync with operation BUS_DMASYNC_POSTREAD 
for the i386 architecture (all x86 architectures ?) needs a memory
barrier since the P6 family (and others?) performs speculative out
of order reads.

The manual page BUS_DMA(9) states:

      On platforms which implement a weak memory access ordering mod-
      el, bus_dmamap_sync() will always cause the the appropriate mem-
      ory barriers to be issued.

Solution:
      Add an inexpensive locking instruction to the bus_dmamap_sync macro.
>How-To-Repeat:

>Fix:
Patch:
Index: bus.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/bus.h,v
retrieving revision 1.2
diff -r1.2 bus.h
73a74
> #include <machine/atomic.h>
1126a1128,1133
> do {                                                          \
>         int dummy;                                            \
>         /* Enforce memory order for BUS_DMASYNC_POSTREAD */     \
>         /* Any I/O instruction, locking instruction, */         \
>         /* serializing instruction or the LOCK prefix works */  \
>       (void) x86_atomic_testset_i(&dummy,0);                  \
1128,1129c1135,1138
<           (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
< 
---
>           (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))     \
>           : (void)0);                                         \
> } while (/* CONSTCOND */ 0)
>       


>Release-Note:
>Audit-Trail:
>Unformatted: