Просмотр исходного кода

[PATCH] Add flush_kernel_dcache_page() API

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>
James Bottomley 19 лет назад
Родитель
Сommit
5a3a5a98b6
2 измененных файлов с 18 добавлено и 0 удалено
  1. 12 0
      Documentation/cachetlb.txt
  2. 6 0
      include/linux/highmem.h

+ 12 - 0
Documentation/cachetlb.txt

@@ -371,6 +371,18 @@ maps this page at its virtual address.
 	architectures).  For incoherent architectures, it should flush
 	architectures).  For incoherent architectures, it should flush
 	the cache of the page at vmaddr in the current user process.
 	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)
   void flush_icache_range(unsigned long start, unsigned long end)
   	When the kernel stores into addresses that it will execute
   	When the kernel stores into addresses that it will execute
 	out of (eg when loading modules), this function is called.
 	out of (eg when loading modules), this function is called.

+ 6 - 0
include/linux/highmem.h

@@ -13,6 +13,12 @@ static inline void flush_anon_page(struct page *page, unsigned long vmaddr)
 }
 }
 #endif
 #endif
 
 
+#ifndef ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+static inline void flush_kernel_dcache_page(struct page *page)
+{
+}
+#endif
+
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_HIGHMEM
 
 
 #include <asm/highmem.h>
 #include <asm/highmem.h>