aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-17 14:59:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-17 14:59:04 -0500
commitf045bbb9fa1bf6f507ad4de12d4e3471d8f672f1 (patch)
tree285dc114754f7a6acd5dde5eac5a628bdd14598e /mm/memory.c
parentcf3c0a1579eff90195a791c5f464463c1011ef4a (diff)
mmu_gather: fix over-eager tlb_flush_mmu_free() calling
Dave Hansen reports that commit fb7332a9fedf ("mmu_gather: move minimal range calculations into generic code") caused a performance problem: "tlb_finish_mmu() goes up about 9x in the profiles (~0.4%->3.6%) and tlb_flush_mmu_free() takes about 3.1% of CPU time with the patch applied, but does not show up at all on the commit before" and the reason is that Will moved the test for whether we need to flush from tlb_flush_mmu() into tlb_flush_mmu_tlbonly(). But that meant that tlb_flush_mmu_free() basically lost that check. Move it back into tlb_flush_mmu() where it belongs, so that it covers both tlb_flush_mmu_tlbonly() _and_ tlb_flush_mmu_free(). Reported-and-tested-by: Dave Hansen <dave@sr71.net> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/mm/memory.c b/mm/memory.c
index c3b9097251c5..6efe36a998ba 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -235,9 +235,6 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long
235 235
236static void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) 236static void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
237{ 237{
238 if (!tlb->end)
239 return;
240
241 tlb_flush(tlb); 238 tlb_flush(tlb);
242 mmu_notifier_invalidate_range(tlb->mm, tlb->start, tlb->end); 239 mmu_notifier_invalidate_range(tlb->mm, tlb->start, tlb->end);
243#ifdef CONFIG_HAVE_RCU_TABLE_FREE 240#ifdef CONFIG_HAVE_RCU_TABLE_FREE
@@ -259,6 +256,9 @@ static void tlb_flush_mmu_free(struct mmu_gather *tlb)
259 256
260void tlb_flush_mmu(struct mmu_gather *tlb) 257void tlb_flush_mmu(struct mmu_gather *tlb)
261{ 258{
259 if (!tlb->end)
260 return;
261
262 tlb_flush_mmu_tlbonly(tlb); 262 tlb_flush_mmu_tlbonly(tlb);
263 tlb_flush_mmu_free(tlb); 263 tlb_flush_mmu_free(tlb);
264} 264}