aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorMinchan Kim <minchan@kernel.org>2015-09-08 18:00:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-08 18:35:28 -0400
commit8334b96221ff0dcbde4873d31eb4d84774ed8ed4 (patch)
tree35c6f7a7ab427834a10c3e74ccedcac9911e588a /fs/proc
parent3115aec4513e5bcb399235cac98a5637fe641c13 (diff)
mm: /proc/pid/smaps:: show proportional swap share of the mapping
We want to know per-process workingset size for smart memory management on userland and we use swap(ex, zram) heavily to maximize memory efficiency so workingset includes swap as well as RSS. On such system, if there are lots of shared anonymous pages, it's really hard to figure out exactly how many each process consumes memory(ie, rss + wap) if the system has lots of shared anonymous memory(e.g, android). This patch introduces SwapPss field on /proc/<pid>/smaps so we can get more exact workingset size per process. Bongkyu tested it. Result is below. 1. 50M used swap SwapTotal: 461976 kB SwapFree: 411192 kB $ adb shell cat /proc/*/smaps | grep "SwapPss:" | awk '{sum += $2} END {print sum}'; 48236 $ adb shell cat /proc/*/smaps | grep "Swap:" | awk '{sum += $2} END {print sum}'; 141184 2. 240M used swap SwapTotal: 461976 kB SwapFree: 216808 kB $ adb shell cat /proc/*/smaps | grep "SwapPss:" | awk '{sum += $2} END {print sum}'; 230315 $ adb shell cat /proc/*/smaps | grep "Swap:" | awk '{sum += $2} END {print sum}'; 1387744 [akpm@linux-foundation.org: simplify kunmap_atomic() call] Signed-off-by: Minchan Kim <minchan@kernel.org> Reported-by: Bongkyu Kim <bongkyu.kim@lge.com> Tested-by: Bongkyu Kim <bongkyu.kim@lge.com> Cc: Hugh Dickins <hughd@google.com> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Jerome Marchand <jmarchan@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/task_mmu.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 67c76468a7be..41f1a50c10c9 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -446,6 +446,7 @@ struct mem_size_stats {
446 unsigned long anonymous_thp; 446 unsigned long anonymous_thp;
447 unsigned long swap; 447 unsigned long swap;
448 u64 pss; 448 u64 pss;
449 u64 swap_pss;
449}; 450};
450 451
451static void smaps_account(struct mem_size_stats *mss, struct page *page, 452static void smaps_account(struct mem_size_stats *mss, struct page *page,
@@ -492,9 +493,20 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
492 } else if (is_swap_pte(*pte)) { 493 } else if (is_swap_pte(*pte)) {
493 swp_entry_t swpent = pte_to_swp_entry(*pte); 494 swp_entry_t swpent = pte_to_swp_entry(*pte);
494 495
495 if (!non_swap_entry(swpent)) 496 if (!non_swap_entry(swpent)) {
497 int mapcount;
498
496 mss->swap += PAGE_SIZE; 499 mss->swap += PAGE_SIZE;
497 else if (is_migration_entry(swpent)) 500 mapcount = swp_swapcount(swpent);
501 if (mapcount >= 2) {
502 u64 pss_delta = (u64)PAGE_SIZE << PSS_SHIFT;
503
504 do_div(pss_delta, mapcount);
505 mss->swap_pss += pss_delta;
506 } else {
507 mss->swap_pss += (u64)PAGE_SIZE << PSS_SHIFT;
508 }
509 } else if (is_migration_entry(swpent))
498 page = migration_entry_to_page(swpent); 510 page = migration_entry_to_page(swpent);
499 } 511 }
500 512
@@ -640,6 +652,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
640 "Anonymous: %8lu kB\n" 652 "Anonymous: %8lu kB\n"
641 "AnonHugePages: %8lu kB\n" 653 "AnonHugePages: %8lu kB\n"
642 "Swap: %8lu kB\n" 654 "Swap: %8lu kB\n"
655 "SwapPss: %8lu kB\n"
643 "KernelPageSize: %8lu kB\n" 656 "KernelPageSize: %8lu kB\n"
644 "MMUPageSize: %8lu kB\n" 657 "MMUPageSize: %8lu kB\n"
645 "Locked: %8lu kB\n", 658 "Locked: %8lu kB\n",
@@ -654,6 +667,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
654 mss.anonymous >> 10, 667 mss.anonymous >> 10,
655 mss.anonymous_thp >> 10, 668 mss.anonymous_thp >> 10,
656 mss.swap >> 10, 669 mss.swap >> 10,
670 (unsigned long)(mss.swap_pss >> (10 + PSS_SHIFT)),
657 vma_kernel_pagesize(vma) >> 10, 671 vma_kernel_pagesize(vma) >> 10,
658 vma_mmu_pagesize(vma) >> 10, 672 vma_mmu_pagesize(vma) >> 10,
659 (vma->vm_flags & VM_LOCKED) ? 673 (vma->vm_flags & VM_LOCKED) ?