summaryrefslogtreecommitdiffstats
path: root/sys/nfs
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2009-05-18 18:37:18 +0000
committermarcel <marcel@FreeBSD.org>2009-05-18 18:37:18 +0000
commit8b09116a5afc11ad02ed3d58dc2619303aeca12b (patch)
treecf3c716dbc38984e19bd613ced4f6b9f8d4ca6b7 /sys/nfs
parentc6c278457529c585668914f3ccc199e9c40165ac (diff)
downloadFreeBSD-src-8b09116a5afc11ad02ed3d58dc2619303aeca12b.zip
FreeBSD-src-8b09116a5afc11ad02ed3d58dc2619303aeca12b.tar.gz
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.
Diffstat (limited to 'sys/nfs')
-rw-r--r--sys/nfs/nfs_common.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c
index 4c0a2c9..faa9302 100644
--- a/sys/nfs/nfs_common.c
+++ b/sys/nfs/nfs_common.c
@@ -127,9 +127,10 @@ nfsm_mbuftouio(struct mbuf **mrep, struct uio *uiop, int siz, caddr_t *dpos)
(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;
OpenPOWER on IntegriCloud