From owner-svn-src-head@FreeBSD.ORG Mon May 18 18:37:20 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E2BC0106564A; Mon, 18 May 2009 18:37:19 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CD9458FC1A; Mon, 18 May 2009 18:37:19 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4IIbJku071189; Mon, 18 May 2009 18:37:19 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4IIbIrn071176; Mon, 18 May 2009 18:37:18 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <200905181837.n4IIbIrn071176@svn.freebsd.org> From: Marcel Moolenaar Date: Mon, 18 May 2009 18:37:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192323 - in head/sys: amd64/amd64 arm/arm dev/md i386/i386 ia64/ia64 mips/mips nfs pc98/pc98 powerpc/aim powerpc/booke sparc64/sparc64 sun4v/sun4v sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 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: Mon, 18 May 2009 18:37:20 -0000 Author: marcel Date: Mon May 18 18:37:18 2009 New Revision: 192323 URL: http://svn.freebsd.org/changeset/base/192323 Log: Add cpu_flush_dcache() for use after non-DMA based I/O so that a possible future I-cache coherency operation can succeed. On ARM for example the L1 cache can be (is) virtually mapped, which means that any I/O that uses temporary mappings will not see the I-cache made coherent. On ia64 a similar behaviour has been observed. By flushing the D-cache, execution of binaries backed by md(4) and/or NFS work reliably. For Book-E (powerpc), execution over NFS exhibits SIGILL once in a while as well, though cpu_flush_dcache() hasn't been implemented yet. Doing an explicit D-cache flush as part of the non-DMA based I/O read operation eliminates the need to do it as part of the I-cache coherency operation itself and as such avoids pessimizing the DMA-based I/O read operations for which D-cache are already flushed/invalidated. It also allows future optimizations whereby the bcopy() followed by the D-cache flush can be integrated in a single operation, which could be implemented using on-chips DMA engines, by-passing the D-cache altogether. Modified: head/sys/amd64/amd64/machdep.c head/sys/arm/arm/machdep.c head/sys/dev/md/md.c head/sys/i386/i386/machdep.c head/sys/ia64/ia64/machdep.c head/sys/mips/mips/machdep.c head/sys/nfs/nfs_common.c head/sys/pc98/pc98/machdep.c head/sys/powerpc/aim/machdep.c head/sys/powerpc/booke/machdep.c head/sys/sparc64/sparc64/machdep.c head/sys/sun4v/sun4v/machdep.c head/sys/sys/systm.h Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/amd64/amd64/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -506,6 +506,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* Not applicable */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/arm/arm/machdep.c ============================================================================== --- head/sys/arm/arm/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/arm/arm/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -316,6 +316,18 @@ cpu_startup(void *dummy) SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + + cpu_dcache_wb_range((uintptr_t)ptr, len); + cpu_l2cache_wb_range((uintptr_t)ptr, len); +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/dev/md/md.c ============================================================================== --- head/sys/dev/md/md.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/dev/md/md.c Mon May 18 18:37:18 2009 (r192323) @@ -436,10 +436,11 @@ mdstart_malloc(struct md_s *sc, struct b if (osp == 0) bzero(dst, sc->sectorsize); else if (osp <= 255) - for (i = 0; i < sc->sectorsize; i++) - dst[i] = osp; - else + memset(dst, osp, sc->sectorsize); + else { bcopy((void *)osp, dst, sc->sectorsize); + cpu_flush_dcache(dst, sc->sectorsize); + } osp = 0; } else if (bp->bio_cmd == BIO_WRITE) { if (sc->flags & MD_COMPRESS) { @@ -491,6 +492,7 @@ mdstart_preload(struct md_s *sc, struct case BIO_READ: bcopy(sc->pl_ptr + bp->bio_offset, bp->bio_data, bp->bio_length); + cpu_flush_dcache(bp->bio_data, bp->bio_length); break; case BIO_WRITE: bcopy(bp->bio_data, sc->pl_ptr + bp->bio_offset, @@ -633,6 +635,7 @@ mdstart_swap(struct md_s *sc, struct bio break; } bcopy((void *)(sf_buf_kva(sf) + offs), p, len); + cpu_flush_dcache(p, len); } else if (bp->bio_cmd == BIO_WRITE) { if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL) rv = vm_pager_get_pages(sc->object, &m, 1, 0); Modified: head/sys/i386/i386/machdep.c ============================================================================== --- head/sys/i386/i386/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/i386/i386/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -1113,6 +1113,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* Not applicable */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/ia64/ia64/machdep.c ============================================================================== --- head/sys/ia64/ia64/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/ia64/ia64/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -311,6 +311,21 @@ cpu_boot(int howto) efi_reset_system(); } +void +cpu_flush_dcache(void *ptr, size_t len) +{ + vm_offset_t lim, va; + + va = (uintptr_t)ptr & ~31; + lim = (uintptr_t)ptr + len; + while (va < lim) { + ia64_fc(va); + va += 32; + } + + ia64_srlz_d(); +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/mips/mips/machdep.c ============================================================================== --- head/sys/mips/mips/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/mips/mips/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -200,6 +200,16 @@ cpu_reset(void) platform_reset(); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/nfs/nfs_common.c ============================================================================== --- head/sys/nfs/nfs_common.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/nfs/nfs_common.c Mon May 18 18:37:18 2009 (r192323) @@ -127,9 +127,10 @@ nfsm_mbuftouio(struct mbuf **mrep, struc (mbufcp, uiocp, xfer); else #endif - if (uiop->uio_segflg == UIO_SYSSPACE) + if (uiop->uio_segflg == UIO_SYSSPACE) { bcopy(mbufcp, uiocp, xfer); - else + cpu_flush_dcache(uiocp, xfer); + } else copyout(mbufcp, uiocp, xfer); left -= xfer; len -= xfer; Modified: head/sys/pc98/pc98/machdep.c ============================================================================== --- head/sys/pc98/pc98/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/pc98/pc98/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -1050,6 +1050,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* Not applicable */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/powerpc/aim/machdep.c ============================================================================== --- head/sys/powerpc/aim/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/powerpc/aim/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -864,6 +864,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + void cpu_initclocks(void) { Modified: head/sys/powerpc/booke/machdep.c ============================================================================== --- head/sys/powerpc/booke/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/powerpc/booke/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -556,6 +556,16 @@ fill_fpregs(struct thread *td, struct fp return (0); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/sparc64/sparc64/machdep.c ============================================================================== --- head/sys/sparc64/sparc64/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/sparc64/sparc64/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -742,6 +742,16 @@ cpu_shutdown(void *args) ofw_exit(args); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given CPU ID. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/sun4v/sun4v/machdep.c ============================================================================== --- head/sys/sun4v/sun4v/machdep.c Mon May 18 18:34:03 2009 (r192322) +++ head/sys/sun4v/sun4v/machdep.c Mon May 18 18:37:18 2009 (r192323) @@ -767,6 +767,16 @@ cpu_shutdown(void *args) hv_mach_exit(0); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) Modified: head/sys/sys/systm.h ============================================================================== --- head/sys/sys/systm.h Mon May 18 18:34:03 2009 (r192322) +++ head/sys/sys/systm.h Mon May 18 18:37:18 2009 (r192323) @@ -147,6 +147,7 @@ void panic(const char *, ...) __dead2 __ #endif void cpu_boot(int); +void cpu_flush_dcache(void *, size_t); void cpu_rootconf(void); void critical_enter(void); void critical_exit(void);