diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-12-02 14:56:50 -0500 |
---|---|---|
committer | Mel Gorman <mgorman@suse.de> | 2012-12-11 09:43:00 -0500 |
commit | 4fc3f1d66b1ef0d7b8dc11f4ff1cc510f78b37d6 (patch) | |
tree | 90baaa56f6b5244525c7637a14550f830486112a /mm/huge_memory.c | |
parent | 5a505085f043e8380f83610f79642853c051e2f1 (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.c | 6 |
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)); |
1564 | out_unlock: | 1564 | out_unlock: |
1565 | page_unlock_anon_vma(anon_vma); | 1565 | page_unlock_anon_vma_read(anon_vma); |
1566 | out: | 1566 | out: |
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); |