Subject: Re: bus_dmamap_sync not enough ?
To: Jason R Thorpe <>
From: Stephan Uphoff <>
List: tech-kern
Date: 02/11/2003 15:42:24
> Jason R. Thorpe wrote:
> On Tue, Feb 11, 2003 at 12:35:01PM -0500, Stephan Uphoff wrote:
>  > The i82257 driver ignores this problem and just illegally calls 
>  > bus_dmamap_sync with
>  > BUS_DMASYNC_POSTXXXX flags with full knowledge that the DMA might not have 
>  > completed.
>  > ( When it finds out that the DMA did not complete it just calls bus_dmamap_sync
>  > again with BUS_DMASYNC_PREXXXX op flags)
> This is not illegal... this is an acceptable/intended use of the interface
> (I should know -- I designed the interface and wrote the code that you're
> citing :-)
> -- 
>         -- Jason R. Thorpe <>

I missed that you wrote the driver - excellent then I can point out some
of the details. (and btw, thanks for all the great code !)

The bus_dma(9) manual states for bus_dmamap_sync:
	This function must be called to synchronize DMA buffers before
        and after a DMA operation.
	[ ... ]	
	If DMA read and write operations are not preceded and followed by the appro-
        priate synchronization operations, behavior is undefined.

If the manual is correct then fxp_rxintr() has a race condition as a DMA read 
might happen for example between lines  "/* ## A ## */" and "/* ## B ## */"

File i82257.c:

		FXP_RFASYNC(sc, m,

		/* ## A ##*/
		rxstat = le16toh(rfa->rfa_status);

		if ((rxstat & FXP_RFA_STATUS_C) == 0) {
			 * We have processed all of the
			 * receive buffers.
			 /* ## B ## */

There are several more examples in the driver with possible read AND write DMA
operations on buffers last synchronized with  BUS_DMASYNC_POSTREAD|BUS_DMASYNC_

If the driver code is correct (and the manual page is wrong) the architecture
specific implementation of _bus_dmamap_sync for i386 must be converted from
a no-op to a serializing assembly instruction for BUS_DMASYNC_POSTREAD 
( Otherwise you might get out of order CPU reads of in order DMA read 
operations )

I also fail to see how bounce buffers (32bit PCI device and more than 4GB main 
would ever work if bus_dmamap_sync(... BUS_DMASYNC_PREWRITE) is allowed to be 
concurrently with a DMA read operation on the same buffer.


Stephan Uphoff
9275 Martin Road
Roswell, GA 30076