Commit b084d4353ff99d824d3bc5a5c2c22c70b1fba722
Committed by
Linus Torvalds
1 parent
34e55232e5
Exists in
master
and in
4 other branches
mm: count swap usage
A frequent questions from users about memory management is what numbers of swap ents are user for processes. And this information will give some hints to oom-killer. Besides we can count the number of swapents per a process by scanning /proc/<pid>/smaps, this is very slow and not good for usual process information handler which works like 'ps' or 'top'. (ps or top is now enough slow..) This patch adds a counter of swapents to mm_counter and update is at each swap events. Information is exported via /proc/<pid>/status file as [kamezawa@bluextal memory]$ cat /proc/self/status Name: cat State: R (running) Tgid: 2910 Pid: 2910 PPid: 2823 TracerPid: 0 Uid: 500 500 500 500 Gid: 500 500 500 500 FDSize: 256 Groups: 500 VmPeak: 82696 kB VmSize: 82696 kB VmLck: 0 kB VmHWM: 432 kB VmRSS: 432 kB VmData: 172 kB VmStk: 84 kB VmExe: 48 kB VmLib: 1568 kB VmPTE: 40 kB VmSwap: 0 kB <=============== this. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Reviewed-by: Minchan Kim <minchan.kim@gmail.com> Reviewed-by: Christoph Lameter <cl@linux-foundation.org> Cc: Lee Schermerhorn <lee.schermerhorn@hp.com> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 6 changed files with 23 additions and 7 deletions Side-by-side Diff
Documentation/filesystems/proc.txt
... | ... | @@ -164,6 +164,7 @@ |
164 | 164 | VmExe: 68 kB |
165 | 165 | VmLib: 1412 kB |
166 | 166 | VmPTE: 20 kb |
167 | + VmSwap: 0 kB | |
167 | 168 | Threads: 1 |
168 | 169 | SigQ: 0/28578 |
169 | 170 | SigPnd: 0000000000000000 |
... | ... | @@ -219,6 +220,7 @@ |
219 | 220 | VmExe size of text segment |
220 | 221 | VmLib size of shared library code |
221 | 222 | VmPTE size of page table entries |
223 | + VmSwap size of swap usage (the number of referred swapents) | |
222 | 224 | Threads number of threads |
223 | 225 | SigQ number of signals queued/max. number for queue |
224 | 226 | SigPnd bitmap of pending signals for the thread |
fs/proc/task_mmu.c
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | |
17 | 17 | void task_mem(struct seq_file *m, struct mm_struct *mm) |
18 | 18 | { |
19 | - unsigned long data, text, lib; | |
19 | + unsigned long data, text, lib, swap; | |
20 | 20 | unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; |
21 | 21 | |
22 | 22 | /* |
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | data = mm->total_vm - mm->shared_vm - mm->stack_vm; |
37 | 37 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; |
38 | 38 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; |
39 | + swap = get_mm_counter(mm, MM_SWAPENTS); | |
39 | 40 | seq_printf(m, |
40 | 41 | "VmPeak:\t%8lu kB\n" |
41 | 42 | "VmSize:\t%8lu kB\n" |
... | ... | @@ -46,7 +47,8 @@ |
46 | 47 | "VmStk:\t%8lu kB\n" |
47 | 48 | "VmExe:\t%8lu kB\n" |
48 | 49 | "VmLib:\t%8lu kB\n" |
49 | - "VmPTE:\t%8lu kB\n", | |
50 | + "VmPTE:\t%8lu kB\n" | |
51 | + "VmSwap:\t%8lu kB\n", | |
50 | 52 | hiwater_vm << (PAGE_SHIFT-10), |
51 | 53 | (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), |
52 | 54 | mm->locked_vm << (PAGE_SHIFT-10), |
... | ... | @@ -54,7 +56,8 @@ |
54 | 56 | total_rss << (PAGE_SHIFT-10), |
55 | 57 | data << (PAGE_SHIFT-10), |
56 | 58 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, |
57 | - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); | |
59 | + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10, | |
60 | + swap << (PAGE_SHIFT-10)); | |
58 | 61 | } |
59 | 62 | |
60 | 63 | unsigned long task_vsize(struct mm_struct *mm) |
include/linux/mm_types.h
mm/memory.c
... | ... | @@ -679,7 +679,9 @@ |
679 | 679 | &src_mm->mmlist); |
680 | 680 | spin_unlock(&mmlist_lock); |
681 | 681 | } |
682 | - if (is_write_migration_entry(entry) && | |
682 | + if (likely(!non_swap_entry(entry))) | |
683 | + rss[MM_SWAPENTS]++; | |
684 | + else if (is_write_migration_entry(entry) && | |
683 | 685 | is_cow_mapping(vm_flags)) { |
684 | 686 | /* |
685 | 687 | * COW mappings require pages in both parent |
... | ... | @@ -974,9 +976,14 @@ |
974 | 976 | if (pte_file(ptent)) { |
975 | 977 | if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) |
976 | 978 | print_bad_pte(vma, addr, ptent, NULL); |
977 | - } else if | |
978 | - (unlikely(!free_swap_and_cache(pte_to_swp_entry(ptent)))) | |
979 | - print_bad_pte(vma, addr, ptent, NULL); | |
979 | + } else { | |
980 | + swp_entry_t entry = pte_to_swp_entry(ptent); | |
981 | + | |
982 | + if (!non_swap_entry(entry)) | |
983 | + rss[MM_SWAPENTS]--; | |
984 | + if (unlikely(!free_swap_and_cache(entry))) | |
985 | + print_bad_pte(vma, addr, ptent, NULL); | |
986 | + } | |
980 | 987 | pte_clear_not_present_full(mm, addr, pte, tlb->fullmm); |
981 | 988 | } while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0)); |
982 | 989 | |
... | ... | @@ -2692,6 +2699,7 @@ |
2692 | 2699 | */ |
2693 | 2700 | |
2694 | 2701 | inc_mm_counter_fast(mm, MM_ANONPAGES); |
2702 | + dec_mm_counter_fast(mm, MM_SWAPENTS); | |
2695 | 2703 | pte = mk_pte(page, vma->vm_page_prot); |
2696 | 2704 | if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) { |
2697 | 2705 | pte = maybe_mkwrite(pte_mkdirty(pte), vma); |
mm/rmap.c