Messages in this thread Patch in this message | | | From | "Chen, Kenneth W" <> | Subject | hugetlb demand paging patch part [1/3] | Date | Tue, 13 Apr 2004 16:20:26 -0700 |
| |
Part 1 of 3
1. hugetlb_fix_pte.patch - with demand paging, we can not unconditionally assume valid pmd/pte. Fix it up in arch specific huge_pge_offset() and have all caller check the return value.
i386/mm/hugetlbpage.c | 11 +++++++---- ia64/mm/hugetlbpage.c | 18 ++++++++++++------ sh/mm/hugetlbpage.c | 15 +++++++-------- sparc64/mm/hugetlbpage.c | 15 +++++++-------- 4 files changed, 33 insertions(+), 26 deletions(-)
diff -Nurp linux-2.6.5/arch/i386/mm/hugetlbpage.c linux-2.6.5.htlb/arch/i386/mm/hugetlbpage.c --- linux-2.6.5/arch/i386/mm/hugetlbpage.c 2004-04-10 17:05:34.000000000 -0700 +++ linux-2.6.5.htlb/arch/i386/mm/hugetlbpage.c 2004-04-10 17:10:39.000000000 -0700 @@ -36,7 +36,8 @@ static pte_t *huge_pte_offset(struct mm_ pmd_t *pmd = NULL;
pgd = pgd_offset(mm, addr); - pmd = pmd_offset(pgd, addr); + if (pgd_present(*pgd)) + pmd = pmd_offset(pgd, addr); return (pte_t *) pmd; }
@@ -75,11 +76,13 @@ int copy_hugetlb_page_range(struct mm_st unsigned long addr = vma->vm_start; unsigned long end = vma->vm_end;
- while (addr < end) { + for (; addr < end; addr+= HPAGE_SIZE) { + src_pte = huge_pte_offset(src, addr); + if (!src_pte || pte_none(*src_pte)) + continue; dst_pte = huge_pte_alloc(dst, addr); if (!dst_pte) goto nomem; - src_pte = huge_pte_offset(src, addr); entry = *src_pte; ptepage = pte_page(entry); get_page(ptepage); @@ -227,7 +230,7 @@ void unmap_hugepage_range(struct vm_area
for (address = start; address < end; address += HPAGE_SIZE) { pte = huge_pte_offset(mm, address); - if (pte_none(*pte)) + if (!pte || pte_none(*pte)) continue; page = pte_page(*pte); huge_page_release(page); diff -Nurp linux-2.6.5/arch/ia64/mm/hugetlbpage.c linux-2.6.5.htlb/arch/ia64/mm/hugetlbpage.c --- linux-2.6.5/arch/ia64/mm/hugetlbpage.c 2004-04-10 17:05:34.000000000 -0700 +++ linux-2.6.5.htlb/arch/ia64/mm/hugetlbpage.c 2004-04-10 17:10:29.000000000 -0700 @@ -48,8 +48,11 @@ huge_pte_offset (struct mm_struct *mm, u pte_t *pte = NULL;
pgd = pgd_offset(mm, taddr); - pmd = pmd_offset(pgd, taddr); - pte = pte_offset_map(pmd, taddr); + if (pgd_present(*pgd)) { + pmd = pmd_offset(pgd, taddr); + if (pmd_present(*pmd)) + pte = pte_offset_map(pmd, taddr); + } return pte; }
@@ -95,17 +98,18 @@ int copy_hugetlb_page_range(struct mm_st unsigned long addr = vma->vm_start; unsigned long end = vma->vm_end;
- while (addr < end) { + for (; addr < end; addr += HPAGE_SIZE) { + src_pte = huge_pte_offset(src, addr); + if (!src_pte || pte_none(*src_pte)) + continue; dst_pte = huge_pte_alloc(dst, addr); if (!dst_pte) goto nomem; - src_pte = huge_pte_offset(src, addr); entry = *src_pte; ptepage = pte_page(entry); get_page(ptepage); set_pte(dst_pte, entry); dst->rss += (HPAGE_SIZE / PAGE_SIZE); - addr += HPAGE_SIZE; } return 0; nomem: @@ -167,6 +171,8 @@ struct page *follow_huge_addr(struct mm_ pte_t *ptep;
ptep = huge_pte_offset(mm, addr); + if (!ptep || pte_none(*ptep)) + return NULL; page = pte_page(*ptep); page += ((addr & ~HPAGE_MASK) >> PAGE_SHIFT); get_page(page); @@ -247,7 +253,7 @@ void unmap_hugepage_range(struct vm_area
for (address = start; address < end; address += HPAGE_SIZE) { pte = huge_pte_offset(mm, address); - if (pte_none(*pte)) + if (!pte || pte_none(*pte)) continue; page = pte_page(*pte); huge_page_release(page); diff -Nurp linux-2.6.5/arch/sh/mm/hugetlbpage.c linux-2.6.5.htlb/arch/sh/mm/hugetlbpage.c --- linux-2.6.5/arch/sh/mm/hugetlbpage.c 2004-04-10 17:05:34.000000000 -0700 +++ linux-2.6.5.htlb/arch/sh/mm/hugetlbpage.c 2004-04-10 17:45:40.000000000 -0700 @@ -46,9 +46,9 @@ static pte_t *huge_pte_offset(struct mm_ pte_t *pte = NULL;
pgd = pgd_offset(mm, addr); - if (pgd) { + if (pgd_present(*pgd)) { pmd = pmd_offset(pgd, addr); - if (pmd) + if (pmd_present(*pmd)) pte = pte_offset_map(pmd, addr); } return pte; @@ -101,12 +101,13 @@ int copy_hugetlb_page_range(struct mm_st unsigned long end = vma->vm_end; int i;
- while (addr < end) { + for (; addr < end; addr += HPAGE_SIZE) { + src_pte = huge_pte_offset(src, addr); + if (!src_pte || pte_none(*src_pte)) + continue; dst_pte = huge_pte_alloc(dst, addr); if (!dst_pte) goto nomem; - src_pte = huge_pte_offset(src, addr); - BUG_ON(!src_pte || pte_none(*src_pte)); entry = *src_pte; ptepage = pte_page(entry); get_page(ptepage); @@ -116,7 +117,6 @@ int copy_hugetlb_page_range(struct mm_st dst_pte++; } dst->rss += (HPAGE_SIZE / PAGE_SIZE); - addr += HPAGE_SIZE; } return 0;
@@ -202,8 +202,7 @@ void unmap_hugepage_range(struct vm_area
for (address = start; address < end; address += HPAGE_SIZE) { pte = huge_pte_offset(mm, address); - BUG_ON(!pte); - if (pte_none(*pte)) + if (!pte || pte_none(*pte)) continue; page = pte_page(*pte); huge_page_release(page); diff -Nurp linux-2.6.5/arch/sparc64/mm/hugetlbpage.c linux-2.6.5.htlb/arch/sparc64/mm/hugetlbpage.c --- linux-2.6.5/arch/sparc64/mm/hugetlbpage.c 2004-04-10 17:05:34.000000000 -0700 +++ linux-2.6.5.htlb/arch/sparc64/mm/hugetlbpage.c 2004-04-10 17:44:04.000000000 -0700 @@ -43,9 +43,9 @@ static pte_t *huge_pte_offset(struct mm_ pte_t *pte = NULL;
pgd = pgd_offset(mm, addr); - if (pgd) { + if (pgd_present(*pgd)) { pmd = pmd_offset(pgd, addr); - if (pmd) + if (pmd_present(*pmd)) pte = pte_offset_map(pmd, addr); } return pte; @@ -98,12 +98,13 @@ int copy_hugetlb_page_range(struct mm_st unsigned long end = vma->vm_end; int i;
- while (addr < end) { + for (; addr < end; addr += HPAGE_SIZE) { + src_pte = huge_pte_offset(src, addr); + if (!src_pte || pte_none(*src_pte)) + continue; dst_pte = huge_pte_alloc(dst, addr); if (!dst_pte) goto nomem; - src_pte = huge_pte_offset(src, addr); - BUG_ON(!src_pte || pte_none(*src_pte)); entry = *src_pte; ptepage = pte_page(entry); get_page(ptepage); @@ -113,7 +114,6 @@ int copy_hugetlb_page_range(struct mm_st dst_pte++; } dst->rss += (HPAGE_SIZE / PAGE_SIZE); - addr += HPAGE_SIZE; } return 0;
@@ -199,8 +199,7 @@ void unmap_hugepage_range(struct vm_area
for (address = start; address < end; address += HPAGE_SIZE) { pte = huge_pte_offset(mm, address); - BUG_ON(!pte); - if (pte_none(*pte)) + if (!pte || pte_none(*pte)) continue; page = pte_page(*pte); huge_page_release(page);
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |