mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									25ee01a2fc
								
							
						
					
					
						commit
						5d317b2b65
					
				
					 6 changed files with 37 additions and 1 deletions
				
			
		| 
						 | 
					@ -175,6 +175,7 @@ read the file /proc/PID/status:
 | 
				
			||||||
  VmLib:      1412 kB
 | 
					  VmLib:      1412 kB
 | 
				
			||||||
  VmPTE:        20 kb
 | 
					  VmPTE:        20 kb
 | 
				
			||||||
  VmSwap:        0 kB
 | 
					  VmSwap:        0 kB
 | 
				
			||||||
 | 
					  HugetlbPages:          0 kB
 | 
				
			||||||
  Threads:        1
 | 
					  Threads:        1
 | 
				
			||||||
  SigQ:   0/28578
 | 
					  SigQ:   0/28578
 | 
				
			||||||
  SigPnd: 0000000000000000
 | 
					  SigPnd: 0000000000000000
 | 
				
			||||||
| 
						 | 
					@ -238,6 +239,7 @@ Table 1-2: Contents of the status files (as of 4.1)
 | 
				
			||||||
 VmPTE                       size of page table entries
 | 
					 VmPTE                       size of page table entries
 | 
				
			||||||
 VmPMD                       size of second level page tables
 | 
					 VmPMD                       size of second level page tables
 | 
				
			||||||
 VmSwap                      size of swap usage (the number of referred swapents)
 | 
					 VmSwap                      size of swap usage (the number of referred swapents)
 | 
				
			||||||
 | 
					 HugetlbPages                size of hugetlb memory portions
 | 
				
			||||||
 Threads                     number of threads
 | 
					 Threads                     number of threads
 | 
				
			||||||
 SigQ                        number of signals queued/max. number for queue
 | 
					 SigQ                        number of signals queued/max. number for queue
 | 
				
			||||||
 SigPnd                      bitmap of pending signals for the thread
 | 
					 SigPnd                      bitmap of pending signals for the thread
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 | 
				
			||||||
		ptes >> 10,
 | 
							ptes >> 10,
 | 
				
			||||||
		pmds >> 10,
 | 
							pmds >> 10,
 | 
				
			||||||
		swap << (PAGE_SHIFT-10));
 | 
							swap << (PAGE_SHIFT-10));
 | 
				
			||||||
 | 
						hugetlb_report_usage(m, mm);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long task_vsize(struct mm_struct *mm)
 | 
					unsigned long task_vsize(struct mm_struct *mm)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -483,6 +483,17 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 | 
				
			||||||
#define hugepages_supported() (HPAGE_SHIFT != 0)
 | 
					#define hugepages_supported() (HPAGE_SHIFT != 0)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void hugetlb_count_add(long l, struct mm_struct *mm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						atomic_long_add(l, &mm->hugetlb_usage);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						atomic_long_sub(l, &mm->hugetlb_usage);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#else	/* CONFIG_HUGETLB_PAGE */
 | 
					#else	/* CONFIG_HUGETLB_PAGE */
 | 
				
			||||||
struct hstate {};
 | 
					struct hstate {};
 | 
				
			||||||
#define alloc_huge_page(v, a, r) NULL
 | 
					#define alloc_huge_page(v, a, r) NULL
 | 
				
			||||||
