diff options
-rw-r--r-- | mm/hugetlb.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index fbd1111ea119..6bf720bc662c 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -301,6 +301,7 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, | |||
301 | { | 301 | { |
302 | struct mm_struct *mm = vma->vm_mm; | 302 | struct mm_struct *mm = vma->vm_mm; |
303 | unsigned long address; | 303 | unsigned long address; |
304 | pte_t *ptep; | ||
304 | pte_t pte; | 305 | pte_t pte; |
305 | struct page *page; | 306 | struct page *page; |
306 | 307 | ||
@@ -309,9 +310,17 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, | |||
309 | BUG_ON(end & ~HPAGE_MASK); | 310 | BUG_ON(end & ~HPAGE_MASK); |
310 | 311 | ||
311 | for (address = start; address < end; address += HPAGE_SIZE) { | 312 | for (address = start; address < end; address += HPAGE_SIZE) { |
312 | pte = huge_ptep_get_and_clear(mm, address, huge_pte_offset(mm, address)); | 313 | ptep = huge_pte_offset(mm, address); |
314 | if (! ptep) | ||
315 | /* This can happen on truncate, or if an | ||
316 | * mmap() is aborted due to an error before | ||
317 | * the prefault */ | ||
318 | continue; | ||
319 | |||
320 | pte = huge_ptep_get_and_clear(mm, address, ptep); | ||
313 | if (pte_none(pte)) | 321 | if (pte_none(pte)) |
314 | continue; | 322 | continue; |
323 | |||
315 | page = pte_page(pte); | 324 | page = pte_page(pte); |
316 | put_page(page); | 325 | put_page(page); |
317 | } | 326 | } |