On Thu, 2011-01-06 at 12:25 -0600, James Bottomley wrote: > OK, so thinking about this, it seems that the only danger is actually > what NFS is doing: reading cache pages via a vmap. In that case, since > the requirement is to invalidate the vmap range to prepare for read, we > could have invalidate_kernel_vmap_range loop over the underlying pages > and flush them through the kernel alias if the architecture specific > flag indicates their contents might be dirty. > > The loop adds expense that is probably largely unnecessary to > invalidate_kernel_vmap_range() but the alternative is adding to the API > proliferation with something that only flushes the kernel pages if the > arch specific flag says they're dirty. This is what I think the arm patch would look like (example only: I can't compile it). Is something like this too expensive? the loop can't be optimised away because of the need to check the pages (and vmalloc_to_page is a three level page table lookup). James --- diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 3acd8fa..34469ca 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -414,8 +414,17 @@ static inline void flush_kernel_vmap_range(void *addr, int size) } static inline void invalidate_kernel_vmap_range(void *addr, int size) { - if ((cache_is_vivt() || cache_is_vipt_aliasing())) - __cpuc_flush_dcache_area(addr, (size_t)size); + if ((cache_is_vivt() || cache_is_vipt_aliasing())) { + void *cursor = addr; + + for ( ; cursor < addr + size; cursor += PAGE_SIZE) { + struct page *page = vmalloc_to_page(cursor); + + if (!test_and_set_bit(PG_dcache_clean, &page->flags)) + __flush_dcache_page(page_mapping(page), page); + } + __cpuc_flush_dcache_area(addr, (size_t)size); + } } #define ARCH_HAS_FLUSH_ANON_PAGE -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html