[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1294348078.22825.346.camel@mulgrave.site>
Date: Thu, 06 Jan 2011 15:07:58 -0600
From: James Bottomley <James.Bottomley@...senPartnership.com>
To: Russell King - ARM Linux <linux@....linux.org.uk>
Cc: Trond Myklebust <Trond.Myklebust@...app.com>,
Linus Torvalds <torvalds@...ux-foundation.org>,
linux-nfs@...r.kernel.org, linux-kernel@...r.kernel.org,
Marc Kleine-Budde <mkl@...gutronix.de>,
Uwe Kleine-König
<u.kleine-koenig@...gutronix.de>,
Marc Kleine-Budde <m.kleine-budde@...gutronix.de>,
linux-arm-kernel@...ts.infradead.org,
Parisc List <linux-parisc@...r.kernel.org>,
linux-arch@...r.kernel.org
Subject: Re: still nfs problems [Was: Linux 2.6.37-rc8]
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-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists