Commit 25ee01a2 authored by Naoya Horiguchi's avatar Naoya Horiguchi Committed by Linus Torvalds

mm: hugetlb: proc: add hugetlb-related fields to /proc/PID/smaps

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB),
which is inconvenient when we want to know per-task or per-vma base
hugetlb usage.  To solve this, this patch adds new fields for hugetlb
usage like below:

  Size:              20480 kB
  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Shared_Hugetlb:    18432 kB
  Private_Hugetlb:    2048 kB
  Swap:                  0 kB
  KernelPageSize:     2048 kB
  MMUPageSize:        2048 kB
  Locked:                0 kB
  VmFlags: rd wr mr mw me de ht

[hughd@google.com: fix Private_Hugetlb alignment ]
Signed-off-by: default avatarNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Acked-by: default avatarJoern Engel <joern@logfs.org>
Acked-by: default avatarDavid Rientjes <rientjes@google.com>
Acked-by: default avatarMichal Hocko <mhocko@suse.cz>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Signed-off-by: default avatarHugh Dickins <hughd@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 600e19af
...@@ -424,6 +424,9 @@ Private_Clean: 0 kB ...@@ -424,6 +424,9 @@ Private_Clean: 0 kB
Private_Dirty: 0 kB Private_Dirty: 0 kB
Referenced: 892 kB Referenced: 892 kB
Anonymous: 0 kB Anonymous: 0 kB
AnonHugePages: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB Swap: 0 kB
SwapPss: 0 kB SwapPss: 0 kB
KernelPageSize: 4 kB KernelPageSize: 4 kB
...@@ -452,6 +455,11 @@ and a page is modified, the file page is replaced by a private anonymous copy. ...@@ -452,6 +455,11 @@ and a page is modified, the file page is replaced by a private anonymous copy.
"Swap" shows how much would-be-anonymous memory is also used, but out on "Swap" shows how much would-be-anonymous memory is also used, but out on
swap. swap.
"SwapPss" shows proportional swap share of this mapping. "SwapPss" shows proportional swap share of this mapping.
"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
"Shared_Hugetlb" and "Private_Hugetlb" show the ammounts of memory backed by
hugetlbfs page which is *not* counted in "RSS" or "PSS" field for historical
reasons. And these are not included in {Shared,Private}_{Clean,Dirty} field.
"VmFlags" field deserves a separate description. This member represents the kernel "VmFlags" field deserves a separate description. This member represents the kernel
flags associated with the particular virtual memory area in two letter encoded flags associated with the particular virtual memory area in two letter encoded
manner. The codes are the following: manner. The codes are the following:
......
...@@ -446,6 +446,8 @@ struct mem_size_stats { ...@@ -446,6 +446,8 @@ struct mem_size_stats {
unsigned long anonymous; unsigned long anonymous;
unsigned long anonymous_thp; unsigned long anonymous_thp;
unsigned long swap; unsigned long swap;
unsigned long shared_hugetlb;
unsigned long private_hugetlb;
u64 pss; u64 pss;
u64 swap_pss; u64 swap_pss;
}; };
...@@ -625,12 +627,44 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) ...@@ -625,12 +627,44 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
seq_putc(m, '\n'); seq_putc(m, '\n');
} }
#ifdef CONFIG_HUGETLB_PAGE
static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
struct mem_size_stats *mss = walk->private;
struct vm_area_struct *vma = walk->vma;
struct page *page = NULL;
if (pte_present(*pte)) {
page = vm_normal_page(vma, addr, *pte);
} else if (is_swap_pte(*pte)) {
swp_entry_t swpent = pte_to_swp_entry(*pte);
if (is_migration_entry(swpent))
page = migration_entry_to_page(swpent);
}
if (page) {
int mapcount = page_mapcount(page);
if (mapcount >= 2)
mss->shared_hugetlb += huge_page_size(hstate_vma(vma));
else
mss->private_hugetlb += huge_page_size(hstate_vma(vma));
}
return 0;
}
#endif /* HUGETLB_PAGE */
static int show_smap(struct seq_file *m, void *v, int is_pid) static int show_smap(struct seq_file *m, void *v, int is_pid)
{ {
struct vm_area_struct *vma = v; struct vm_area_struct *vma = v;
struct mem_size_stats mss; struct mem_size_stats mss;
struct mm_walk smaps_walk = { struct mm_walk smaps_walk = {
.pmd_entry = smaps_pte_range, .pmd_entry = smaps_pte_range,
#ifdef CONFIG_HUGETLB_PAGE
.hugetlb_entry = smaps_hugetlb_range,
#endif
.mm = vma->vm_mm, .mm = vma->vm_mm,
.private = &mss, .private = &mss,
}; };
...@@ -652,6 +686,8 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) ...@@ -652,6 +686,8 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
"Referenced: %8lu kB\n" "Referenced: %8lu kB\n"
"Anonymous: %8lu kB\n" "Anonymous: %8lu kB\n"
"AnonHugePages: %8lu kB\n" "AnonHugePages: %8lu kB\n"
"Shared_Hugetlb: %8lu kB\n"
"Private_Hugetlb: %7lu kB\n"
"Swap: %8lu kB\n" "Swap: %8lu kB\n"
"SwapPss: %8lu kB\n" "SwapPss: %8lu kB\n"
"KernelPageSize: %8lu kB\n" "KernelPageSize: %8lu kB\n"
...@@ -667,6 +703,8 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) ...@@ -667,6 +703,8 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
mss.referenced >> 10, mss.referenced >> 10,
mss.anonymous >> 10, mss.anonymous >> 10,
mss.anonymous_thp >> 10, mss.anonymous_thp >> 10,
mss.shared_hugetlb >> 10,
mss.private_hugetlb >> 10,
mss.swap >> 10, mss.swap >> 10,
(unsigned long)(mss.swap_pss >> (10 + PSS_SHIFT)), (unsigned long)(mss.swap_pss >> (10 + PSS_SHIFT)),
vma_kernel_pagesize(vma) >> 10, vma_kernel_pagesize(vma) >> 10,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment