From nobody@FreeBSD.org  Sat Jan 24 17:33:34 2004
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 8B52B16A4CE
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 24 Jan 2004 17:33:34 -0800 (PST)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id ACC0043D31
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 24 Jan 2004 17:33:33 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.10/8.12.10) with ESMTP id i0P1XXdL032570
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 24 Jan 2004 17:33:33 -0800 (PST)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.10/8.12.10/Submit) id i0P1XXjE032567;
	Sat, 24 Jan 2004 17:33:33 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200401250133.i0P1XXjE032567@www.freebsd.org>
Date: Sat, 24 Jan 2004 17:33:33 -0800 (PST)
From: Stephan Uphoff <ups@tree.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: bus_dmamap_sync with BUS_DMASYNC_POSTREAD needs memory barrier.
X-Send-Pr-Version: www-2.0

>Number:         61858
>Category:       i386
>Synopsis:       bus_dmamap_sync with BUS_DMASYNC_POSTREAD needs memory barrier.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    remko
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan 24 17:40:09 PST 2004
>Closed-Date:    Mon Jul 30 10:20:23 GMT 2007
>Last-Modified:  Mon Jul 30 10:20:23 GMT 2007
>Originator:     Stephan Uphoff
>Release:        current
>Organization:
>Environment:
N/A
>Description:
bus_dmamap_sync is basically a no-op on i386 for PCI.
However since modern i386 CPUs can issue speculative out of order readaheads a memory barrier is required for BUS_DMASYNC_POSTREAD

Example: 

Device uses DMA for data (D) and control (C) memory.
CPU tests if DMA finished by checking (C)

Some ugly pseudo code:

bus_dmamap_sync(.....,BUS_DMASYNC_POSTREAD);  /* Sync (C) Control */
if (C)
	{
	bus_dmamap_sync(.....,BUS_DMASYNC_POSTREAD);  /* Sync (D) DATA */
	var = D;
	....

The current  bus_dmamap_sync(.....,BUS_DMASYNC_POSTREAD) does not act
as a memory barrier as required by the manual page.

This means the CPU can reorder the read accesses to the memory.
(No-op bus_dmamap_sync removed) 

	speculative_preload  = D;
                    <---- Race condition if DMA happens here
	if (C)
	    {
	     var = speculative_preload;


var can contain invalid data as it might have
been loaded before C became valid.
>How-To-Repeat:
      
>Fix:
Add a memory barrier.

Import recent changes to bus_dmamap_sync from NetBSD.

Linux has an interesting solution (link section trick) that dynamically
patches the executable to use the fastest memory barrier
supported by the current CPU.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-i386->bms 
Responsible-Changed-By: bms 
Responsible-Changed-When: Sun Jul 4 15:13:18 GMT 2004 
Responsible-Changed-Why:  
I've been discussing this one with green@ 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61858 
Responsible-Changed-From-To: bms->freebsd-i386 
Responsible-Changed-By: bms 
Responsible-Changed-When: Wed Aug 2 12:59:04 UTC 2006 
Responsible-Changed-Why:  
back to the free pool 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61858 
State-Changed-From-To: open->feedback 
State-Changed-By: remko 
State-Changed-When: Mon Sep 11 12:42:15 UTC 2006 
State-Changed-Why:  
Hello, 

A lot of work had been done on the busdma infrastructure 
etc, can you tell me whether this problem you described 
is still there in the latest freebsd release? (6.1) 

Thanks 


Responsible-Changed-From-To: freebsd-i386->remko 
Responsible-Changed-By: remko 
Responsible-Changed-When: Mon Sep 11 12:42:15 UTC 2006 
Responsible-Changed-Why:  
grab the pr 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61858 
State-Changed-From-To: feedback->closed 
State-Changed-By: linimon 
State-Changed-When: Mon Jul 30 10:19:47 UTC 2007 
State-Changed-Why:  
Feedback timeout (> 6 months).  This can be re-opened if it is still a 
problem. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61858 
>Unformatted:
