From 31cfd7b786682261f58439117e9286cceaa8104a Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Sat, 18 Oct 2008 20:27:10 -0700 Subject: [PATCH] --- yaml --- r: 115871 b: refs/heads/master c: 4b2e38ad703541f7845c2d766426148b8d1aa329 h: refs/heads/master i: 115869: f586b47ef511d0bc452fb79ded7c71a2d94c82fe 115867: 5b56cc90a1475c7508ee956fd9ca7d746b050961 115863: 54c5a8d9ab98119f58baf274e773bd89345ebb6d 115855: caddaf0535f334df44e62b84bddff523ce404667 115839: 6c0a54656ba0b036e542d8b4240675fc99e506dd v: v3 --- [refs] | 2 +- trunk/mm/hugetlb.c | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index aecde45d3b99..23aee5614bf8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e575f111dc0f27044e170580e7de50985ab3e011 +refs/heads/master: 4b2e38ad703541f7845c2d766426148b8d1aa329 diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index ab79cd4dd23c..ce8cbb29860b 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -2071,6 +2071,14 @@ follow_huge_pud(struct mm_struct *mm, unsigned long address, return NULL; } +static int huge_zeropage_ok(pte_t *ptep, int write, int shared) +{ + if (!ptep || write || shared) + return 0; + else + return huge_pte_none(huge_ptep_get(ptep)); +} + int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, struct page **pages, struct vm_area_struct **vmas, unsigned long *position, int *length, int i, @@ -2080,6 +2088,8 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long vaddr = *position; int remainder = *length; struct hstate *h = hstate_vma(vma); + int zeropage_ok = 0; + int shared = vma->vm_flags & VM_SHARED; spin_lock(&mm->page_table_lock); while (vaddr < vma->vm_end && remainder) { @@ -2092,8 +2102,11 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, * first, for the page indexing below to work. */ pte = huge_pte_offset(mm, vaddr & huge_page_mask(h)); + if (huge_zeropage_ok(pte, write, shared)) + zeropage_ok = 1; - if (!pte || huge_pte_none(huge_ptep_get(pte)) || + if (!pte || + (huge_pte_none(huge_ptep_get(pte)) && !zeropage_ok) || (write && !pte_write(huge_ptep_get(pte)))) { int ret; @@ -2113,8 +2126,11 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, page = pte_page(huge_ptep_get(pte)); same_page: if (pages) { - get_page(page); - pages[i] = page + pfn_offset; + if (zeropage_ok) + pages[i] = ZERO_PAGE(0); + else + pages[i] = page + pfn_offset; + get_page(pages[i]); } if (vmas)