Change pagemap output format to allow for future reporting of huge pages
Change pagemap output format to allow for future reporting of huge pages. (Format comment and minor cleanups: mpm@selenic.com) Signed-off-by: Hans Rosenfeld <hans.rosenfeld@amd.com> Signed-off-by: Matt Mackall <mpm@selenic.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
51ec92e295
commit
f16278c679
|
@ -527,13 +527,21 @@ struct pagemapread {
|
|||
char __user *out, *end;
|
||||
};
|
||||
|
||||
#define PM_ENTRY_BYTES sizeof(u64)
|
||||
#define PM_RESERVED_BITS 3
|
||||
#define PM_RESERVED_OFFSET (64 - PM_RESERVED_BITS)
|
||||
#define PM_RESERVED_MASK (((1LL<<PM_RESERVED_BITS)-1) << PM_RESERVED_OFFSET)
|
||||
#define PM_SPECIAL(nr) (((nr) << PM_RESERVED_OFFSET) & PM_RESERVED_MASK)
|
||||
#define PM_NOT_PRESENT PM_SPECIAL(1LL)
|
||||
#define PM_SWAP PM_SPECIAL(2LL)
|
||||
#define PM_ENTRY_BYTES sizeof(u64)
|
||||
#define PM_STATUS_BITS 3
|
||||
#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS)
|
||||
#define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET)
|
||||
#define PM_STATUS(nr) (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK)
|
||||
#define PM_PSHIFT_BITS 6
|
||||
#define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS)
|
||||
#define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET)
|
||||
#define PM_PSHIFT(x) (((u64) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK)
|
||||
#define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1)
|
||||
#define PM_PFRAME(x) ((x) & PM_PFRAME_MASK)
|
||||
|
||||
#define PM_PRESENT PM_STATUS(4LL)
|
||||
#define PM_SWAP PM_STATUS(2LL)
|
||||
#define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT)
|
||||
#define PM_END_OF_BUFFER 1
|
||||
|
||||
static int add_to_pagemap(unsigned long addr, u64 pfn,
|
||||
|
@ -574,7 +582,7 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
|
|||
u64 swap_pte_to_pagemap_entry(pte_t pte)
|
||||
{
|
||||
swp_entry_t e = pte_to_swp_entry(pte);
|
||||
return PM_SWAP | swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
|
||||
return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
|
||||
}
|
||||
|
||||
static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
|
||||
|
@ -588,9 +596,11 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
|
|||
u64 pfn = PM_NOT_PRESENT;
|
||||
pte = pte_offset_map(pmd, addr);
|
||||
if (is_swap_pte(*pte))
|
||||
pfn = swap_pte_to_pagemap_entry(*pte);
|
||||
pfn = PM_PFRAME(swap_pte_to_pagemap_entry(*pte))
|
||||
| PM_PSHIFT(PAGE_SHIFT) | PM_SWAP;
|
||||
else if (pte_present(*pte))
|
||||
pfn = pte_pfn(*pte);
|
||||
pfn = PM_PFRAME(pte_pfn(*pte))
|
||||
| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
|
||||
/* unmap so we're not in atomic when we copy to userspace */
|
||||
pte_unmap(pte);
|
||||
err = add_to_pagemap(addr, pfn, pm);
|
||||
|
@ -611,12 +621,20 @@ static struct mm_walk pagemap_walk = {
|
|||
/*
|
||||
* /proc/pid/pagemap - an array mapping virtual pages to pfns
|
||||
*
|
||||
* For each page in the address space, this file contains one 64-bit
|
||||
* entry representing the corresponding physical page frame number
|
||||
* (PFN) if the page is present. If there is a swap entry for the
|
||||
* physical page, then an encoding of the swap file number and the
|
||||
* page's offset into the swap file are returned. If no page is
|
||||
* present at all, PM_NOT_PRESENT is returned. This allows determining
|
||||
* For each page in the address space, this file contains one 64-bit entry
|
||||
* consisting of the following:
|
||||
*
|
||||
* Bits 0-55 page frame number (PFN) if present
|
||||
* Bits 0-4 swap type if swapped
|
||||
* Bits 5-55 swap offset if swapped
|
||||
* Bits 55-60 page shift (page size = 1<<page shift)
|
||||
* Bit 61 reserved for future use
|
||||
* Bit 62 page swapped
|
||||
* Bit 63 page present
|
||||
*
|
||||
* If the page is not present but in swap, then the PFN contains an
|
||||
* encoding of the swap file number and the page's offset into the
|
||||
* swap. Unmapped pages return a null PFN. This allows determining
|
||||
* precisely which pages are mapped (or in swap) and comparing mapped
|
||||
* pages between processes.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue