diff options
author | Mel Gorman <mgorman@suse.de> | 2013-10-07 06:28:50 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-10-09 06:39:50 -0400 |
commit | a1a46184e34cfd0764f06a54870defa052b0a094 (patch) | |
tree | b4d12f1d23963fb3de14cf8d81f7979c4f58d95a /mm | |
parent | f123d74abf91574837d14e5ea58f6a779a387bf5 (diff) |
mm: numa: Do not migrate or account for hinting faults on the zero page
The zero page is not replicated between nodes and is often shared between
processes. The data is read-only and likely to be cached in local CPUs
if heavily accessed meaning that the remote memory access cost is less
of a concern. This patch prevents trapping faults on the zero pages. For
tasks using the zero page this will reduce the number of PTE updates,
TLB flushes and hinting faults.
Signed-off-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
[ Correct use of is_huge_zero_page]
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1381141781-10992-13-git-send-email-mgorman@suse.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/huge_memory.c | 10 | ||||
-rw-r--r-- | mm/memory.c | 1 |
2 files changed, 10 insertions, 1 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index de8d5cfc2bf2..8677dbf31c2e 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1291,6 +1291,7 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1291 | goto out_unlock; | 1291 | goto out_unlock; |
1292 | 1292 | ||
1293 | page = pmd_page(pmd); | 1293 | page = pmd_page(pmd); |
1294 | BUG_ON(is_huge_zero_page(page)); | ||
1294 | page_nid = page_to_nid(page); | 1295 | page_nid = page_to_nid(page); |
1295 | count_vm_numa_event(NUMA_HINT_FAULTS); | 1296 | count_vm_numa_event(NUMA_HINT_FAULTS); |
1296 | if (page_nid == this_nid) | 1297 | if (page_nid == this_nid) |
@@ -1481,8 +1482,15 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, | |||
1481 | } else { | 1482 | } else { |
1482 | struct page *page = pmd_page(*pmd); | 1483 | struct page *page = pmd_page(*pmd); |
1483 | 1484 | ||
1484 | /* only check non-shared pages */ | 1485 | /* |
1486 | * Only check non-shared pages. Do not trap faults | ||
1487 | * against the zero page. The read-only data is likely | ||
1488 | * to be read-cached on the local CPU cache and it is | ||
1489 | * less useful to know about local vs remote hits on | ||
1490 | * the zero page. | ||
1491 | */ | ||
1485 | if (page_mapcount(page) == 1 && | 1492 | if (page_mapcount(page) == 1 && |
1493 | !is_huge_zero_page(page) && | ||
1486 | !pmd_numa(*pmd)) { | 1494 | !pmd_numa(*pmd)) { |
1487 | entry = pmdp_get_and_clear(mm, addr, pmd); | 1495 | entry = pmdp_get_and_clear(mm, addr, pmd); |
1488 | entry = pmd_mknuma(entry); | 1496 | entry = pmd_mknuma(entry); |
diff --git a/mm/memory.c b/mm/memory.c index 42ae82ee04c1..ed51f15136ee 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -3564,6 +3564,7 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3564 | pte_unmap_unlock(ptep, ptl); | 3564 | pte_unmap_unlock(ptep, ptl); |
3565 | return 0; | 3565 | return 0; |
3566 | } | 3566 | } |
3567 | BUG_ON(is_zero_pfn(page_to_pfn(page))); | ||
3567 | 3568 | ||
3568 | page_nid = page_to_nid(page); | 3569 | page_nid = page_to_nid(page); |
3569 | target_nid = numa_migrate_prep(page, vma, addr, page_nid); | 3570 | target_nid = numa_migrate_prep(page, vma, addr, page_nid); |