diff options
author | Andy Whitcroft <apw@shadowen.org> | 2008-11-06 15:53:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-06 18:41:18 -0500 |
commit | 18229df5b613ed0732a766fc37850de2e7988e43 (patch) | |
tree | ab235f27a5a9d93b8f94773252a1d8f660b9fad1 /mm/hugetlb.c | |
parent | 69d177c2fc702d402b17fdca2190d5a7e3ca55c5 (diff) |
hugetlb: pull gigantic page initialisation out of the default path
As we can determine exactly when a gigantic page is in use we can optimise
the common regular page cases by pulling out gigantic page initialisation
into its own function. As gigantic pages are never released to buddy we
do not need a destructor. This effectivly reverts the previous change to
the main buddy allocator. It also adds a paranoid check to ensure we
never release gigantic pages from hugetlbfs to the main buddy.
Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Cc: Jon Tollefson <kniht@linux.vnet.ibm.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Christoph Lameter <cl@linux-foundation.org>
Cc: <stable@kernel.org> [2.6.27.x]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r-- | mm/hugetlb.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index e6afe527bd0..d143ab67be4 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -491,6 +491,8 @@ static void update_and_free_page(struct hstate *h, struct page *page) | |||
491 | { | 491 | { |
492 | int i; | 492 | int i; |
493 | 493 | ||
494 | VM_BUG_ON(h->order >= MAX_ORDER); | ||
495 | |||
494 | h->nr_huge_pages--; | 496 | h->nr_huge_pages--; |
495 | h->nr_huge_pages_node[page_to_nid(page)]--; | 497 | h->nr_huge_pages_node[page_to_nid(page)]--; |
496 | for (i = 0; i < pages_per_huge_page(h); i++) { | 498 | for (i = 0; i < pages_per_huge_page(h); i++) { |
@@ -1005,6 +1007,14 @@ found: | |||
1005 | return 1; | 1007 | return 1; |
1006 | } | 1008 | } |
1007 | 1009 | ||
1010 | static void prep_compound_huge_page(struct page *page, int order) | ||
1011 | { | ||
1012 | if (unlikely(order > (MAX_ORDER - 1))) | ||
1013 | prep_compound_gigantic_page(page, order); | ||
1014 | else | ||
1015 | prep_compound_page(page, order); | ||
1016 | } | ||
1017 | |||
1008 | /* Put bootmem huge pages into the standard lists after mem_map is up */ | 1018 | /* Put bootmem huge pages into the standard lists after mem_map is up */ |
1009 | static void __init gather_bootmem_prealloc(void) | 1019 | static void __init gather_bootmem_prealloc(void) |
1010 | { | 1020 | { |
@@ -1015,7 +1025,7 @@ static void __init gather_bootmem_prealloc(void) | |||
1015 | struct hstate *h = m->hstate; | 1025 | struct hstate *h = m->hstate; |
1016 | __ClearPageReserved(page); | 1026 | __ClearPageReserved(page); |
1017 | WARN_ON(page_count(page) != 1); | 1027 | WARN_ON(page_count(page) != 1); |
1018 | prep_compound_page(page, h->order); | 1028 | prep_compound_huge_page(page, h->order); |
1019 | prep_new_huge_page(h, page, page_to_nid(page)); | 1029 | prep_new_huge_page(h, page, page_to_nid(page)); |
1020 | } | 1030 | } |
1021 | } | 1031 | } |