| 
						 | 
					@ -519,6 +530,14 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return &mm->page_table_lock;
 | 
						return &mm->page_table_lock;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void hugetlb_report_usage(struct seq_file *f, struct mm_struct *m)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif	/* CONFIG_HUGETLB_PAGE */
 | 
					#endif	/* CONFIG_HUGETLB_PAGE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline spinlock_t *huge_pte_lock(struct hstate *h,
 | 
					static inline spinlock_t *huge_pte_lock(struct hstate *h,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -486,6 +486,9 @@ struct mm_struct {
 | 
				
			||||||
	/* address of the bounds directory */
 | 
						/* address of the bounds directory */
 | 
				
			||||||
	void __user *bd_addr;
 | 
						void __user *bd_addr;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_HUGETLB_PAGE
 | 
				
			||||||
 | 
						atomic_long_t hugetlb_usage;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void mm_init_cpumask(struct mm_struct *mm)
 | 
					static inline void mm_init_cpumask(struct mm_struct *mm)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2790,6 +2790,12 @@ void hugetlb_show_meminfo(void)
 | 
				
			||||||
				1UL << (huge_page_order(h) + PAGE_SHIFT - 10));
 | 
									1UL << (huge_page_order(h) + PAGE_SHIFT - 10));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						seq_printf(m, "HugetlbPages:\t%8lu kB\n",
 | 
				
			||||||
 | 
							   atomic_long_read(&mm->hugetlb_usage) << (PAGE_SHIFT - 10));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Return the number pages of memory we physically have, in PAGE_SIZE units. */
 | 
					/* Return the number pages of memory we physically have, in PAGE_SIZE units. */
 | 
				
			||||||
unsigned long hugetlb_total_pages(void)
 | 
					unsigned long hugetlb_total_pages(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -3025,6 +3031,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 | 
				
			||||||
			get_page(ptepage);
 | 
								get_page(ptepage);
 | 
				
			||||||
			page_dup_rmap(ptepage);
 | 
								page_dup_rmap(ptepage);
 | 
				
			||||||
			set_huge_pte_at(dst, addr, dst_pte, entry);
 | 
								set_huge_pte_at(dst, addr, dst_pte, entry);
 | 
				
			||||||
 | 
								hugetlb_count_add(pages_per_huge_page(h), dst);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		spin_unlock(src_ptl);
 | 
							spin_unlock(src_ptl);
 | 
				
			||||||
		spin_unlock(dst_ptl);
 | 
							spin_unlock(dst_ptl);
 | 
				
			||||||
| 
						 | 
					@ -3105,6 +3112,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 | 
				
			||||||
		if (huge_pte_dirty(pte))
 | 
							if (huge_pte_dirty(pte))
 | 
				
			||||||
			set_page_dirty(page);
 | 
								set_page_dirty(page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hugetlb_count_sub(pages_per_huge_page(h), mm);
 | 
				
			||||||
		page_remove_rmap(page);
 | 
							page_remove_rmap(page);
 | 
				
			||||||
		force_flush = !__tlb_remove_page(tlb, page);
 | 
							force_flush = !__tlb_remove_page(tlb, page);
 | 
				
			||||||
		if (force_flush) {
 | 
							if (force_flush) {
 | 
				
			||||||
| 
						 | 
					@ -3509,6 +3517,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
 | 
				
			||||||
				&& (vma->vm_flags & VM_SHARED)));
 | 
									&& (vma->vm_flags & VM_SHARED)));
 | 
				
			||||||
	set_huge_pte_at(mm, address, ptep, new_pte);
 | 
						set_huge_pte_at(mm, address, ptep, new_pte);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hugetlb_count_add(pages_per_huge_page(h), mm);
 | 
				
			||||||
	if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
 | 
						if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
 | 
				
			||||||
		/* Optimization, do the COW without a second fault */
 | 
							/* Optimization, do the COW without a second fault */
 | 
				
			||||||
		ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
 | 
							ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1352,7 +1352,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 | 
				
			||||||
	update_hiwater_rss(mm);
 | 
						update_hiwater_rss(mm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
 | 
						if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
 | 
				
			||||||
		if (!PageHuge(page)) {
 | 
							if (PageHuge(page)) {
 | 
				
			||||||
 | 
								hugetlb_count_sub(1 << compound_order(page), mm);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
			if (PageAnon(page))
 | 
								if (PageAnon(page))
 | 
				
			||||||
				dec_mm_counter(mm, MM_ANONPAGES);
 | 
									dec_mm_counter(mm, MM_ANONPAGES);
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue