Prev: [tip:perf/pebs] perf trace: Don't use pager if scripting
Next: arch/powerpc/sysdev/cpm2_pic.h: Checkpatch cleanup
From: Russell King - ARM Linux on 4 Mar 2010 11:50 On Tue, Mar 02, 2010 at 05:34:29PM +0000, Catalin Marinas wrote: > There are places in Linux where writes to newly allocated page cache > pages happen without a subsequent call to flush_dcache_page() (several > PIO drivers including USB HCD). This patch changes the meaning of > PG_arch_1 to be PG_dcache_clean and always flush the D-cache for a newly > mapped page in update_mmu_cache(). > > The patch also sets the PG_arch_1 bit in the DMA cache maintenance > function to avoid additional cache flushing in update_mmu_cache(). .... > arch/arm/include/asm/cacheflush.h | 6 +++--- > arch/arm/mm/copypage-v6.c | 2 +- > arch/arm/mm/dma-mapping.c | 5 +++++ > arch/arm/mm/fault-armv.c | 2 +- > arch/arm/mm/flush.c | 2 +- > 5 files changed, 11 insertions(+), 6 deletions(-) Could you please send for RFC a fuller patch which covers all places that PG_dcache_dirty is used and/or mentioned? $ grep PG_dcache_dirty arch/arm -r arch/arm/mm/copypage-v6.c: if (test_and_clear_bit(PG_dcache_dirty, &from->flags)) arch/arm/mm/fault-armv.c: * 1. If PG_dcache_dirty is set for the page, we need to ensure arch/arm/mm/fault-armv.c: if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) arch/arm/mm/flush.c: set_bit(PG_dcache_dirty, &page->flags); arch/arm/mm/copypage-v4mc.c: if (test_and_clear_bit(PG_dcache_dirty, &from->flags)) arch/arm/mm/copypage-xscale.c: if (test_and_clear_bit(PG_dcache_dirty, &from->flags)) arch/arm/include/asm/tlbflush.h: * if PG_dcache_dirty is set for the page, we need to ensure that any arch/arm/include/asm/cacheflush.h:#define PG_dcache_dirty PG_arch_1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Catalin Marinas on 4 Mar 2010 12:30 On Thu, 2010-03-04 at 16:44 +0000, Russell King - ARM Linux wrote: > On Tue, Mar 02, 2010 at 05:34:29PM +0000, Catalin Marinas wrote: > > There are places in Linux where writes to newly allocated page cache > > pages happen without a subsequent call to flush_dcache_page() (several > > PIO drivers including USB HCD). This patch changes the meaning of > > PG_arch_1 to be PG_dcache_clean and always flush the D-cache for a newly > > mapped page in update_mmu_cache(). > > > > The patch also sets the PG_arch_1 bit in the DMA cache maintenance > > function to avoid additional cache flushing in update_mmu_cache(). > ... > > arch/arm/include/asm/cacheflush.h | 6 +++--- > > arch/arm/mm/copypage-v6.c | 2 +- > > arch/arm/mm/dma-mapping.c | 5 +++++ > > arch/arm/mm/fault-armv.c | 2 +- > > arch/arm/mm/flush.c | 2 +- > > 5 files changed, 11 insertions(+), 6 deletions(-) > > Could you please send for RFC a fuller patch which covers all places that > PG_dcache_dirty is used and/or mentioned? Ah, I thought the compilation would find them but I was wrong. I'll repost. -- Catalin -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Catalin Marinas on 4 Mar 2010 13:40 On Thu, 2010-03-04 at 16:44 +0000, Russell King - ARM Linux wrote: > On Tue, Mar 02, 2010 at 05:34:29PM +0000, Catalin Marinas wrote: > > There are places in Linux where writes to newly allocated page cache > > pages happen without a subsequent call to flush_dcache_page() (several > > PIO drivers including USB HCD). This patch changes the meaning of > > PG_arch_1 to be PG_dcache_clean and always flush the D-cache for a newly > > mapped page in update_mmu_cache(). > > > > The patch also sets the PG_arch_1 bit in the DMA cache maintenance > > function to avoid additional cache flushing in update_mmu_cache(). > ... > > arch/arm/include/asm/cacheflush.h | 6 +++--- > > arch/arm/mm/copypage-v6.c | 2 +- > > arch/arm/mm/dma-mapping.c | 5 +++++ > > arch/arm/mm/fault-armv.c | 2 +- > > arch/arm/mm/flush.c | 2 +- > > 5 files changed, 11 insertions(+), 6 deletions(-) > > Could you please send for RFC a fuller patch which covers all places that > PG_dcache_dirty is used and/or mentioned? ARM: Assume new page cache pages have dirty D-cache From: Catalin Marinas <catalin.marinas(a)arm.com> There are places in Linux where writes to newly allocated page cache pages happen without a subsequent call to flush_dcache_page() (several PIO drivers including USB HCD). This patch changes the meaning of PG_arch_1 to be PG_dcache_clean and always flush the D-cache for a newly mapped page in update_mmu_cache(). The patch also sets the PG_arch_1 bit in the DMA cache maintenance function to avoid additional cache flushing in update_mmu_cache(). Signed-off-by: Catalin Marinas <catalin.marinas(a)arm.com> Cc: Russell King <rmk(a)arm.linux.org.uk> Cc: Benjamin Herrenschmidt <benh(a)kernel.crashing.org> Cc: James Bottomley <James.Bottomley(a)HansenPartnership.com> --- arch/arm/include/asm/cacheflush.h | 6 +++--- arch/arm/include/asm/tlbflush.h | 2 +- arch/arm/mm/copypage-v4mc.c | 2 +- arch/arm/mm/copypage-v6.c | 2 +- arch/arm/mm/copypage-xscale.c | 2 +- arch/arm/mm/dma-mapping.c | 5 +++++ arch/arm/mm/fault-armv.c | 4 ++-- arch/arm/mm/flush.c | 2 +- 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index ed7d289..96d666f 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -137,10 +137,10 @@ #endif /* - * This flag is used to indicate that the page pointed to by a pte - * is dirty and requires cleaning before returning it to the user. + * This flag is used to indicate that the page pointed to by a pte is clean + * and does not require cleaning before returning it to the user. */ -#define PG_dcache_dirty PG_arch_1 +#define PG_dcache_clean PG_arch_1 /* * MM Cache Management diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index c2f1605..ccc3a2a 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -525,7 +525,7 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); #endif /* - * if PG_dcache_dirty is set for the page, we need to ensure that any + * If PG_dcache_clean is not set for the page, we need to ensure that any * cache entries for the kernels virtual memory range are written * back to the page. */ diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index 7370a71..34c9fe5 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -73,7 +73,7 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from, { void *kto = kmap_atomic(to, KM_USER1); - if (test_and_clear_bit(PG_dcache_dirty, &from->flags)) + if (!test_and_set_bit(PG_dcache_clean, &from->flags)) __flush_dcache_page(page_mapping(from), from); spin_lock(&minicache_lock); diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 0fa1319..7e0a050 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -86,7 +86,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to, unsigned int offset = CACHE_COLOUR(vaddr); unsigned long kfrom, kto; - if (test_and_clear_bit(PG_dcache_dirty, &from->flags)) + if (!test_and_set_bit(PG_dcache_clean, &from->flags)) __flush_dcache_page(page_mapping(from), from); /* FIXME: not highmem safe */ diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 76824d3..4c94ea3 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -95,7 +95,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from, { void *kto = kmap_atomic(to, KM_USER1); - if (test_and_clear_bit(PG_dcache_dirty, &from->flags)) + if (!test_and_set_bit(PG_dcache_clean, &from->flags)) __flush_dcache_page(page_mapping(from), from); spin_lock(&minicache_lock); diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index dcf1ecc..105a3a9 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -478,6 +478,11 @@ static void dma_cache_maint_contiguous(struct page *page, unsigned long offset, paddr = page_to_phys(page) + offset; outer_op(paddr, paddr + size); + + /* + * Mark the D-cache clean for this page to avoid extra flushing. + */ + set_bit(PG_dcache_clean, &page->flags); } void dma_cache_maint_page(struct page *page, unsigned long offset, diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 8b755ff..baa5742 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -136,7 +136,7 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigne * a page table, or changing an existing PTE. Basically, there are two * things that we need to take care of: * - * 1. If PG_dcache_dirty is set for the page, we need to ensure + * 1. If PG_dcache_clean is not set for the page, we need to ensure * that any cache entries for the kernels virtual memory * range are written back to the page. * 2. If we have multiple shared mappings of the same space in @@ -162,7 +162,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) return; mapping = page_mapping(page); - if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) + if (!test_and_set_bit(PG_dcache_clean, &page->flags)) __flush_dcache_page(mapping, page); if (mapping) { if (cache_is_vivt()) diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 834db87..b829d30 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -209,7 +209,7 @@ void flush_dcache_page(struct page *page) if (!cache_ops_need_broadcast() && !PageHighMem(page) && mapping && !mapping_mapped(mapping)) - set_bit(PG_dcache_dirty, &page->flags); + clear_bit(PG_dcache_clean, &page->flags); else { __flush_dcache_page(mapping, page); if (mapping && cache_is_vivt()) -- Catalin -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Russell King - ARM Linux on 4 Mar 2010 16:50 On Thu, Mar 04, 2010 at 06:36:42PM +0000, Catalin Marinas wrote: > ARM: Assume new page cache pages have dirty D-cache > > From: Catalin Marinas <catalin.marinas(a)arm.com> > > There are places in Linux where writes to newly allocated page cache > pages happen without a subsequent call to flush_dcache_page() (several > PIO drivers including USB HCD). This patch changes the meaning of > PG_arch_1 to be PG_dcache_clean and always flush the D-cache for a newly > mapped page in update_mmu_cache(). > > The patch also sets the PG_arch_1 bit in the DMA cache maintenance > function to avoid additional cache flushing in update_mmu_cache(). As I just realised, this is going to subject all pages placed into userspace with a D cache flush - even anonymous pages, and those which we've been careful to deal with the cache issues already (eg, via the COW page copying code.) I think all the copypage functions need to set PG_dcache_clean on the new pages once their copy has completed. I wonder if there's any other anonymous page creating functions which could do with a similar treatment... -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Paul Mundt on 4 Mar 2010 20:30
On Thu, Mar 04, 2010 at 09:44:35PM +0000, Russell King - ARM Linux wrote: > On Thu, Mar 04, 2010 at 06:36:42PM +0000, Catalin Marinas wrote: > > ARM: Assume new page cache pages have dirty D-cache > > > > From: Catalin Marinas <catalin.marinas(a)arm.com> > > > > There are places in Linux where writes to newly allocated page cache > > pages happen without a subsequent call to flush_dcache_page() (several > > PIO drivers including USB HCD). This patch changes the meaning of > > PG_arch_1 to be PG_dcache_clean and always flush the D-cache for a newly > > mapped page in update_mmu_cache(). > > > > The patch also sets the PG_arch_1 bit in the DMA cache maintenance > > function to avoid additional cache flushing in update_mmu_cache(). > > As I just realised, this is going to subject all pages placed into > userspace with a D cache flush - even anonymous pages, and those > which we've been careful to deal with the cache issues already (eg, > via the COW page copying code.) > > I think all the copypage functions need to set PG_dcache_clean on the > new pages once their copy has completed. > > I wonder if there's any other anonymous page creating functions which > could do with a similar treatment... In the anonymous page case, flush_anon_page() is always called prior to flush_dcache_page(), so flush_anon_page() could just set PG_dcache_clean to work around that. That would handle get_user_pages(), too. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ |