aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-04-12 02:48:25 -0400
committerVineet Gupta <vgupta@synopsys.com>2013-05-07 09:38:12 -0400
commit7586bf7286097cd47299c44192c30e01f0d55391 (patch)
tree34f071c6a0f34bd7c256e332550c25887d36fb81 /arch/arc
parent24603fdd19d978fcc0d089d92370ee1aa3a71e84 (diff)
ARC: [mm] optimise icache flush for kernel mappings
This change continues the theme from prev commit - this time icache handling for kernel's own code modification (vmalloc: loadable modules, breakpoints for kprobes/kgdb...) flush_icache_range() calls the CDU icache helper with vaddr to enable exact line invalidate. For a true kernel-virtual mapping, the vaddr is actually virtual hence valid as index into cache. For kprobes breakpoint however, the vaddr arg is actually paddr - since that's how normal kernel is mapped in ARC memory map. This implies that CDU will use the same addr for indexing as for tag match - which is fine since kernel code would only have that "implicit" mapping and none other. This should speed up module loading significantly - specially on default ARC700 icache configurations (32k) which alias. Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/mm/cache_arc700.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c
index a65c13942766..5651e7bd3b7e 100644
--- a/arch/arc/mm/cache_arc700.c
+++ b/arch/arc/mm/cache_arc700.c
@@ -642,8 +642,8 @@ void dma_cache_wback(unsigned long start, unsigned long sz)
642EXPORT_SYMBOL(dma_cache_wback); 642EXPORT_SYMBOL(dma_cache_wback);
643 643
644/* 644/*
645 * This is API for making I/D Caches consistent when modifying code 645 * This is API for making I/D Caches consistent when modifying
646 * (loadable modules, kprobes, etc) 646 * kernel code (loadable modules, kprobes, kgdb...)
647 * This is called on insmod, with kernel virtual address for CODE of 647 * This is called on insmod, with kernel virtual address for CODE of
648 * the module. ARC cache maintenance ops require PHY address thus we 648 * the module. ARC cache maintenance ops require PHY address thus we
649 * need to convert vmalloc addr to PHY addr 649 * need to convert vmalloc addr to PHY addr
@@ -673,7 +673,13 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
673 673
674 /* Case: Kernel Phy addr (0x8000_0000 onwards) */ 674 /* Case: Kernel Phy addr (0x8000_0000 onwards) */
675 if (likely(kstart > PAGE_OFFSET)) { 675 if (likely(kstart > PAGE_OFFSET)) {
676 __ic_line_inv(kstart, kend - kstart); 676 /*
677 * The 2nd arg despite being paddr will be used to index icache
678 * This is OK since no alternate virtual mappings will exist
679 * given the callers for this case: kprobe/kgdb in built-in
680 * kernel code only.
681 */
682 __ic_line_inv_vaddr(kstart, kstart, kend - kstart);
677 __dc_line_op(kstart, kend - kstart, OP_FLUSH); 683 __dc_line_op(kstart, kend - kstart, OP_FLUSH);
678 return; 684 return;
679 } 685 }
@@ -694,7 +700,7 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
694 sz = min_t(unsigned int, tot_sz, PAGE_SIZE - off); 700 sz = min_t(unsigned int, tot_sz, PAGE_SIZE - off);
695 local_irq_save(flags); 701 local_irq_save(flags);
696 __dc_line_op(phy, sz, OP_FLUSH); 702 __dc_line_op(phy, sz, OP_FLUSH);
697 __ic_line_inv(phy, sz); 703 __ic_line_inv_vaddr(phy, kstart, sz);
698 local_irq_restore(flags); 704 local_irq_restore(flags);
699 kstart += sz; 705 kstart += sz;
700 tot_sz -= sz; 706 tot_sz -= sz;