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>
This commit is contained in:
committed by
Linus Torvalds
parent
69d177c2fc
commit
18229df5b6
@@ -263,34 +263,48 @@ void prep_compound_page(struct page *page, unsigned long order)
|
||||
{
|
||||
int i;
|
||||
int nr_pages = 1 << order;
|
||||
struct page *p = page + 1;
|
||||
|
||||
set_compound_page_dtor(page, free_compound_page);
|
||||
set_compound_order(page, order);
|
||||
__SetPageHead(page);
|
||||
for (i = 1; i < nr_pages; i++, p++) {
|
||||
if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
|
||||
p = pfn_to_page(page_to_pfn(page) + i);
|
||||
for (i = 1; i < nr_pages; i++) {
|
||||
struct page *p = page + i;
|
||||
|
||||
__SetPageTail(p);
|
||||
p->first_page = page;
|
||||
}
|
||||
}
|
||||
|
||||
static void destroy_compound_page(struct page *page, unsigned long order)
|
||||
#ifdef CONFIG_HUGETLBFS
|
||||
void prep_compound_gigantic_page(struct page *page, unsigned long order)
|
||||
{
|
||||
int i;
|
||||
int nr_pages = 1 << order;
|
||||
struct page *p = page + 1;
|
||||
|
||||
set_compound_page_dtor(page, free_compound_page);
|
||||
set_compound_order(page, order);
|
||||
__SetPageHead(page);
|
||||
for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
|
||||
__SetPageTail(p);
|
||||
p->first_page = page;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void destroy_compound_page(struct page *page, unsigned long order)
|
||||
{
|
||||
int i;
|
||||
int nr_pages = 1 << order;
|
||||
|
||||
if (unlikely(compound_order(page) != order))
|
||||
bad_page(page);
|
||||
|
||||
if (unlikely(!PageHead(page)))
|
||||
bad_page(page);
|
||||
__ClearPageHead(page);
|
||||
for (i = 1; i < nr_pages; i++, p++) {
|
||||
if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
|
||||
p = pfn_to_page(page_to_pfn(page) + i);
|
||||
for (i = 1; i < nr_pages; i++) {
|
||||
struct page *p = page + i;
|
||||
|
||||
if (unlikely(!PageTail(p) |
|
||||
(p->first_page != page)))
|
||||
|
Reference in New Issue
Block a user