aboutsummaryrefslogtreecommitdiffstats
path: root/mm/huge_memory.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-12-02 14:56:50 -0500
committerMel Gorman <mgorman@suse.de>2012-12-11 09:43:00 -0500
commit4fc3f1d66b1ef0d7b8dc11f4ff1cc510f78b37d6 (patch)
tree90baaa56f6b5244525c7637a14550f830486112a /mm/huge_memory.c
parent5a505085f043e8380f83610f79642853c051e2f1 (diff)
mm/rmap, migration: Make rmap_walk_anon() and try_to_unmap_anon() more scalable
rmap_walk_anon() and try_to_unmap_anon() appears to be too careful about locking the anon vma: while it needs protection against anon vma list modifications, it does not need exclusive access to the list itself. Transforming this exclusive lock to a read-locked rwsem removes a global lock from the hot path of page-migration intense threaded workloads which can cause pathological performance like this: 96.43% process 0 [kernel.kallsyms] [k] perf_trace_sched_switch | --- perf_trace_sched_switch __schedule schedule schedule_preempt_disabled __mutex_lock_common.isra.6 __mutex_lock_slowpath mutex_lock | |--50.61%-- rmap_walk | move_to_new_page | migrate_pages | migrate_misplaced_page | __do_numa_page.isra.69 | handle_pte_fault | handle_mm_fault | __do_page_fault | do_page_fault | page_fault | __memset_sse2 | | | --100.00%-- worker_thread | | | --100.00%-- start_thread | --49.39%-- page_lock_anon_vma try_to_unmap_anon try_to_unmap migrate_pages migrate_misplaced_page __do_numa_page.isra.69 handle_pte_fault handle_mm_fault __do_page_fault do_page_fault page_fault __memset_sse2 | --100.00%-- worker_thread start_thread With this change applied the profile is now nicely flat and there's no anon-vma related scheduling/blocking. Rename anon_vma_[un]lock() => anon_vma_[un]lock_write(), to make it clearer that it's an exclusive write-lock in that case - suggested by Rik van Riel. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Turner <pjt@google.com> Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com> Cc: Christoph Lameter <cl@linux.com> Cc: Rik van Riel <riel@redhat.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Hugh Dickins <hughd@google.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Mel Gorman <mgorman@suse.de>
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r--mm/huge_memory.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index acd37fe55eb7..a24c9cb9c83e 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1549,7 +1549,7 @@ int split_huge_page(struct page *page)
1549 int ret = 1; 1549 int ret = 1;
1550 1550
1551 BUG_ON(!PageAnon(page)); 1551 BUG_ON(!PageAnon(page));
1552 anon_vma = page_lock_anon_vma(page); 1552 anon_vma = page_lock_anon_vma_read(page);
1553 if (!anon_vma) 1553 if (!anon_vma)
1554 goto out; 1554 goto out;
1555 ret = 0; 1555 ret = 0;
@@ -1562,7 +1562,7 @@ int split_huge_page(struct page *page)
1562 1562
1563 BUG_ON(PageCompound(page)); 1563 BUG_ON(PageCompound(page));
1564out_unlock: 1564out_unlock:
1565 page_unlock_anon_vma(anon_vma); 1565 page_unlock_anon_vma_read(anon_vma);
1566out: 1566out:
1567 return ret; 1567 return ret;
1568} 1568}
@@ -2074,7 +2074,7 @@ static void collapse_huge_page(struct mm_struct *mm,
2074 if (!pmd_present(*pmd) || pmd_trans_huge(*pmd)) 2074 if (!pmd_present(*pmd) || pmd_trans_huge(*pmd))
2075 goto out; 2075 goto out;
2076 2076
2077 anon_vma_lock(vma->anon_vma); 2077 anon_vma_lock_write(vma->anon_vma);
2078 2078
2079 pte = pte_offset_map(pmd, address); 2079 pte = pte_offset_map(pmd, address);
2080 ptl = pte_lockptr(mm, pmd); 2080 ptl = pte_lockptr(mm, pmd);