mm: report the pagesize backing a VMA in /proc/pid/smaps
[sfrench/cifs-2.6.git] / mm / hugetlb.c
index d143ab67be444119b6240c5f8461a72fe2fc9647..5cb8bc7c80f709a8213309b9617c4a396854f057 100644 (file)
@@ -219,6 +219,22 @@ static pgoff_t vma_hugecache_offset(struct hstate *h,
                        (vma->vm_pgoff >> huge_page_order(h));
 }
 
+/*
+ * Return the size of the pages allocated when backing a VMA. In the majority
+ * cases this will be same size as used by the page table entries.
+ */
+unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
+{
+       struct hstate *hstate;
+
+       if (!is_vm_hugetlb_page(vma))
+               return PAGE_SIZE;
+
+       hstate = hstate_vma(vma);
+
+       return 1UL << (hstate->order + PAGE_SHIFT);
+}
+
 /*
  * Flags for MAP_PRIVATE reservations.  These are stored in the bottom
  * bits of the reservation map pointer, which are always clear due to
@@ -1796,6 +1812,7 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
 static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
                                struct page *page, unsigned long address)
 {
+       struct hstate *h = hstate_vma(vma);
        struct vm_area_struct *iter_vma;
        struct address_space *mapping;
        struct prio_tree_iter iter;
@@ -1805,7 +1822,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
         * vm_pgoff is in PAGE_SIZE units, hence the different calculation
         * from page cache lookup which is in HPAGE_SIZE units.
         */
-       address = address & huge_page_mask(hstate_vma(vma));
+       address = address & huge_page_mask(h);
        pgoff = ((address - vma->vm_start) >> PAGE_SHIFT)
                + (vma->vm_pgoff >> PAGE_SHIFT);
        mapping = (struct address_space *)page_private(page);
@@ -1824,7 +1841,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
                 */
                if (!is_vma_resv_set(iter_vma, HPAGE_RESV_OWNER))
                        unmap_hugepage_range(iter_vma,
-                               address, address + HPAGE_SIZE,
+                               address, address + huge_page_size(h),
                                page);
        }