diff options
| -rw-r--r-- | fs/proc/task_mmu.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 9dca07e0758d..5afaa58a8630 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
| @@ -936,6 +936,26 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, | |||
| 936 | pte_t *pte; | 936 | pte_t *pte; |
| 937 | 937 | ||
| 938 | md = walk->private; | 938 | md = walk->private; |
| 939 | spin_lock(&walk->mm->page_table_lock); | ||
| 940 | if (pmd_trans_huge(*pmd)) { | ||
| 941 | if (pmd_trans_splitting(*pmd)) { | ||
| 942 | spin_unlock(&walk->mm->page_table_lock); | ||
| 943 | wait_split_huge_page(md->vma->anon_vma, pmd); | ||
| 944 | } else { | ||
| 945 | pte_t huge_pte = *(pte_t *)pmd; | ||
| 946 | struct page *page; | ||
| 947 | |||
| 948 | page = can_gather_numa_stats(huge_pte, md->vma, addr); | ||
| 949 | if (page) | ||
| 950 | gather_stats(page, md, pte_dirty(huge_pte), | ||
| 951 | HPAGE_PMD_SIZE/PAGE_SIZE); | ||
| 952 | spin_unlock(&walk->mm->page_table_lock); | ||
| 953 | return 0; | ||
| 954 | } | ||
| 955 | } else { | ||
| 956 | spin_unlock(&walk->mm->page_table_lock); | ||
| 957 | } | ||
| 958 | |||
| 939 | orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); | 959 | orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); |
| 940 | do { | 960 | do { |
| 941 | struct page *page = can_gather_numa_stats(*pte, md->vma, addr); | 961 | struct page *page = can_gather_numa_stats(*pte, md->vma, addr); |
