diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:23:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:23:15 -0400 |
commit | 9e2d8656f5e8aa214e66b462680cf86b210b74a8 (patch) | |
tree | f67d62e896cedf75599ea45f9ecf9999c6ad24cd /mm/hugetlb.c | |
parent | 1ea4f4f8405cc1ceec23f2d261bc3775785e6712 (diff) | |
parent | 9e695d2ecc8451cc2c1603d60b5c8e7f5581923a (diff) |
Merge branch 'akpm' (Andrew's patch-bomb)
Merge patches from Andrew Morton:
"A few misc things and very nearly all of the MM tree. A tremendous
amount of stuff (again), including a significant rbtree library
rework."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (160 commits)
sparc64: Support transparent huge pages.
mm: thp: Use more portable PMD clearing sequenece in zap_huge_pmd().
mm: Add and use update_mmu_cache_pmd() in transparent huge page code.
sparc64: Document PGD and PMD layout.
sparc64: Eliminate PTE table memory wastage.
sparc64: Halve the size of PTE tables
sparc64: Only support 4MB huge pages and 8KB base pages.
memory-hotplug: suppress "Trying to free nonexistent resource <XXXXXXXXXXXXXXXX-YYYYYYYYYYYYYYYY>" warning
mm: memcg: clean up mm_match_cgroup() signature
mm: document PageHuge somewhat
mm: use %pK for /proc/vmallocinfo
mm, thp: fix mlock statistics
mm, thp: fix mapped pages avoiding unevictable list on mlock
memory-hotplug: update memory block's state and notify userspace
memory-hotplug: preparation to notify memory block's state at memory hot remove
mm: avoid section mismatch warning for memblock_type_name
make GFP_NOTRACK definition unconditional
cma: decrease cc.nr_migratepages after reclaiming pagelist
CMA: migrate mlocked pages
kpageflags: fix wrong KPF_THP on non-huge compound pages
...
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r-- | mm/hugetlb.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index bc727122dd44..59a0059b39e2 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/hugetlb.h> | 30 | #include <linux/hugetlb.h> |
31 | #include <linux/hugetlb_cgroup.h> | 31 | #include <linux/hugetlb_cgroup.h> |
32 | #include <linux/node.h> | 32 | #include <linux/node.h> |
33 | #include <linux/hugetlb_cgroup.h> | ||
34 | #include "internal.h" | 33 | #include "internal.h" |
35 | 34 | ||
36 | const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; | 35 | const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; |
@@ -637,6 +636,7 @@ static void free_huge_page(struct page *page) | |||
637 | h->surplus_huge_pages--; | 636 | h->surplus_huge_pages--; |
638 | h->surplus_huge_pages_node[nid]--; | 637 | h->surplus_huge_pages_node[nid]--; |
639 | } else { | 638 | } else { |
639 | arch_clear_hugepage_flags(page); | ||
640 | enqueue_huge_page(h, page); | 640 | enqueue_huge_page(h, page); |
641 | } | 641 | } |
642 | spin_unlock(&hugetlb_lock); | 642 | spin_unlock(&hugetlb_lock); |
@@ -671,6 +671,11 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order) | |||
671 | } | 671 | } |
672 | } | 672 | } |
673 | 673 | ||
674 | /* | ||
675 | * PageHuge() only returns true for hugetlbfs pages, but not for normal or | ||
676 | * transparent huge pages. See the PageTransHuge() documentation for more | ||
677 | * details. | ||
678 | */ | ||
674 | int PageHuge(struct page *page) | 679 | int PageHuge(struct page *page) |
675 | { | 680 | { |
676 | compound_page_dtor *dtor; | 681 | compound_page_dtor *dtor; |
@@ -2355,13 +2360,15 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, | |||
2355 | struct page *page; | 2360 | struct page *page; |
2356 | struct hstate *h = hstate_vma(vma); | 2361 | struct hstate *h = hstate_vma(vma); |
2357 | unsigned long sz = huge_page_size(h); | 2362 | unsigned long sz = huge_page_size(h); |
2363 | const unsigned long mmun_start = start; /* For mmu_notifiers */ | ||
2364 | const unsigned long mmun_end = end; /* For mmu_notifiers */ | ||
2358 | 2365 | ||
2359 | WARN_ON(!is_vm_hugetlb_page(vma)); | 2366 | WARN_ON(!is_vm_hugetlb_page(vma)); |
2360 | BUG_ON(start & ~huge_page_mask(h)); | 2367 | BUG_ON(start & ~huge_page_mask(h)); |
2361 | BUG_ON(end & ~huge_page_mask(h)); | 2368 | BUG_ON(end & ~huge_page_mask(h)); |
2362 | 2369 | ||
2363 | tlb_start_vma(tlb, vma); | 2370 | tlb_start_vma(tlb, vma); |
2364 | mmu_notifier_invalidate_range_start(mm, start, end); | 2371 | mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); |
2365 | again: | 2372 | again: |
2366 | spin_lock(&mm->page_table_lock); | 2373 | spin_lock(&mm->page_table_lock); |
2367 | for (address = start; address < end; address += sz) { | 2374 | for (address = start; address < end; address += sz) { |
@@ -2425,7 +2432,7 @@ again: | |||
2425 | if (address < end && !ref_page) | 2432 | if (address < end && !ref_page) |
2426 | goto again; | 2433 | goto again; |
2427 | } | 2434 | } |
2428 | mmu_notifier_invalidate_range_end(mm, start, end); | 2435 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); |
2429 | tlb_end_vma(tlb, vma); | 2436 | tlb_end_vma(tlb, vma); |
2430 | } | 2437 | } |
2431 | 2438 | ||
@@ -2473,7 +2480,6 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2473 | struct hstate *h = hstate_vma(vma); | 2480 | struct hstate *h = hstate_vma(vma); |
2474 | struct vm_area_struct *iter_vma; | 2481 | struct vm_area_struct *iter_vma; |
2475 | struct address_space *mapping; | 2482 | struct address_space *mapping; |
2476 | struct prio_tree_iter iter; | ||
2477 | pgoff_t pgoff; | 2483 | pgoff_t pgoff; |
2478 | 2484 | ||
2479 | /* | 2485 | /* |
@@ -2481,7 +2487,8 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2481 | * from page cache lookup which is in HPAGE_SIZE units. | 2487 | * from page cache lookup which is in HPAGE_SIZE units. |
2482 | */ | 2488 | */ |
2483 | address = address & huge_page_mask(h); | 2489 | address = address & huge_page_mask(h); |
2484 | pgoff = vma_hugecache_offset(h, vma, address); | 2490 | pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + |
2491 | vma->vm_pgoff; | ||
2485 | mapping = vma->vm_file->f_dentry->d_inode->i_mapping; | 2492 | mapping = vma->vm_file->f_dentry->d_inode->i_mapping; |
2486 | 2493 | ||
2487 | /* | 2494 | /* |
@@ -2490,7 +2497,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2490 | * __unmap_hugepage_range() is called as the lock is already held | 2497 | * __unmap_hugepage_range() is called as the lock is already held |
2491 | */ | 2498 | */ |
2492 | mutex_lock(&mapping->i_mmap_mutex); | 2499 | mutex_lock(&mapping->i_mmap_mutex); |
2493 | vma_prio_tree_foreach(iter_vma, &iter, &mapping->i_mmap, pgoff, pgoff) { | 2500 | vma_interval_tree_foreach(iter_vma, &mapping->i_mmap, pgoff, pgoff) { |
2494 | /* Do not unmap the current VMA */ | 2501 | /* Do not unmap the current VMA */ |
2495 | if (iter_vma == vma) | 2502 | if (iter_vma == vma) |
2496 | continue; | 2503 | continue; |
@@ -2525,6 +2532,8 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2525 | struct page *old_page, *new_page; | 2532 | struct page *old_page, *new_page; |
2526 | int avoidcopy; | 2533 | int avoidcopy; |
2527 | int outside_reserve = 0; | 2534 | int outside_reserve = 0; |
2535 | unsigned long mmun_start; /* For mmu_notifiers */ | ||
2536 | unsigned long mmun_end; /* For mmu_notifiers */ | ||
2528 | 2537 | ||
2529 | old_page = pte_page(pte); | 2538 | old_page = pte_page(pte); |
2530 | 2539 | ||
@@ -2611,6 +2620,9 @@ retry_avoidcopy: | |||
2611 | pages_per_huge_page(h)); | 2620 | pages_per_huge_page(h)); |
2612 | __SetPageUptodate(new_page); | 2621 | __SetPageUptodate(new_page); |
2613 | 2622 | ||
2623 | mmun_start = address & huge_page_mask(h); | ||
2624 | mmun_end = mmun_start + huge_page_size(h); | ||
2625 | mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); | ||
2614 | /* | 2626 | /* |
2615 | * Retake the page_table_lock to check for racing updates | 2627 | * Retake the page_table_lock to check for racing updates |
2616 | * before the page tables are altered | 2628 | * before the page tables are altered |
@@ -2619,9 +2631,6 @@ retry_avoidcopy: | |||
2619 | ptep = huge_pte_offset(mm, address & huge_page_mask(h)); | 2631 | ptep = huge_pte_offset(mm, address & huge_page_mask(h)); |
2620 | if (likely(pte_same(huge_ptep_get(ptep), pte))) { | 2632 | if (likely(pte_same(huge_ptep_get(ptep), pte))) { |
2621 | /* Break COW */ | 2633 | /* Break COW */ |
2622 | mmu_notifier_invalidate_range_start(mm, | ||
2623 | address & huge_page_mask(h), | ||
2624 | (address & huge_page_mask(h)) + huge_page_size(h)); | ||
2625 | huge_ptep_clear_flush(vma, address, ptep); | 2634 | huge_ptep_clear_flush(vma, address, ptep); |
2626 | set_huge_pte_at(mm, address, ptep, | 2635 | set_huge_pte_at(mm, address, ptep, |
2627 | make_huge_pte(vma, new_page, 1)); | 2636 | make_huge_pte(vma, new_page, 1)); |
@@ -2629,10 +2638,11 @@ retry_avoidcopy: | |||
2629 | hugepage_add_new_anon_rmap(new_page, vma, address); | 2638 | hugepage_add_new_anon_rmap(new_page, vma, address); |
2630 | /* Make the old page be freed below */ | 2639 | /* Make the old page be freed below */ |
2631 | new_page = old_page; | 2640 | new_page = old_page; |
2632 | mmu_notifier_invalidate_range_end(mm, | ||
2633 | address & huge_page_mask(h), | ||
2634 | (address & huge_page_mask(h)) + huge_page_size(h)); | ||
2635 | } | 2641 | } |
2642 | spin_unlock(&mm->page_table_lock); | ||
2643 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); | ||
2644 | /* Caller expects lock to be held */ | ||
2645 | spin_lock(&mm->page_table_lock); | ||
2636 | page_cache_release(new_page); | 2646 | page_cache_release(new_page); |
2637 | page_cache_release(old_page); | 2647 | page_cache_release(old_page); |
2638 | return 0; | 2648 | return 0; |