Skip to content

Commit

Permalink
proc/pid/pagemap: correctly report non-present ptes and holes between…
Browse files Browse the repository at this point in the history
… vmas

Reset the current pagemap-entry if the current pte isn't present, or if
current vma is over.  Otherwise pagemap reports last entry again and
again.

Non-present pte reporting was broken in commit 092b50b ("pagemap:
introduce data structure for pagemap entry")

Reporting for holes was broken in commit 5aaabe8 ("pagemap: avoid
splitting thp when reading /proc/pid/pagemap")

Signed-off-by: Konstantin Khlebnikov <[email protected]>
Reported-by: Pavel Emelyanov <[email protected]>
Cc: Naoya Horiguchi <[email protected]>
Cc: KAMEZAWA Hiroyuki <[email protected]>
Cc: Andi Kleen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
koct9i authored and torvalds committed May 10, 2012
1 parent bc46f93 commit 16fbdce
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions fs/proc/task_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,8 @@ static void pte_to_pagemap_entry(pagemap_entry_t *pme, pte_t pte)
else if (pte_present(pte))
*pme = make_pme(PM_PFRAME(pte_pfn(pte))
| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
else
*pme = make_pme(PM_NOT_PRESENT);
}

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
Expand All @@ -761,6 +763,8 @@ static void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme,
if (pmd_present(pmd))
*pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset)
| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
else
*pme = make_pme(PM_NOT_PRESENT);
}
#else
static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme,
Expand Down Expand Up @@ -801,8 +805,10 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,

/* check to see if we've left 'vma' behind
* and need a new, higher one */
if (vma && (addr >= vma->vm_end))
if (vma && (addr >= vma->vm_end)) {
vma = find_vma(walk->mm, addr);
pme = make_pme(PM_NOT_PRESENT);
}

/* check that 'vma' actually covers this address,
* and that it isn't a huge page vma */
Expand Down Expand Up @@ -830,6 +836,8 @@ static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme,
if (pte_present(pte))
*pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset)
| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
else
*pme = make_pme(PM_NOT_PRESENT);
}

/* This function walks within one hugetlb entry in the single call */
Expand All @@ -839,7 +847,7 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
{
struct pagemapread *pm = walk->private;
int err = 0;
pagemap_entry_t pme = make_pme(PM_NOT_PRESENT);
pagemap_entry_t pme;

for (; addr != end; addr += PAGE_SIZE) {
int offset = (addr & ~hmask) >> PAGE_SHIFT;
Expand Down

0 comments on commit 16fbdce

Please sign in to comment.