aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2005-04-19 16:29:16 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org.(none)>2005-04-19 16:29:16 -0400
commit3bf5ee95648c694bac4d13529563c230cd4fe5f2 (patch)
tree9430e6e4f4c3d586ecb7375cd780fd17694888c7 /include/linux
parentee39b37b23da0b6ec53a8ebe90ff41c016f8ae27 (diff)
[PATCH] freepgt: hugetlb_free_pgd_range
ia64 and ppc64 had hugetlb_free_pgtables functions which were no longer being called, and it wasn't obvious what to do about them. The ppc64 case turns out to be easy: the associated tables are noted elsewhere and freed later, safe to either skip its hugetlb areas or go through the motions of freeing nothing. Since ia64 does need a special case, restore to ppc64 the special case of skipping them. The ia64 hugetlb case has been broken since pgd_addr_end went in, though it probably appeared to work okay if you just had one such area; in fact it's been broken much longer if you consider a long munmap spanning from another region into the hugetlb region. In the ia64 hugetlb region, more virtual address bits are available than in the other regions, yet the page tables are structured the same way: the page at the bottom is larger. Here we need to scale down each addr before passing it to the standard free_pgd_range. Was about to write a hugely_scaled_down macro, but found htlbpage_to_page already exists for just this purpose. Fixed off-by-one in ia64 is_hugepage_only_range. Uninline free_pgd_range to make it available to ia64. Make sure the vma-gathering loop in free_pgtables cannot join a hugepage_only_range to any other (safe to join huges? probably but don't bother). Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/hugetlb.h6
-rw-r--r--include/linux/mm.h4
2 files changed, 7 insertions, 3 deletions
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index ae45676d27ba..6af1ae4a8211 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -37,7 +37,8 @@ extern int sysctl_hugetlb_shm_group;
37 37
38#ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE 38#ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE
39#define is_hugepage_only_range(mm, addr, len) 0 39#define is_hugepage_only_range(mm, addr, len) 0
40#define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0) 40#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \
41 do { } while (0)
41#endif 42#endif
42 43
43#ifndef ARCH_HAS_PREPARE_HUGEPAGE_RANGE 44#ifndef ARCH_HAS_PREPARE_HUGEPAGE_RANGE
@@ -72,7 +73,8 @@ static inline unsigned long hugetlb_total_pages(void)
72#define prepare_hugepage_range(addr, len) (-EINVAL) 73#define prepare_hugepage_range(addr, len) (-EINVAL)
73#define pmd_huge(x) 0 74#define pmd_huge(x) 0
74#define is_hugepage_only_range(mm, addr, len) 0 75#define is_hugepage_only_range(mm, addr, len) 0
75#define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0) 76#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \
77 do { } while (0)
76#define alloc_huge_page() ({ NULL; }) 78#define alloc_huge_page() ({ NULL; })
77#define free_huge_page(p) ({ (void)(p); BUG(); }) 79#define free_huge_page(p) ({ (void)(p); BUG(); })
78 80
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 59eca28b5ae2..c74a74ca401d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -587,7 +587,9 @@ unsigned long unmap_vmas(struct mmu_gather **tlb, struct mm_struct *mm,
587 struct vm_area_struct *start_vma, unsigned long start_addr, 587 struct vm_area_struct *start_vma, unsigned long start_addr,
588 unsigned long end_addr, unsigned long *nr_accounted, 588 unsigned long end_addr, unsigned long *nr_accounted,
589 struct zap_details *); 589 struct zap_details *);
590void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma, 590void free_pgd_range(struct mmu_gather **tlb, unsigned long addr,
591 unsigned long end, unsigned long floor, unsigned long ceiling);
592void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *start_vma,
591 unsigned long floor, unsigned long ceiling); 593 unsigned long floor, unsigned long ceiling);
592int copy_page_range(struct mm_struct *dst, struct mm_struct *src, 594int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
593 struct vm_area_struct *vma); 595 struct vm_area_struct *vma);