aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2008-07-24 00:27:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:18 -0400
commitceb868796181dc95ea01a110e123afd391639873 (patch)
tree991be618e5195b05c31974a19adb4b9602315013 /mm
parent4abd32dbab201c3ced0b0af12accea77cd9eeffc (diff)
hugetlb: introduce pud_huge
Straight forward extensions for huge pages located in the PUD instead of PMDs. Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Nick Piggin <npiggin@suse.de> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/hugetlb.c9
-rw-r--r--mm/memory.c15
2 files changed, 20 insertions, 4 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 0c74c14dd2f7..107c1ce223cb 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1996,6 +1996,15 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
1996 return ret; 1996 return ret;
1997} 1997}
1998 1998
1999/* Can be overriden by architectures */
2000__attribute__((weak)) struct page *
2001follow_huge_pud(struct mm_struct *mm, unsigned long address,
2002 pud_t *pud, int write)
2003{
2004 BUG();
2005 return NULL;
2006}
2007
1999int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, 2008int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
2000 struct page **pages, struct vm_area_struct **vmas, 2009 struct page **pages, struct vm_area_struct **vmas,
2001 unsigned long *position, int *length, int i, 2010 unsigned long *position, int *length, int i,
diff --git a/mm/memory.c b/mm/memory.c
index 02fc6b1047b0..262e3eb6601a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -998,19 +998,24 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
998 goto no_page_table; 998 goto no_page_table;
999 999
1000 pud = pud_offset(pgd, address); 1000 pud = pud_offset(pgd, address);
1001 if (pud_none(*pud) || unlikely(pud_bad(*pud))) 1001 if (pud_none(*pud))
1002 goto no_page_table;
1003 if (pud_huge(*pud)) {
1004 BUG_ON(flags & FOLL_GET);
1005 page = follow_huge_pud(mm, address, pud, flags & FOLL_WRITE);
1006 goto out;
1007 }
1008 if (unlikely(pud_bad(*pud)))
1002 goto no_page_table; 1009 goto no_page_table;
1003 1010
1004 pmd = pmd_offset(pud, address); 1011 pmd = pmd_offset(pud, address);
1005 if (pmd_none(*pmd)) 1012 if (pmd_none(*pmd))
1006 goto no_page_table; 1013 goto no_page_table;
1007
1008 if (pmd_huge(*pmd)) { 1014 if (pmd_huge(*pmd)) {
1009 BUG_ON(flags & FOLL_GET); 1015 BUG_ON(flags & FOLL_GET);
1010 page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE); 1016 page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
1011 goto out; 1017 goto out;
1012 } 1018 }
1013
1014 if (unlikely(pmd_bad(*pmd))) 1019 if (unlikely(pmd_bad(*pmd)))
1015 goto no_page_table; 1020 goto no_page_table;
1016 1021
@@ -1567,6 +1572,8 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
1567 unsigned long next; 1572 unsigned long next;
1568 int err; 1573 int err;
1569 1574
1575 BUG_ON(pud_huge(*pud));
1576
1570 pmd = pmd_alloc(mm, pud, addr); 1577 pmd = pmd_alloc(mm, pud, addr);
1571 if (!pmd) 1578 if (!pmd)
1572 return -ENOMEM; 1579 return -ENOMEM;