aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/task_mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r--fs/proc/task_mmu.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7faaf2acc570..4540b8f76f16 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -125,7 +125,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
125 if (!priv->task) 125 if (!priv->task)
126 return ERR_PTR(-ESRCH); 126 return ERR_PTR(-ESRCH);
127 127
128 mm = mm_for_maps(priv->task); 128 mm = mm_access(priv->task, PTRACE_MODE_READ);
129 if (!mm || IS_ERR(mm)) 129 if (!mm || IS_ERR(mm))
130 return mm; 130 return mm;
131 down_read(&mm->mmap_sem); 131 down_read(&mm->mmap_sem);
@@ -393,6 +393,7 @@ struct mem_size_stats {
393 unsigned long anonymous; 393 unsigned long anonymous;
394 unsigned long anonymous_thp; 394 unsigned long anonymous_thp;
395 unsigned long swap; 395 unsigned long swap;
396 unsigned long nonlinear;
396 u64 pss; 397 u64 pss;
397}; 398};
398 399
@@ -402,24 +403,33 @@ static void smaps_pte_entry(pte_t ptent, unsigned long addr,
402{ 403{
403 struct mem_size_stats *mss = walk->private; 404 struct mem_size_stats *mss = walk->private;
404 struct vm_area_struct *vma = mss->vma; 405 struct vm_area_struct *vma = mss->vma;
405 struct page *page; 406 pgoff_t pgoff = linear_page_index(vma, addr);
407 struct page *page = NULL;
406 int mapcount; 408 int mapcount;
407 409
408 if (is_swap_pte(ptent)) { 410 if (pte_present(ptent)) {
409 mss->swap += ptent_size; 411 page = vm_normal_page(vma, addr, ptent);
410 return; 412 } else if (is_swap_pte(ptent)) {
413 swp_entry_t swpent = pte_to_swp_entry(ptent);
414
415 if (!non_swap_entry(swpent))
416 mss->swap += ptent_size;
417 else if (is_migration_entry(swpent))
418 page = migration_entry_to_page(swpent);
419 } else if (pte_file(ptent)) {
420 if (pte_to_pgoff(ptent) != pgoff)
421 mss->nonlinear += ptent_size;
411 } 422 }
412 423
413 if (!pte_present(ptent))
414 return;
415
416 page = vm_normal_page(vma, addr, ptent);
417 if (!page) 424 if (!page)
418 return; 425 return;
419 426
420 if (PageAnon(page)) 427 if (PageAnon(page))
421 mss->anonymous += ptent_size; 428 mss->anonymous += ptent_size;
422 429
430 if (page->index != pgoff)
431 mss->nonlinear += ptent_size;
432
423 mss->resident += ptent_size; 433 mss->resident += ptent_size;
424 /* Accumulate the size in pages that have been accessed. */ 434 /* Accumulate the size in pages that have been accessed. */
425 if (pte_young(ptent) || PageReferenced(page)) 435 if (pte_young(ptent) || PageReferenced(page))
@@ -521,6 +531,10 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
521 (vma->vm_flags & VM_LOCKED) ? 531 (vma->vm_flags & VM_LOCKED) ?
522 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0); 532 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0);
523 533
534 if (vma->vm_flags & VM_NONLINEAR)
535 seq_printf(m, "Nonlinear: %8lu kB\n",
536 mss.nonlinear >> 10);
537
524 if (m->count < m->size) /* vma is copied successfully */ 538 if (m->count < m->size) /* vma is copied successfully */
525 m->version = (vma != get_gate_vma(task->mm)) 539 m->version = (vma != get_gate_vma(task->mm))
526 ? vma->vm_start : 0; 540 ? vma->vm_start : 0;
@@ -700,6 +714,7 @@ struct pagemapread {
700 714
701#define PM_PRESENT PM_STATUS(4LL) 715#define PM_PRESENT PM_STATUS(4LL)
702#define PM_SWAP PM_STATUS(2LL) 716#define PM_SWAP PM_STATUS(2LL)
717#define PM_FILE PM_STATUS(1LL)
703#define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT) 718#define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT)
704#define PM_END_OF_BUFFER 1 719#define PM_END_OF_BUFFER 1
705 720
@@ -733,22 +748,33 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
733 return err; 748 return err;
734} 749}
735 750
736static u64 swap_pte_to_pagemap_entry(pte_t pte) 751static void pte_to_pagemap_entry(pagemap_entry_t *pme,
752 struct vm_area_struct *vma, unsigned long addr, pte_t pte)
737{ 753{
738 swp_entry_t e = pte_to_swp_entry(pte); 754 u64 frame, flags;
739 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); 755 struct page *page = NULL;
740} 756
741 757 if (pte_present(pte)) {
742static void pte_to_pagemap_entry(pagemap_entry_t *pme, pte_t pte) 758 frame = pte_pfn(pte);
743{ 759 flags = PM_PRESENT;
744 if (is_swap_pte(pte)) 760 page = vm_normal_page(vma, addr, pte);
745 *pme = make_pme(PM_PFRAME(swap_pte_to_pagemap_entry(pte)) 761 } else if (is_swap_pte(pte)) {
746 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP); 762 swp_entry_t entry = pte_to_swp_entry(pte);
747 else if (pte_present(pte)) 763
748 *pme = make_pme(PM_PFRAME(pte_pfn(pte)) 764 frame = swp_type(entry) |
749 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); 765 (swp_offset(entry) << MAX_SWAPFILES_SHIFT);
750 else 766 flags = PM_SWAP;
767 if (is_migration_entry(entry))
768 page = migration_entry_to_page(entry);
769 } else {
751 *pme = make_pme(PM_NOT_PRESENT); 770 *pme = make_pme(PM_NOT_PRESENT);
771 return;
772 }
773
774 if (page && !PageAnon(page))
775 flags |= PM_FILE;
776
777 *pme = make_pme(PM_PFRAME(frame) | PM_PSHIFT(PAGE_SHIFT) | flags);
752} 778}
753 779
754#ifdef CONFIG_TRANSPARENT_HUGEPAGE 780#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -815,7 +841,7 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
815 if (vma && (vma->vm_start <= addr) && 841 if (vma && (vma->vm_start <= addr) &&
816 !is_vm_hugetlb_page(vma)) { 842 !is_vm_hugetlb_page(vma)) {
817 pte = pte_offset_map(pmd, addr); 843 pte = pte_offset_map(pmd, addr);
818 pte_to_pagemap_entry(&pme, *pte); 844 pte_to_pagemap_entry(&pme, vma, addr, *pte);
819 /* unmap before userspace copy */ 845 /* unmap before userspace copy */
820 pte_unmap(pte); 846 pte_unmap(pte);
821 } 847 }
@@ -869,11 +895,11 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
869 * For each page in the address space, this file contains one 64-bit entry 895 * For each page in the address space, this file contains one 64-bit entry
870 * consisting of the following: 896 * consisting of the following:
871 * 897 *
872 * Bits 0-55 page frame number (PFN) if present 898 * Bits 0-54 page frame number (PFN) if present
873 * Bits 0-4 swap type if swapped 899 * Bits 0-4 swap type if swapped
874 * Bits 5-55 swap offset if swapped 900 * Bits 5-54 swap offset if swapped
875 * Bits 55-60 page shift (page size = 1<<page shift) 901 * Bits 55-60 page shift (page size = 1<<page shift)
876 * Bit 61 reserved for future use 902 * Bit 61 page is file-page or shared-anon
877 * Bit 62 page swapped 903 * Bit 62 page swapped
878 * Bit 63 page present 904 * Bit 63 page present
879 * 905 *
@@ -919,7 +945,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
919 if (!pm.buffer) 945 if (!pm.buffer)
920 goto out_task; 946 goto out_task;
921 947
922 mm = mm_for_maps(task); 948 mm = mm_access(task, PTRACE_MODE_READ);
923 ret = PTR_ERR(mm); 949 ret = PTR_ERR(mm);
924 if (!mm || IS_ERR(mm)) 950 if (!mm || IS_ERR(mm))
925 goto out_free; 951 goto out_free;