lkml.org 
[lkml]   [2011]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: still nfs problems [Was: Linux 2.6.37-rc8]
    From
    Date
    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



    \
     
     \ /
      Last update: 2011-01-06 22:11    [W:0.021 / U:30.464 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site