From owner-svn-src-head@FreeBSD.ORG Sat Nov 22 03:03:12 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id B858FE13; Sat, 22 Nov 2014 03:03:12 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8CECD2AD; Sat, 22 Nov 2014 03:03:12 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sAM33CNm035311; Sat, 22 Nov 2014 03:03:12 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sAM33C5o035310; Sat, 22 Nov 2014 03:03:12 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201411220303.sAM33C5o035310@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Sat, 22 Nov 2014 03:03:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r274839 - head/sys/arm/arm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 22 Nov 2014 03:03:12 -0000 Author: ian Date: Sat Nov 22 03:03:11 2014 New Revision: 274839 URL: https://svnweb.freebsd.org/changeset/base/274839 Log: When doing a PREREAD sync of an mbuf-type dma buffer, do a writeback of the first cacheline if the buffer start address is not on a cacheline boundary. Normally a buffer which is not cacheline-aligned is bounced, but a special rule applies for mbufs, which are always misaligned due to the header. We know the cpu will not write to the header while dma is in progress (so we've been told anyway), but it may have written to the header shortly before starting a read, so we need to flush that write out to memory before invalidating the whole buffer. In collaboration with Mical Meloun and Svata Kraus. Modified: head/sys/arm/arm/busdma_machdep-v6.c Modified: head/sys/arm/arm/busdma_machdep-v6.c ============================================================================== --- head/sys/arm/arm/busdma_machdep-v6.c Sat Nov 22 02:44:39 2014 (r274838) +++ head/sys/arm/arm/busdma_machdep-v6.c Sat Nov 22 03:03:11 2014 (r274839) @@ -1456,7 +1456,24 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus break; case BUS_DMASYNC_PREREAD: + /* + * An mbuf may start in the middle of a cacheline. There + * will be no cpu writes to the beginning of that line + * (which contains the mbuf header) while dma is in + * progress. Handle that case by doing a writeback of + * just the first cacheline before invalidating the + * overall buffer. Any mbuf in a chain may have this + * misalignment. Buffers which are not mbufs bounce if + * they are not aligned to a cacheline. + */ while (sl != end) { + if (sl->vaddr & arm_dcache_align_mask) { + KASSERT(map->flags & DMAMAP_MBUF, + ("unaligned buffer is not an mbuf")); + cpu_dcache_wb_range(sl->vaddr, 1); + l2cache_wb_range(sl->vaddr, + sl->busaddr, 1); + } cpu_dcache_inv_range(sl->vaddr, sl->datacount); l2cache_inv_range(sl->vaddr, sl->busaddr, sl->datacount);