Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 May 2009 18:37:18 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
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
Message-ID:  <200905181837.n4IIbIrn071176@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905181837.n4IIbIrn071176>