aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/task_mmu.c73
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))