* [RFC PATCH 0/3] ARM: flush_dcache_page/update_mmu_cache reimplementation
@ 2010-05-13 11:15 Catalin Marinas
2010-05-13 11:15 ` [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMP systems Catalin Marinas
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Catalin Marinas @ 2010-05-13 11:15 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
These patches are meant to fix several cache coherency issues with PIO
drivers on the ARM implementation. The code change is relatively small.
It follows some ideas from the IA-64 and PowerPC implementations where
the PG_arch_1 bit means "clean" rather than "dirty" D-cache for a given
page. The main difference is the that we do not do the cache flushing in
set_pte_at() but keep it in update_mmu_cache() and deferring the
L_PTE_EXEC attribute setting (the NX hardware bit clearing).
Even if cache flushing would be done in set_pte_at(), on SMP systems we
would still have a small window between setting the PTE and flushing the
caches so the same NX/no-NX pte setting would need to be followed.
Catalin Marinas (3):
ARM: Use lazy cache flushing on ARMv7 SMP systems
ARM: Assume new page cache pages have dirty D-cache
ARM: Defer the L_PTE_EXEC flag setting to update_mmu_cache() on SMP
arch/arm/include/asm/cacheflush.h | 6 +++---
arch/arm/include/asm/pgtable.h | 12 ++++++++++++
arch/arm/include/asm/smp_plat.h | 4 ++++
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 | 6 ++++++
arch/arm/mm/fault-armv.c | 21 +++++++++++++--------
arch/arm/mm/flush.c | 15 +++++----------
10 files changed, 47 insertions(+), 25 deletions(-)
--
Catalin
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMP systems
2010-05-13 11:15 [RFC PATCH 0/3] ARM: flush_dcache_page/update_mmu_cache reimplementation Catalin Marinas
@ 2010-05-13 11:15 ` Catalin Marinas
2010-05-13 11:32 ` Russell King - ARM Linux
2010-05-13 11:16 ` [RFC PATCH 2/3] ARM: Assume new page cache pages have dirty D-cache Catalin Marinas
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Catalin Marinas @ 2010-05-13 11:15 UTC (permalink / raw)
To: linux-arm-kernel
ARMv7 processors like Cortex-A9 broadcast the cache maintenance
operations in hardware. This patch allows the
flush_dcache_page/update_mmu_cache pair to work in lazy flushing mode
similar to the UP case.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/include/asm/smp_plat.h | 4 ++++
arch/arm/mm/fault-armv.c | 2 --
arch/arm/mm/flush.c | 13 ++++---------
3 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
index e621530..963a338 100644
--- a/arch/arm/include/asm/smp_plat.h
+++ b/arch/arm/include/asm/smp_plat.h
@@ -13,9 +13,13 @@ static inline int tlb_ops_need_broadcast(void)
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
}
+#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
+#define cache_ops_need_broadcast() 0
+#else
static inline int cache_ops_need_broadcast(void)
{
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
}
+#endif
#endif
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 0d414c2..a415dc0 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -170,10 +170,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
return;
mapping = page_mapping(page);
-#ifndef CONFIG_SMP
if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
__flush_dcache_page(mapping, page);
-#endif
if (mapping) {
if (cache_is_vivt())
make_coherent(mapping, vma, addr, ptep, pfn);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index c6844cb..5ad8711 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -17,6 +17,7 @@
#include <asm/smp_plat.h>
#include <asm/system.h>
#include <asm/tlbflush.h>
+#include <asm/smp_plat.h>
#include "mm.h"
@@ -93,12 +94,10 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
#define flush_pfn_alias(pfn,vaddr) do { } while (0)
#endif
-#ifdef CONFIG_SMP
static void flush_ptrace_access_other(void *args)
{
__flush_icache_all();
}
-#endif
static
void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
@@ -122,11 +121,9 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
if (vma->vm_flags & VM_EXEC) {
unsigned long addr = (unsigned long)kaddr;
__cpuc_coherent_kern_range(addr, addr + len);
-#ifdef CONFIG_SMP
if (cache_ops_need_broadcast())
smp_call_function(flush_ptrace_access_other,
NULL, 1);
-#endif
}
}
@@ -246,12 +243,10 @@ void flush_dcache_page(struct page *page)
mapping = page_mapping(page);
-#ifndef CONFIG_SMP
- if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
+ if (!cache_ops_need_broadcast() &&
+ !PageHighMem(page) && mapping && !mapping_mapped(mapping))
set_bit(PG_dcache_dirty, &page->flags);
- else
-#endif
- {
+ else {
__flush_dcache_page(mapping, page);
if (mapping && cache_is_vivt())
__flush_dcache_aliases(mapping, page);
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH 2/3] ARM: Assume new page cache pages have dirty D-cache
2010-05-13 11:15 [RFC PATCH 0/3] ARM: flush_dcache_page/update_mmu_cache reimplementation Catalin Marinas
2010-05-13 11:15 ` [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMP systems Catalin Marinas
@ 2010-05-13 11:16 ` Catalin Marinas
2010-05-13 11:16 ` [RFC PATCH 3/3] ARM: Defer the L_PTE_EXEC flag setting to update_mmu_cache() on SMP Catalin Marinas
2010-05-13 11:22 ` [RFC PATCH] ARM: Allow lazy cache flushing on ARM11MPCore Catalin Marinas
3 siblings, 0 replies; 8+ messages in thread
From: Catalin Marinas @ 2010-05-13 11:16 UTC (permalink / raw)
To: linux-arm-kernel
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@arm.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 | 6 ++++++
arch/arm/mm/fault-armv.c | 4 ++--
arch/arm/mm/flush.c | 2 +-
8 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 4656a24..d3730f0 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 bd863d8..40a7092 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -552,7 +552,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 598c51a..b806151 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 f55fa10..bdba6c6 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -79,7 +79,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 9920c0a..649bbcd 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 c4de90f..835bb96 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -510,6 +510,12 @@ void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
outer_inv_range(paddr, paddr + size);
dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
+
+ /*
+ * Mark the D-cache clean for this page to avoid extra flushing.
+ */
+ if (dir != DMA_TO_DEVICE)
+ set_bit(PG_dcache_clean, &page->flags);
}
EXPORT_SYMBOL(___dma_page_dev_to_cpu);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index a415dc0..f9e9cbb 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -143,7 +143,7 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
* 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
@@ -170,7 +170,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
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 5ad8711..5abab9a 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -245,7 +245,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())
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH 3/3] ARM: Defer the L_PTE_EXEC flag setting to update_mmu_cache() on SMP
2010-05-13 11:15 [RFC PATCH 0/3] ARM: flush_dcache_page/update_mmu_cache reimplementation Catalin Marinas
2010-05-13 11:15 ` [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMP systems Catalin Marinas
2010-05-13 11:16 ` [RFC PATCH 2/3] ARM: Assume new page cache pages have dirty D-cache Catalin Marinas
@ 2010-05-13 11:16 ` Catalin Marinas
2010-05-13 11:22 ` [RFC PATCH] ARM: Allow lazy cache flushing on ARM11MPCore Catalin Marinas
3 siblings, 0 replies; 8+ messages in thread
From: Catalin Marinas @ 2010-05-13 11:16 UTC (permalink / raw)
To: linux-arm-kernel
On SMP systems, there is a small chance of a PTE becoming visible to a
different CPU before the cache maintenance operations in
update_mmu_cache(). This patch clears the L_PTE_EXEC bit in set_pte_at()
but sets it later in update_mmu_cache() if vm_flags & VM_EXEC.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/include/asm/pgtable.h | 12 ++++++++++++
arch/arm/mm/fault-armv.c | 17 ++++++++++++-----
2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 1139768..4328105 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -278,9 +278,21 @@ extern struct page *empty_zero_page;
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
+#ifndef CONFIG_SMP
#define set_pte_at(mm,addr,ptep,pteval) do { \
set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
} while (0)
+#else
+/*
+ * The L_PTE_EXEC attribute is later be set in update_mmu_cache() to avoid a
+ * race with SMP systems executing from the new mapping before the cache
+ * flushing took place.
+ */
+#define set_pte_at(mm,addr,ptep,pteval) do { \
+ set_pte_ext(ptep, __pte(pte_val(pteval) & ~L_PTE_EXEC), \
+ (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
+ } while (0)
+#endif
/*
* The following only work if pte_present() is true.
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index f9e9cbb..c01356d 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -172,11 +172,18 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
mapping = page_mapping(page);
if (!test_and_set_bit(PG_dcache_clean, &page->flags))
__flush_dcache_page(mapping, page);
- if (mapping) {
- if (cache_is_vivt())
- make_coherent(mapping, vma, addr, ptep, pfn);
- else if (vma->vm_flags & VM_EXEC)
- __flush_icache_all();
+ if (!mapping)
+ return;
+
+ if (cache_is_vivt())
+ make_coherent(mapping, vma, addr, ptep, pfn);
+ else if (vma->vm_flags & VM_EXEC) {
+ __flush_icache_all();
+#ifdef CONFIG_SMP
+ set_pte_ext(ptep, __pte(pte_val(*ptep) | L_PTE_EXEC),
+ addr >= TASK_SIZE ? 0 : PTE_EXT_NG);
+ flush_tlb_page(vma, addr);
+#endif
}
}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH] ARM: Allow lazy cache flushing on ARM11MPCore
2010-05-13 11:15 [RFC PATCH 0/3] ARM: flush_dcache_page/update_mmu_cache reimplementation Catalin Marinas
` (2 preceding siblings ...)
2010-05-13 11:16 ` [RFC PATCH 3/3] ARM: Defer the L_PTE_EXEC flag setting to update_mmu_cache() on SMP Catalin Marinas
@ 2010-05-13 11:22 ` Catalin Marinas
2010-05-13 11:44 ` Catalin Marinas
3 siblings, 1 reply; 8+ messages in thread
From: Catalin Marinas @ 2010-05-13 11:22 UTC (permalink / raw)
To: linux-arm-kernel
(we could actually go a step further for ARM11MPCore as well.
This patch is not part of the initial cache flush reworking
series but I'm posting it for comments as well)
The ARM11MPCore doesn't broadcast the cache maintenance operations in
hardware, therefore the flush_dcache_page() currently performs the cache
flushing non-lazily. But since not all drivers call this function after
writing to a page cache page, the kernel needs a different approach like
using read-for-ownership on the CPU flushing the cache to force the
dirty cache lines migration from other CPUs. This way the cache flushing
operation can be done lazily in update_mmu_cache().
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/include/asm/smp_plat.h | 9 ---------
arch/arm/mm/cache-v6.S | 4 ++++
arch/arm/mm/flush.c | 3 +--
3 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
index 963a338..59303e2 100644
--- a/arch/arm/include/asm/smp_plat.h
+++ b/arch/arm/include/asm/smp_plat.h
@@ -13,13 +13,4 @@ static inline int tlb_ops_need_broadcast(void)
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
}
-#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
-#define cache_ops_need_broadcast() 0
-#else
-static inline int cache_ops_need_broadcast(void)
-{
- return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
-}
-#endif
-
#endif
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index e46ecd8..a4a6840 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -170,6 +170,10 @@ ENDPROC(v6_coherent_kern_range)
ENTRY(v6_flush_kern_dcache_area)
add r1, r0, r1
1:
+#ifdef CONFIG_SMP
+ /* no cache maintenance broadcasting on ARM11MPCore */
+ ldr r2, [r0] @ read for ownership
+#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
#else
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 5abab9a..7d8b261 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -243,8 +243,7 @@ void flush_dcache_page(struct page *page)
mapping = page_mapping(page);
- if (!cache_ops_need_broadcast() &&
- !PageHighMem(page) && mapping && !mapping_mapped(mapping))
+ if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
clear_bit(PG_dcache_clean, &page->flags);
else {
__flush_dcache_page(mapping, page);
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMP systems
2010-05-13 11:15 ` [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMP systems Catalin Marinas
@ 2010-05-13 11:32 ` Russell King - ARM Linux
2010-05-13 11:42 ` [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMPsystems Catalin Marinas
0 siblings, 1 reply; 8+ messages in thread
From: Russell King - ARM Linux @ 2010-05-13 11:32 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, May 13, 2010 at 12:15:55PM +0100, Catalin Marinas wrote:
> diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
> index 0d414c2..a415dc0 100644
> --- a/arch/arm/mm/fault-armv.c
> +++ b/arch/arm/mm/fault-armv.c
> @@ -170,10 +170,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
> return;
>
> mapping = page_mapping(page);
> -#ifndef CONFIG_SMP
> if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
> __flush_dcache_page(mapping, page);
> -#endif
> if (mapping) {
> if (cache_is_vivt())
> make_coherent(mapping, vma, addr, ptep, pfn);
> diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
> index c6844cb..5ad8711 100644
> --- a/arch/arm/mm/flush.c
> +++ b/arch/arm/mm/flush.c
> @@ -17,6 +17,7 @@
> #include <asm/smp_plat.h>
> #include <asm/system.h>
> #include <asm/tlbflush.h>
> +#include <asm/smp_plat.h>
>
> #include "mm.h"
>
> @@ -93,12 +94,10 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
> #define flush_pfn_alias(pfn,vaddr) do { } while (0)
> #endif
>
> -#ifdef CONFIG_SMP
> static void flush_ptrace_access_other(void *args)
> {
> __flush_icache_all();
> }
> -#endif
>
> static
> void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
> @@ -122,11 +121,9 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
> if (vma->vm_flags & VM_EXEC) {
> unsigned long addr = (unsigned long)kaddr;
> __cpuc_coherent_kern_range(addr, addr + len);
> -#ifdef CONFIG_SMP
> if (cache_ops_need_broadcast())
> smp_call_function(flush_ptrace_access_other,
> NULL, 1);
> -#endif
Err. __cpuc_coherent_kern_range() makes the cache lines coherent between
the data and instruction threads. So what you're doing is:
1. flush the D and I caches for the affected cache lines on the local
processor
2. flush the entire I cache on the local processor
Why?
This has absolutely nothing to do with the rest of the patch.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMPsystems
2010-05-13 11:32 ` Russell King - ARM Linux
@ 2010-05-13 11:42 ` Catalin Marinas
0 siblings, 0 replies; 8+ messages in thread
From: Catalin Marinas @ 2010-05-13 11:42 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-05-13 at 12:32 +0100, Russell King - ARM Linux wrote:
> On Thu, May 13, 2010 at 12:15:55PM +0100, Catalin Marinas wrote:
> > diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
> > index c6844cb..5ad8711 100644
> > --- a/arch/arm/mm/flush.c
> > +++ b/arch/arm/mm/flush.c
> > @@ -17,6 +17,7 @@
> > #include <asm/smp_plat.h>
> > #include <asm/system.h>
> > #include <asm/tlbflush.h>
> > +#include <asm/smp_plat.h>
> >
> > #include "mm.h"
> >
> > @@ -93,12 +94,10 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
> > #define flush_pfn_alias(pfn,vaddr) do { } while (0)
> > #endif
> >
> > -#ifdef CONFIG_SMP
> > static void flush_ptrace_access_other(void *args)
> > {
> > __flush_icache_all();
> > }
> > -#endif
> >
> > static
> > void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
> > @@ -122,11 +121,9 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
> > if (vma->vm_flags & VM_EXEC) {
> > unsigned long addr = (unsigned long)kaddr;
> > __cpuc_coherent_kern_range(addr, addr + len);
> > -#ifdef CONFIG_SMP
> > if (cache_ops_need_broadcast())
> > smp_call_function(flush_ptrace_access_other,
> > NULL, 1);
> > -#endif
>
> Err. __cpuc_coherent_kern_range() makes the cache lines coherent between
> the data and instruction threads. So what you're doing is:
>
> 1. flush the D and I caches for the affected cache lines on the local
> processor
> 2. flush the entire I cache on the local processor
This should be "flush the entire I cache on the other processors".
> Why?
I don't think my patch changes the current flush_ptrace_access()
behaviour. It just removes the #ifdef CONFIG_SMP since
cache_ops_need_broadcast() is 0 anyway on !SMP and the code compiled
out.
The current behaviour is needed on ARM11MPCore (and I now realised that
my 4th patch for ARM11MPCore is slightly wrong) since the I-cache
maintenance isn't visible to the other CPUs (and you miss breakpoints
when gdb and the debugged app are on different processors).
--
Catalin
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC PATCH] ARM: Allow lazy cache flushing on ARM11MPCore
2010-05-13 11:22 ` [RFC PATCH] ARM: Allow lazy cache flushing on ARM11MPCore Catalin Marinas
@ 2010-05-13 11:44 ` Catalin Marinas
0 siblings, 0 replies; 8+ messages in thread
From: Catalin Marinas @ 2010-05-13 11:44 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-05-13 at 12:22 +0100, Catalin Marinas wrote:
> diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
> index 963a338..59303e2 100644
> --- a/arch/arm/include/asm/smp_plat.h
> +++ b/arch/arm/include/asm/smp_plat.h
> @@ -13,13 +13,4 @@ static inline int tlb_ops_need_broadcast(void)
> return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
> }
>
> -#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
> -#define cache_ops_need_broadcast() 0
> -#else
> -static inline int cache_ops_need_broadcast(void)
> -{
> - return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
> -}
> -#endif
> -
> #endif
This hunk shouldn't be part of the patch since ptrace flushing still
checks for cache_ops_need_broadcast().
--
Catalin
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-05-13 11:44 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-13 11:15 [RFC PATCH 0/3] ARM: flush_dcache_page/update_mmu_cache reimplementation Catalin Marinas
2010-05-13 11:15 ` [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMP systems Catalin Marinas
2010-05-13 11:32 ` Russell King - ARM Linux
2010-05-13 11:42 ` [RFC PATCH 1/3] ARM: Use lazy cache flushing on ARMv7 SMPsystems Catalin Marinas
2010-05-13 11:16 ` [RFC PATCH 2/3] ARM: Assume new page cache pages have dirty D-cache Catalin Marinas
2010-05-13 11:16 ` [RFC PATCH 3/3] ARM: Defer the L_PTE_EXEC flag setting to update_mmu_cache() on SMP Catalin Marinas
2010-05-13 11:22 ` [RFC PATCH] ARM: Allow lazy cache flushing on ARM11MPCore Catalin Marinas
2010-05-13 11:44 ` Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).