diff options
author | Doug Doan <dougd@cray.com> | 2010-08-09 20:18:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-09 23:44:54 -0400 |
commit | 3edd4fc9537d95e460d502987c63a90d6b9a7a82 (patch) | |
tree | fe0563459b9d6104dcc7f7ab6f8945e815f09665 /mm/hugetlb.c | |
parent | a1b200e27c0426ea98c1231a2b78c6094eb073e4 (diff) |
hugetlb: call mmu notifiers on hugepage cow
When a copy-on-write occurs, we take one of two paths in handle_mm_fault:
through handle_pte_fault for normal pages, or through hugetlb_fault for
huge pages.
In the normal page case, we eventually get to do_wp_page and call mmu
notifiers via ptep_clear_flush_notify. There is no callout to the mmmu
notifiers in the huge page case. This patch fixes that.
Signed-off-by: Doug Doan <dougd@cray.com>
Acked-by: Mel Gorman <mel@csn.ul.ie>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r-- | mm/hugetlb.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 54d42b009dbe..b61d2db9f34e 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -2349,11 +2349,17 @@ retry_avoidcopy: | |||
2349 | ptep = huge_pte_offset(mm, address & huge_page_mask(h)); | 2349 | ptep = huge_pte_offset(mm, address & huge_page_mask(h)); |
2350 | if (likely(pte_same(huge_ptep_get(ptep), pte))) { | 2350 | if (likely(pte_same(huge_ptep_get(ptep), pte))) { |
2351 | /* Break COW */ | 2351 | /* Break COW */ |
2352 | mmu_notifier_invalidate_range_start(mm, | ||
2353 | address & huge_page_mask(h), | ||
2354 | (address & huge_page_mask(h)) + huge_page_size(h)); | ||
2352 | huge_ptep_clear_flush(vma, address, ptep); | 2355 | huge_ptep_clear_flush(vma, address, ptep); |
2353 | set_huge_pte_at(mm, address, ptep, | 2356 | set_huge_pte_at(mm, address, ptep, |
2354 | make_huge_pte(vma, new_page, 1)); | 2357 | make_huge_pte(vma, new_page, 1)); |
2355 | /* Make the old page be freed below */ | 2358 | /* Make the old page be freed below */ |
2356 | new_page = old_page; | 2359 | new_page = old_page; |
2360 | mmu_notifier_invalidate_range_end(mm, | ||
2361 | address & huge_page_mask(h), | ||
2362 | (address & huge_page_mask(h)) + huge_page_size(h)); | ||
2357 | } | 2363 | } |
2358 | page_cache_release(new_page); | 2364 | page_cache_release(new_page); |
2359 | page_cache_release(old_page); | 2365 | page_cache_release(old_page); |