aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2015-11-05 21:47:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 22:34:48 -0500
commit5d317b2b6536592a9b51fe65faed43d65ca9158e (patch)
treef6d51677a577802ddd873c2e01bf04c5aff1e3f1
parent25ee01a2fca02dfb5a3ce316e77910c468108199 (diff)
mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status
Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because userspace applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/PID/status. Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Acked-by: Joern Engel <joern@logfs.org> Acked-by: David Rientjes <rientjes@google.com> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Mike Kravetz <mike.kravetz@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/filesystems/proc.txt2
-rw-r--r--fs/proc/task_mmu.c1
-rw-r--r--include/linux/hugetlb.h19
-rw-r--r--include/linux/mm_types.h3
-rw-r--r--mm/hugetlb.c9
-rw-r--r--mm/rmap.c4
6 files changed, 37 insertions, 1 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a7d6c06f36c4..12ac0e4455d4 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -175,6 +175,7 @@ read the file /proc/PID/status:
175 VmLib: 1412 kB 175 VmLib: 1412 kB
176 VmPTE: 20 kb 176 VmPTE: 20 kb
177 VmSwap: 0 kB 177 VmSwap: 0 kB
178 HugetlbPages: 0 kB
178 Threads: 1 179 Threads: 1
179 SigQ: 0/28578 180 SigQ: 0/28578
180 SigPnd: 0000000000000000 181 SigPnd: 0000000000000000
@@ -238,6 +239,7 @@ Table 1-2: Contents of the status files (as of 4.1)
238 VmPTE size of page table entries 239 VmPTE size of page table entries
239 VmPMD size of second level page tables 240 VmPMD size of second level page tables
240 VmSwap size of swap usage (the number of referred swapents) 241 VmSwap size of swap usage (the number of referred swapents)
242 HugetlbPages size of hugetlb memory portions
241 Threads number of threads 243 Threads number of threads
242 SigQ number of signals queued/max. number for queue 244 SigQ number of signals queued/max. number for queue
243 SigPnd bitmap of pending signals for the thread 245 SigPnd bitmap of pending signals for the thread
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 5988b83836fb..288185e24762 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -70,6 +70,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
70 ptes >> 10, 70 ptes >> 10,
71 pmds >> 10, 71 pmds >> 10,
72 swap << (PAGE_SHIFT-10)); 72 swap << (PAGE_SHIFT-10));
73 hugetlb_report_usage(m, mm);
73} 74}
74 75
75unsigned long task_vsize(struct mm_struct *mm) 76unsigned long task_vsize(struct mm_struct *mm)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 5e35379f58a5..685c262e0be8 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -483,6 +483,17 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
483#define hugepages_supported() (HPAGE_SHIFT != 0) 483#define hugepages_supported() (HPAGE_SHIFT != 0)
484#endif 484#endif
485 485
486void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm);
487
488static inline void hugetlb_count_add(long l, struct mm_struct *mm)
489{
490 atomic_long_add(l, &mm->hugetlb_usage);
491}
492
493static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
494{
495 atomic_long_sub(l, &mm->hugetlb_usage);
496}
486#else /* CONFIG_HUGETLB_PAGE */ 497#else /* CONFIG_HUGETLB_PAGE */
487struct hstate {}; 498struct hstate {};
488#define alloc_huge_page(v, a, r) NULL 499#define alloc_huge_page(v, a, r) NULL
@@ -519,6 +530,14 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
519{ 530{
520 return &mm->page_table_lock; 531 return &mm->page_table_lock;
521} 532}
533
534static inline void hugetlb_report_usage(struct seq_file *f, struct mm_struct *m)
535{
536}
537
538static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
539{
540}
522#endif /* CONFIG_HUGETLB_PAGE */ 541#endif /* CONFIG_HUGETLB_PAGE */
523 542
524static inline spinlock_t *huge_pte_lock(struct hstate *h, 543static inline spinlock_t *huge_pte_lock(struct hstate *h,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 3d6baa7d4534..0a85da25a822 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -486,6 +486,9 @@ struct mm_struct {
486 /* address of the bounds directory */ 486 /* address of the bounds directory */
487 void __user *bd_addr; 487 void __user *bd_addr;
488#endif 488#endif
489#ifdef CONFIG_HUGETLB_PAGE
490 atomic_long_t hugetlb_usage;
491#endif
489}; 492};
490 493
491static inline void mm_init_cpumask(struct mm_struct *mm) 494static inline void mm_init_cpumask(struct mm_struct *mm)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 9cc773483624..abfbe8ca3323 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2790,6 +2790,12 @@ void hugetlb_show_meminfo(void)
2790 1UL << (huge_page_order(h) + PAGE_SHIFT - 10)); 2790 1UL << (huge_page_order(h) + PAGE_SHIFT - 10));
2791} 2791}
2792 2792
2793void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm)
2794{
2795 seq_printf(m, "HugetlbPages:\t%8lu kB\n",
2796 atomic_long_read(&mm->hugetlb_usage) << (PAGE_SHIFT - 10));
2797}
2798
2793/* Return the number pages of memory we physically have, in PAGE_SIZE units. */ 2799/* Return the number pages of memory we physically have, in PAGE_SIZE units. */
2794unsigned long hugetlb_total_pages(void) 2800unsigned long hugetlb_total_pages(void)
2795{ 2801{
@@ -3025,6 +3031,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
3025 get_page(ptepage); 3031 get_page(ptepage);
3026 page_dup_rmap(ptepage); 3032 page_dup_rmap(ptepage);
3027 set_huge_pte_at(dst, addr, dst_pte, entry); 3033 set_huge_pte_at(dst, addr, dst_pte, entry);
3034 hugetlb_count_add(pages_per_huge_page(h), dst);
3028 } 3035 }
3029 spin_unlock(src_ptl); 3036 spin_unlock(src_ptl);
3030 spin_unlock(dst_ptl); 3037 spin_unlock(dst_ptl);
@@ -3105,6 +3112,7 @@ again:
3105 if (huge_pte_dirty(pte)) 3112 if (huge_pte_dirty(pte))
3106 set_page_dirty(page); 3113 set_page_dirty(page);
3107 3114
3115 hugetlb_count_sub(pages_per_huge_page(h), mm);
3108 page_remove_rmap(page); 3116 page_remove_rmap(page);
3109 force_flush = !__tlb_remove_page(tlb, page); 3117 force_flush = !__tlb_remove_page(tlb, page);
3110 if (force_flush) { 3118 if (force_flush) {
@@ -3509,6 +3517,7 @@ retry:
3509 && (vma->vm_flags & VM_SHARED))); 3517 && (vma->vm_flags & VM_SHARED)));
3510 set_huge_pte_at(mm, address, ptep, new_pte); 3518 set_huge_pte_at(mm, address, ptep, new_pte);
3511 3519
3520 hugetlb_count_add(pages_per_huge_page(h), mm);
3512 if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { 3521 if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
3513 /* Optimization, do the COW without a second fault */ 3522 /* Optimization, do the COW without a second fault */
3514 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl); 3523 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
diff --git a/mm/rmap.c b/mm/rmap.c
index f5b5c1f3dcd7..d40e7aefb888 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1352,7 +1352,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
1352 update_hiwater_rss(mm); 1352 update_hiwater_rss(mm);
1353 1353
1354 if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) { 1354 if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
1355 if (!PageHuge(page)) { 1355 if (PageHuge(page)) {
1356 hugetlb_count_sub(1 << compound_order(page), mm);
1357 } else {
1356 if (PageAnon(page)) 1358 if (PageAnon(page))
1357 dec_mm_counter(mm, MM_ANONPAGES); 1359 dec_mm_counter(mm, MM_ANONPAGES);
1358 else 1360 else