summaryrefslogtreecommitdiff
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorKrishna Reddy <vdumpa@nvidia.com>2011-12-02 12:40:21 -0800
committerVarun Colbert <vcolbert@nvidia.com>2012-01-19 16:16:24 -0800
commit7d198798dd246d0b20e06d6f933e96cfde3b60fd (patch)
tree2bdd26cde53656ba1b2749465b0e9bb18cee76ac /arch/arm/mm
parent24f020cec2e6c3328620ad0c43e171c59f648370 (diff)
arm: mm: Optimze cache flush in CPA.
Optimze cache flush time and enable cache flush for high mem pages in CPA. Bug 865816 Change-Id: I15736010bd26c18ea0d3350c15769675f07ac055 Reviewed-on: http://git-master/r/71725 Signed-off-by: Krishna Reddy <vdumpa@nvidia.com> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/75880 Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/pageattr.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c
index 098b957454f6..2026c5100473 100644
--- a/arch/arm/mm/pageattr.c
+++ b/arch/arm/mm/pageattr.c
@@ -29,6 +29,10 @@
#define cpa_debug(x, ...)
#endif
+#define FLUSH_CLEAN_BY_SET_WAY_PAGE_THRESHOLD 8
+extern void v7_flush_kern_cache_all(void *);
+extern void __flush_dcache_page(struct address_space *, struct page *);
+
/*
* The current flushing context - we pass it instead of 5 arguments:
*/
@@ -125,13 +129,26 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache)
}
}
+static void inner_flush_cache_all(void)
+{
+ on_each_cpu(v7_flush_kern_cache_all, NULL, 1);
+}
+
static void cpa_flush_array(unsigned long *start, int numpages, int cache,
int in_flags, struct page **pages)
{
unsigned int i, level;
+ bool flush_inner = true;
+ unsigned long base;
BUG_ON(irqs_disabled());
+ if (numpages >= FLUSH_CLEAN_BY_SET_WAY_PAGE_THRESHOLD &&
+ cache && in_flags & CPA_PAGES_ARRAY) {
+ inner_flush_cache_all();
+ flush_inner = false;
+ }
+
for (i = 0; i < numpages; i++) {
unsigned long addr;
pte_t *pte;
@@ -143,8 +160,14 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache,
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (cache) {
-
+ if (cache && in_flags & CPA_PAGES_ARRAY) {
+ /* cache flush all pages including high mem pages. */
+ if (flush_inner)
+ __flush_dcache_page(
+ page_mapping(pages[i]), pages[i]);
+ base = page_to_phys(pages[i]);
+ outer_flush_range(base, base + PAGE_SIZE);
+ } else if (cache) {
pte = lookup_address(addr, &level);
/*
@@ -795,14 +818,14 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
ret = __change_page_attr_set_clr(&cpa, checkalias);
+ cache = cache_attr(mask_set);
/*
- * Check whether we really changed something:
+ * Check whether we really changed something or
+ * cache need to be flushed.
*/
- if (!(cpa.flags & CPA_FLUSHTLB))
+ if (!(cpa.flags & CPA_FLUSHTLB) && !cache)
goto out;
- cache = cache_attr(mask_set);
-
if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) {
cpa_flush_array(addr, numpages, cache,
cpa.flags, pages);