@@ -491,6 +491,7 @@ Memory Area, or VMA) there is a series of lines such as the following::
FileCont512K: 0 kB
FileCont1M: 0 kB
FileCont2M: 0 kB
+ ContPTEMapped: 0 kB
THPeligible: 0
VmFlags: rd ex mr mw me dw
@@ -550,6 +551,10 @@ pmd size. Therefore the exact set of keys will vary by platform. It only
includes pte-mapped memory and reports on anonymous and file-backed memory
separately.
+"ContPTEMapped" is only present for architectures that support indicating a set
+of contiguously mapped ptes in their page tables. In this case, it indicates
+how much of the memory is currently mapped using contpte mappings.
+
"THPeligible" indicates whether the mapping is eligible for allocating THP
pages as well as the THP is PMD mappable or not - 1 if true, 0 otherwise.
It just shows the current status.
@@ -465,6 +465,7 @@ struct mem_size_stats {
unsigned long anon_cont[CONT_ORDER_MAX + 1];
unsigned long file_cont[CONT_ORDER_MAX + 1];
struct cont_accumulator cacc;
+ unsigned long contpte_mapped;
};
static void cacc_init(struct mem_size_stats *mss)
@@ -548,7 +549,7 @@ static void smaps_page_accumulate(struct mem_size_stats *mss,
static void smaps_account(struct mem_size_stats *mss, struct page *page,
bool compound, bool young, bool dirty, bool locked,
- bool migration)
+ bool migration, bool contpte)
{
int i, nr = compound ? compound_nr(page) : 1;
unsigned long size = nr * PAGE_SIZE;
@@ -572,6 +573,10 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,
if (!compound)
cacc_accumulate(mss, page);
+ /* Accumulate all the pages that are part of a contpte. */
+ if (contpte)
+ mss->contpte_mapped += size;
+
/*
* Then accumulate quantities that may depend on sharing, or that may
* differ page-by-page.
@@ -636,13 +641,16 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
struct vm_area_struct *vma = walk->vma;
bool locked = !!(vma->vm_flags & VM_LOCKED);
struct page *page = NULL;
- bool migration = false, young = false, dirty = false;
+ bool migration = false, young = false, dirty = false, cont = false;
pte_t ptent = ptep_get(pte);
if (pte_present(ptent)) {
page = vm_normal_page(vma, addr, ptent);
young = pte_young(ptent);
dirty = pte_dirty(ptent);
+#ifdef pte_cont
+ cont = pte_cont(ptent);
+#endif
} else if (is_swap_pte(ptent)) {
swp_entry_t swpent = pte_to_swp_entry(ptent);
@@ -672,7 +680,7 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
if (!page)
return;
- smaps_account(mss, page, false, young, dirty, locked, migration);
+ smaps_account(mss, page, false, young, dirty, locked, migration, cont);
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -708,7 +716,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
mss->file_thp += HPAGE_PMD_SIZE;
smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd),
- locked, migration);
+ locked, migration, false);
}
#else
static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
@@ -964,6 +972,9 @@ static void __show_smap(struct seq_file *m, const struct mem_size_stats *mss,
cont_label(i, label),
mss->file_cont[i] >> 10);
}
+#ifdef pte_cont
+ SEQ_PUT_DEC(" kB\nContPTEMapped: ", mss->contpte_mapped);
+#endif
seq_puts(m, " kB\n");
}