diff options
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r-- | fs/proc/task_mmu.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 23c697ed9747..14a933c9f05e 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -501,6 +501,7 @@ struct mem_size_stats { unsigned long swap; unsigned long nonlinear; u64 pss; + u64 swap_pss; }; @@ -518,9 +519,20 @@ static void smaps_pte_entry(pte_t ptent, unsigned long addr, } else if (is_swap_pte(ptent)) { swp_entry_t swpent = pte_to_swp_entry(ptent); - if (!non_swap_entry(swpent)) - mss->swap += ptent_size; - else if (is_migration_entry(swpent)) + if (!non_swap_entry(swpent)) { + int mapcount; + + mss->swap += PAGE_SIZE; + mapcount = swp_swapcount(swpent); + if (mapcount >= 2) { + u64 pss_delta = (u64)PAGE_SIZE << PSS_SHIFT; + + do_div(pss_delta, mapcount); + mss->swap_pss += pss_delta; + } else { + mss->swap_pss += (u64)PAGE_SIZE << PSS_SHIFT; + } + } else if (is_migration_entry(swpent)) page = migration_entry_to_page(swpent); } else if (pte_file(ptent)) { if (pte_to_pgoff(ptent) != pgoff) @@ -676,6 +688,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) "Anonymous: %8lu kB\n" "AnonHugePages: %8lu kB\n" "Swap: %8lu kB\n" + "SwapPss: %8lu kB\n" "KernelPageSize: %8lu kB\n" "MMUPageSize: %8lu kB\n" "Locked: %8lu kB\n", @@ -690,6 +703,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) mss.anonymous >> 10, mss.anonymous_thp >> 10, mss.swap >> 10, + (unsigned long)(mss.swap_pss >> (10 + PSS_SHIFT)), vma_kernel_pagesize(vma) >> 10, vma_mmu_pagesize(vma) >> 10, (vma->vm_flags & VM_LOCKED) ? |