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/ksm.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/ksm.c')
-rw-r--r-- | mm/ksm.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -1634,7 +1634,7 @@ again: | |||
1634 | struct anon_vma_chain *vmac; | 1634 | struct anon_vma_chain *vmac; |
1635 | struct vm_area_struct *vma; | 1635 | struct vm_area_struct *vma; |
1636 | 1636 | ||
1637 | anon_vma_lock(anon_vma); | 1637 | anon_vma_lock_write(anon_vma); |
1638 | anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, | 1638 | anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, |
1639 | 0, ULONG_MAX) { | 1639 | 0, ULONG_MAX) { |
1640 | vma = vmac->vma; | 1640 | vma = vmac->vma; |
@@ -1688,7 +1688,7 @@ again: | |||
1688 | struct anon_vma_chain *vmac; | 1688 | struct anon_vma_chain *vmac; |
1689 | struct vm_area_struct *vma; | 1689 | struct vm_area_struct *vma; |
1690 | 1690 | ||
1691 | anon_vma_lock(anon_vma); | 1691 | anon_vma_lock_write(anon_vma); |
1692 | anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, | 1692 | anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, |
1693 | 0, ULONG_MAX) { | 1693 | 0, ULONG_MAX) { |
1694 | vma = vmac->vma; | 1694 | vma = vmac->vma; |
@@ -1741,7 +1741,7 @@ again: | |||
1741 | struct anon_vma_chain *vmac; | 1741 | struct anon_vma_chain *vmac; |
1742 | struct vm_area_struct *vma; | 1742 | struct vm_area_struct *vma; |
1743 | 1743 | ||
1744 | anon_vma_lock(anon_vma); | 1744 | anon_vma_lock_write(anon_vma); |
1745 | anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, | 1745 | anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, |
1746 | 0, ULONG_MAX) { | 1746 | 0, ULONG_MAX) { |
1747 | vma = vmac->vma; | 1747 | vma = vmac->vma; |