Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309741
b: refs/heads/master
c: 052fb0d
h: refs/heads/master
i:
  309739: b7b1922
v: v3
  • Loading branch information
Konstantin Khlebnikov authored and Linus Torvalds committed Jun 1, 2012
1 parent 393ddde commit 87d7776
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 715be1fce0d964aca15618b24f6f415f3cbd03c8
refs/heads/master: 052fb0d635df5d49dfc85687d94e1a87bf09378d
2 changes: 1 addition & 1 deletion trunk/Documentation/vm/pagemap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ There are three components to pagemap:
* Bits 0-4 swap type if swapped
* Bits 5-54 swap offset if swapped
* Bits 55-60 page shift (page size = 1<<page shift)
* Bit 61 reserved for future use
* Bit 61 page is file-page or shared-anon
* Bit 62 page swapped
* Bit 63 page present

Expand Down
48 changes: 30 additions & 18 deletions trunk/fs/proc/task_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,7 @@ struct pagemapread {

#define PM_PRESENT PM_STATUS(4LL)
#define PM_SWAP PM_STATUS(2LL)
#define PM_FILE PM_STATUS(1LL)
#define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT)
#define PM_END_OF_BUFFER 1

Expand Down Expand Up @@ -733,22 +734,33 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
return err;
}

static u64 swap_pte_to_pagemap_entry(pte_t pte)
static void pte_to_pagemap_entry(pagemap_entry_t *pme,
struct vm_area_struct *vma, unsigned long addr, pte_t pte)
{
swp_entry_t e = pte_to_swp_entry(pte);
return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
}

static void pte_to_pagemap_entry(pagemap_entry_t *pme, pte_t pte)
{
if (is_swap_pte(pte))
*pme = make_pme(PM_PFRAME(swap_pte_to_pagemap_entry(pte))
| PM_PSHIFT(PAGE_SHIFT) | PM_SWAP);
else if (pte_present(pte))
*pme = make_pme(PM_PFRAME(pte_pfn(pte))
| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
else
u64 frame, flags;
struct page *page = NULL;

if (pte_present(pte)) {
frame = pte_pfn(pte);
flags = PM_PRESENT;
page = vm_normal_page(vma, addr, pte);
} else if (is_swap_pte(pte)) {
swp_entry_t entry = pte_to_swp_entry(pte);

frame = swp_type(entry) |
(swp_offset(entry) << MAX_SWAPFILES_SHIFT);
flags = PM_SWAP;
if (is_migration_entry(entry))
page = migration_entry_to_page(entry);
} else {
*pme = make_pme(PM_NOT_PRESENT);
return;
}

if (page && !PageAnon(page))
flags |= PM_FILE;

*pme = make_pme(PM_PFRAME(frame) | PM_PSHIFT(PAGE_SHIFT) | flags);
}

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
Expand Down Expand Up @@ -815,7 +827,7 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
if (vma && (vma->vm_start <= addr) &&
!is_vm_hugetlb_page(vma)) {
pte = pte_offset_map(pmd, addr);
pte_to_pagemap_entry(&pme, *pte);
pte_to_pagemap_entry(&pme, vma, addr, *pte);
/* unmap before userspace copy */
pte_unmap(pte);
}
Expand Down Expand Up @@ -869,11 +881,11 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
* 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-54 page frame number (PFN) if present
* Bits 0-4 swap type if swapped
* Bits 5-55 swap offset if swapped
* Bits 5-54 swap offset if swapped
* Bits 55-60 page shift (page size = 1<<page shift)
* Bit 61 reserved for future use
* Bit 61 page is file-page or shared-anon
* Bit 62 page swapped
* Bit 63 page present
*
Expand Down

0 comments on commit 87d7776

Please sign in to comment.