diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/task_mmu.c | 73 |
1 files changed, 25 insertions, 48 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 95264c0ef308..328843de6e9f 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -394,20 +394,11 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
394 | pte_t *pte; | 394 | pte_t *pte; |
395 | spinlock_t *ptl; | 395 | spinlock_t *ptl; |
396 | 396 | ||
397 | spin_lock(&walk->mm->page_table_lock); | 397 | if (pmd_trans_huge_lock(pmd, vma) == 1) { |
398 | if (pmd_trans_huge(*pmd)) { | 398 | smaps_pte_entry(*(pte_t *)pmd, addr, HPAGE_PMD_SIZE, walk); |
399 | if (pmd_trans_splitting(*pmd)) { | ||
400 | spin_unlock(&walk->mm->page_table_lock); | ||
401 | wait_split_huge_page(vma->anon_vma, pmd); | ||
402 | } else { | ||
403 | smaps_pte_entry(*(pte_t *)pmd, addr, | ||
404 | HPAGE_PMD_SIZE, walk); | ||
405 | spin_unlock(&walk->mm->page_table_lock); | ||
406 | mss->anonymous_thp += HPAGE_PMD_SIZE; | ||
407 | return 0; | ||
408 | } | ||
409 | } else { | ||
410 | spin_unlock(&walk->mm->page_table_lock); | 399 | spin_unlock(&walk->mm->page_table_lock); |
400 | mss->anonymous_thp += HPAGE_PMD_SIZE; | ||
401 | return 0; | ||
411 | } | 402 | } |
412 | 403 | ||
413 | if (pmd_trans_unstable(pmd)) | 404 | if (pmd_trans_unstable(pmd)) |
@@ -705,26 +696,19 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
705 | /* find the first VMA at or above 'addr' */ | 696 | /* find the first VMA at or above 'addr' */ |
706 | vma = find_vma(walk->mm, addr); | 697 | vma = find_vma(walk->mm, addr); |
707 | spin_lock(&walk->mm->page_table_lock); | 698 | spin_lock(&walk->mm->page_table_lock); |
708 | if (pmd_trans_huge(*pmd)) { | 699 | if (pmd_trans_huge_lock(pmd, vma) == 1) { |
709 | if (pmd_trans_splitting(*pmd)) { | 700 | for (; addr != end; addr += PAGE_SIZE) { |
710 | spin_unlock(&walk->mm->page_table_lock); | 701 | unsigned long offset; |
711 | wait_split_huge_page(vma->anon_vma, pmd); | 702 | |
712 | } else { | 703 | offset = (addr & ~PAGEMAP_WALK_MASK) >> |
713 | for (; addr != end; addr += PAGE_SIZE) { | 704 | PAGE_SHIFT; |
714 | unsigned long offset; | 705 | pfn = thp_pmd_to_pagemap_entry(*pmd, offset); |
715 | 706 | err = add_to_pagemap(addr, pfn, pm); | |
716 | offset = (addr & ~PAGEMAP_WALK_MASK) >> | 707 | if (err) |
717 | PAGE_SHIFT; | 708 | break; |
718 | pfn = thp_pmd_to_pagemap_entry(*pmd, offset); | ||
719 | err = add_to_pagemap(addr, pfn, pm); | ||
720 | if (err) | ||
721 | break; | ||
722 | } | ||
723 | spin_unlock(&walk->mm->page_table_lock); | ||
724 | return err; | ||
725 | } | 709 | } |
726 | } else { | ||
727 | spin_unlock(&walk->mm->page_table_lock); | 710 | spin_unlock(&walk->mm->page_table_lock); |
711 | return err; | ||
728 | } | 712 | } |
729 | 713 | ||
730 | for (; addr != end; addr += PAGE_SIZE) { | 714 | for (; addr != end; addr += PAGE_SIZE) { |
@@ -992,24 +976,17 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, | |||
992 | pte_t *pte; | 976 | pte_t *pte; |
993 | 977 | ||
994 | md = walk->private; | 978 | md = walk->private; |
995 | spin_lock(&walk->mm->page_table_lock); | 979 | |
996 | if (pmd_trans_huge(*pmd)) { | 980 | if (pmd_trans_huge_lock(pmd, md->vma) == 1) { |
997 | if (pmd_trans_splitting(*pmd)) { | 981 | pte_t huge_pte = *(pte_t *)pmd; |
998 | spin_unlock(&walk->mm->page_table_lock); | 982 | struct page *page; |
999 | wait_split_huge_page(md->vma->anon_vma, pmd); | 983 | |
1000 | } else { | 984 | page = can_gather_numa_stats(huge_pte, md->vma, addr); |
1001 | pte_t huge_pte = *(pte_t *)pmd; | 985 | if (page) |
1002 | struct page *page; | 986 | gather_stats(page, md, pte_dirty(huge_pte), |
1003 | 987 | HPAGE_PMD_SIZE/PAGE_SIZE); | |
1004 | page = can_gather_numa_stats(huge_pte, md->vma, addr); | ||
1005 | if (page) | ||
1006 | gather_stats(page, md, pte_dirty(huge_pte), | ||
1007 | HPAGE_PMD_SIZE/PAGE_SIZE); | ||
1008 | spin_unlock(&walk->mm->page_table_lock); | ||
1009 | return 0; | ||
1010 | } | ||
1011 | } else { | ||
1012 | spin_unlock(&walk->mm->page_table_lock); | 988 | spin_unlock(&walk->mm->page_table_lock); |
989 | return 0; | ||
1013 | } | 990 | } |
1014 | 991 | ||
1015 | if (pmd_trans_unstable(pmd)) | 992 | if (pmd_trans_unstable(pmd)) |