|
@@ -2331,16 +2331,23 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
|
|
|
if (huge_pmd_unshare(mm, &address, ptep))
|
|
|
continue;
|
|
|
|
|
|
+ pte = huge_ptep_get(ptep);
|
|
|
+ if (huge_pte_none(pte))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * HWPoisoned hugepage is already unmapped and dropped reference
|
|
|
+ */
|
|
|
+ if (unlikely(is_hugetlb_entry_hwpoisoned(pte)))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ page = pte_page(pte);
|
|
|
/*
|
|
|
* If a reference page is supplied, it is because a specific
|
|
|
* page is being unmapped, not a range. Ensure the page we
|
|
|
* are about to unmap is the actual page of interest.
|
|
|
*/
|
|
|
if (ref_page) {
|
|
|
- pte = huge_ptep_get(ptep);
|
|
|
- if (huge_pte_none(pte))
|
|
|
- continue;
|
|
|
- page = pte_page(pte);
|
|
|
if (page != ref_page)
|
|
|
continue;
|
|
|
|
|
@@ -2353,16 +2360,6 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
|
|
|
}
|
|
|
|
|
|
pte = huge_ptep_get_and_clear(mm, address, ptep);
|
|
|
- if (huge_pte_none(pte))
|
|
|
- continue;
|
|
|
-
|
|
|
- /*
|
|
|
- * HWPoisoned hugepage is already unmapped and dropped reference
|
|
|
- */
|
|
|
- if (unlikely(is_hugetlb_entry_hwpoisoned(pte)))
|
|
|
- continue;
|
|
|
-
|
|
|
- page = pte_page(pte);
|
|
|
if (pte_dirty(pte))
|
|
|
set_page_dirty(page);
|
|
|
list_add(&page->lru, &page_list);
|