diff options
author | Andi Kleen <ak@suse.de> | 2008-07-24 00:27:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:18 -0400 |
commit | ceb868796181dc95ea01a110e123afd391639873 (patch) | |
tree | 991be618e5195b05c31974a19adb4b9602315013 /mm | |
parent | 4abd32dbab201c3ced0b0af12accea77cd9eeffc (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.c | 9 | ||||
-rw-r--r-- | mm/memory.c | 15 |
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 * | ||
2001 | follow_huge_pud(struct mm_struct *mm, unsigned long address, | ||
2002 | pud_t *pud, int write) | ||
2003 | { | ||
2004 | BUG(); | ||
2005 | return NULL; | ||
2006 | } | ||
2007 | |||
1999 | int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, | 2008 | int 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; |