From 930978f9396e02388f1bef0139075fc6b2abdaf6 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Mon, 24 May 2010 14:32:11 -0700 Subject: [PATCH] --- yaml --- r: 198234 b: refs/heads/master c: e48293fd75b3aa67f43ad6e3d2ff397caa55d58b h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/mm/mincore.c | 75 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/[refs] b/[refs] index 9d60a06d3904..44538c8a2cbb 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 25ef0e50cca790370ad7838e3ad74db6a6a2d829 +refs/heads/master: e48293fd75b3aa67f43ad6e3d2ff397caa55d58b diff --git a/trunk/mm/mincore.c b/trunk/mm/mincore.c index 211604adc23c..9ac42dc6d7b6 100644 --- a/trunk/mm/mincore.c +++ b/trunk/mm/mincore.c @@ -144,6 +144,60 @@ static void mincore_pte_range(struct vm_area_struct *vma, pmd_t *pmd, pte_unmap_unlock(ptep - 1, ptl); } +static void mincore_pmd_range(struct vm_area_struct *vma, pud_t *pud, + unsigned long addr, unsigned long end, + unsigned char *vec) +{ + unsigned long next; + pmd_t *pmd; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if (pmd_none_or_clear_bad(pmd)) + mincore_unmapped_range(vma, addr, next, vec); + else + mincore_pte_range(vma, pmd, addr, next, vec); + vec += (next - addr) >> PAGE_SHIFT; + } while (pmd++, addr = next, addr != end); +} + +static void mincore_pud_range(struct vm_area_struct *vma, pgd_t *pgd, + unsigned long addr, unsigned long end, + unsigned char *vec) +{ + unsigned long next; + pud_t *pud; + + pud = pud_offset(pgd, addr); + do { + next = pud_addr_end(addr, end); + if (pud_none_or_clear_bad(pud)) + mincore_unmapped_range(vma, addr, next, vec); + else + mincore_pmd_range(vma, pud, addr, next, vec); + vec += (next - addr) >> PAGE_SHIFT; + } while (pud++, addr = next, addr != end); +} + +static void mincore_page_range(struct vm_area_struct *vma, + unsigned long addr, unsigned long end, + unsigned char *vec) +{ + unsigned long next; + pgd_t *pgd; + + pgd = pgd_offset(vma->vm_mm, addr); + do { + next = pgd_addr_end(addr, end); + if (pgd_none_or_clear_bad(pgd)) + mincore_unmapped_range(vma, addr, next, vec); + else + mincore_pud_range(vma, pgd, addr, next, vec); + vec += (next - addr) >> PAGE_SHIFT; + } while (pgd++, addr = next, addr != end); +} + /* * Do a chunk of "sys_mincore()". We've already checked * all the arguments, we hold the mmap semaphore: we should @@ -151,9 +205,6 @@ static void mincore_pte_range(struct vm_area_struct *vma, pmd_t *pmd, */ static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *vec) { - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; struct vm_area_struct *vma; unsigned long end; @@ -170,21 +221,11 @@ static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *v end = pmd_addr_end(addr, end); - pgd = pgd_offset(vma->vm_mm, addr); - if (pgd_none_or_clear_bad(pgd)) - goto none_mapped; - pud = pud_offset(pgd, addr); - if (pud_none_or_clear_bad(pud)) - goto none_mapped; - pmd = pmd_offset(pud, addr); - if (pmd_none_or_clear_bad(pmd)) - goto none_mapped; - - mincore_pte_range(vma, pmd, addr, end, vec); - return (end - addr) >> PAGE_SHIFT; + if (is_vm_hugetlb_page(vma)) + mincore_hugetlb_page_range(vma, addr, end, vec); + else + mincore_page_range(vma, addr, end, vec); -none_mapped: - mincore_unmapped_range(vma, addr, end, vec); return (end - addr) >> PAGE_SHIFT; }