Commit 3340289d authored by Mel Gorman's avatar Mel Gorman Committed by Linus Torvalds

mm: report the MMU pagesize in /proc/pid/smaps

The KernelPageSize entry in /proc/pid/smaps is the pagesize used by the
kernel to back a VMA.  This matches the size used by the MMU in the
majority of cases.  However, one counter-example occurs on PPC64 kernels
whereby a kernel using 64K as a base pagesize may still use 4K pages for
the MMU on older processor.  To distinguish, this patch reports
MMUPageSize as the pagesize used by the MMU in /proc/pid/smaps.
Signed-off-by: default avatarMel Gorman <mel@csn.ul.ie>
Cc: "KOSAKI Motohiro" <kosaki.motohiro@jp.fujitsu.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 08fba699
...@@ -17,6 +17,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, ...@@ -17,6 +17,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep); pte_t *ptep);
/*
* The version of vma_mmu_pagesize() in arch/powerpc/mm/hugetlbpage.c needs
* to override the version in mm/hugetlb.c
*/
#define vma_mmu_pagesize vma_mmu_pagesize
/* /*
* If the arch doesn't supply something else, assume that hugepage * If the arch doesn't supply something else, assume that hugepage
* size aligned regions are ok without further preparation. * size aligned regions are ok without further preparation.
......
...@@ -512,6 +512,13 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, ...@@ -512,6 +512,13 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0); return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0);
} }
unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
{
unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start);
return 1UL << mmu_psize_to_shift(psize);
}
/* /*
* Called by asm hashtable.S for doing lazy icache flush * Called by asm hashtable.S for doing lazy icache flush
*/ */
......
...@@ -397,7 +397,8 @@ static int show_smap(struct seq_file *m, void *v) ...@@ -397,7 +397,8 @@ static int show_smap(struct seq_file *m, void *v)
"Private_Dirty: %8lu kB\n" "Private_Dirty: %8lu kB\n"
"Referenced: %8lu kB\n" "Referenced: %8lu kB\n"
"Swap: %8lu kB\n" "Swap: %8lu kB\n"
"KernelPageSize: %8lu kB\n", "KernelPageSize: %8lu kB\n"
"MMUPageSize: %8lu kB\n",
(vma->vm_end - vma->vm_start) >> 10, (vma->vm_end - vma->vm_start) >> 10,
mss.resident >> 10, mss.resident >> 10,
(unsigned long)(mss.pss >> (10 + PSS_SHIFT)), (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
...@@ -407,7 +408,8 @@ static int show_smap(struct seq_file *m, void *v) ...@@ -407,7 +408,8 @@ static int show_smap(struct seq_file *m, void *v)
mss.private_dirty >> 10, mss.private_dirty >> 10,
mss.referenced >> 10, mss.referenced >> 10,
mss.swap >> 10, mss.swap >> 10,
vma_kernel_pagesize(vma) >> 10); vma_kernel_pagesize(vma) >> 10,
vma_mmu_pagesize(vma) >> 10);
if (m->count < m->size) /* vma is copied successfully */ if (m->count < m->size) /* vma is copied successfully */
m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
......
...@@ -235,6 +235,8 @@ static inline unsigned long huge_page_size(struct hstate *h) ...@@ -235,6 +235,8 @@ static inline unsigned long huge_page_size(struct hstate *h)
extern unsigned long vma_kernel_pagesize(struct vm_area_struct *vma); extern unsigned long vma_kernel_pagesize(struct vm_area_struct *vma);
extern unsigned long vma_mmu_pagesize(struct vm_area_struct *vma);
static inline unsigned long huge_page_mask(struct hstate *h) static inline unsigned long huge_page_mask(struct hstate *h)
{ {
return h->mask; return h->mask;
...@@ -276,6 +278,7 @@ struct hstate {}; ...@@ -276,6 +278,7 @@ struct hstate {};
#define huge_page_size(h) PAGE_SIZE #define huge_page_size(h) PAGE_SIZE
#define huge_page_mask(h) PAGE_MASK #define huge_page_mask(h) PAGE_MASK
#define vma_kernel_pagesize(v) PAGE_SIZE #define vma_kernel_pagesize(v) PAGE_SIZE
#define vma_mmu_pagesize(v) PAGE_SIZE
#define huge_page_order(h) 0 #define huge_page_order(h) 0
#define huge_page_shift(h) PAGE_SHIFT #define huge_page_shift(h) PAGE_SHIFT
static inline unsigned int pages_per_huge_page(struct hstate *h) static inline unsigned int pages_per_huge_page(struct hstate *h)
......
...@@ -235,6 +235,19 @@ unsigned long vma_kernel_pagesize(struct vm_area_struct *vma) ...@@ -235,6 +235,19 @@ unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
return 1UL << (hstate->order + PAGE_SHIFT); return 1UL << (hstate->order + PAGE_SHIFT);
} }
/*
* Return the page size being used by the MMU to back a VMA. In the majority
* of cases, the page size used by the kernel matches the MMU size. On
* architectures where it differs, an architecture-specific version of this
* function is required.
*/
#ifndef vma_mmu_pagesize
unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
{
return vma_kernel_pagesize(vma);
}
#endif
/* /*
* Flags for MAP_PRIVATE reservations. These are stored in the bottom * Flags for MAP_PRIVATE reservations. These are stored in the bottom
* bits of the reservation map pointer, which are always clear due to * bits of the reservation map pointer, which are always clear due to
......
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