[PATCH] Add flush_kernel_dcache_page() API
authorJames Bottomley <James.Bottomley@SteelEye.com>
Sun, 26 Mar 2006 09:36:59 +0000 (01:36 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 26 Mar 2006 16:56:53 +0000 (08:56 -0800)
We have a problem in a lot of emulated storage in that it takes a page from
get_user_pages() and does something like

kmap_atomic(page)
modify page
kunmap_atomic(page)

However, nothing has flushed the kernel cache view of the page before the
kunmap.  We need a lightweight API to do this, so this new API would
specifically be for flushing the kernel cache view of a user page which the
kernel has modified.  The driver would need to add
flush_kernel_dcache_page(page) before the final kunmap.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Documentation/cachetlb.txt
include/linux/highmem.h

index 1f312a9893d91e7d2b57ebf729e1989d2aaf5fa8..53245c429f7d9f13999803ea4ced0813437fceb5 100644 (file)
@@ -371,6 +371,18 @@ maps this page at its virtual address.
        architectures).  For incoherent architectures, it should flush
        the cache of the page at vmaddr in the current user process.
 
+  void flush_kernel_dcache_page(struct page *page)
+       When the kernel needs to modify a user page is has obtained
+       with kmap, it calls this function after all modifications are
+       complete (but before kunmapping it) to bring the underlying
+       page up to date.  It is assumed here that the user has no
+       incoherent cached copies (i.e. the original page was obtained
+       from a mechanism like get_user_pages()).  The default
+       implementation is a nop and should remain so on all coherent
+       architectures.  On incoherent architectures, this should flush
+       the kernel cache for page (using page_address(page)).
+
+
   void flush_icache_range(unsigned long start, unsigned long end)
        When the kernel stores into addresses that it will execute
        out of (eg when loading modules), this function is called.
index 7bd2593dbef9e53c177a22609dc570a8511c4a07..892c4ea1b4254a63d6540f948229a6f8164282e1 100644 (file)
@@ -13,6 +13,12 @@ static inline void flush_anon_page(struct page *page, unsigned long vmaddr)
 }
 #endif
 
+#ifndef ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+static inline void flush_kernel_dcache_page(struct page *page)
+{
+}
+#endif
+
 #ifdef CONFIG_HIGHMEM
 
 #include <asm/highmem.h>