Subject: [PATCH] mm: set pageblock_order in compiling time

That is initial setting, and could be override by command line.

-v2: use HPAGE_SHIFT_DEFAULT by default and set that again when hpage_shift
     get updated again.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/ia64/mm/hugetlbpage.c |    4 ++++
 mm/page_alloc.c            |   45 ++++++---------------------------------------
 2 files changed, 10 insertions(+), 39 deletions(-)

Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c
+++ linux-2.6/mm/page_alloc.c
@@ -147,7 +147,12 @@ bool pm_suspended_storage(void)
 #endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
-int pageblock_order __read_mostly;
+/*
+ * Assume the largest contiguous order of interest is a huge page.
+ * This value may be variable depending on boot parameters on IA64 and
+ * powerpc.
+ */
+int pageblock_order = ((HPAGE_SHIFT_DEFAULT > PAGE_SHIFT) ? (HPAGE_SHIFT_DEFAULT - PAGE_SHIFT) : (MAX_ORDER - 1)) __read_mostly;
 #endif
 
 static void __free_pages_ok(struct page *page, unsigned int order);
@@ -4298,43 +4303,6 @@ static inline void setup_usemap(struct p
 				struct zone *zone, unsigned long zonesize) {}
 #endif /* CONFIG_SPARSEMEM */
 
-#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
-
-/* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
-static inline void __init set_pageblock_order(void)
-{
-	unsigned int order;
-
-	/* Check that pageblock_nr_pages has not already been setup */
-	if (pageblock_order)
-		return;
-
-	if (HPAGE_SHIFT > PAGE_SHIFT)
-		order = HUGETLB_PAGE_ORDER;
-	else
-		order = MAX_ORDER - 1;
-
-	/*
-	 * Assume the largest contiguous order of interest is a huge page.
-	 * This value may be variable depending on boot parameters on IA64 and
-	 * powerpc.
-	 */
-	pageblock_order = order;
-}
-#else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
-
-/*
- * When CONFIG_HUGETLB_PAGE_SIZE_VARIABLE is not set, set_pageblock_order()
- * is unused as pageblock_order is set at compile-time. See
- * include/linux/pageblock-flags.h for the values of pageblock_order based on
- * the kernel config
- */
-static inline void set_pageblock_order(void)
-{
-}
-
-#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
-
 /*
  * Set up the zone data structures:
  *   - mark all pages reserved
@@ -4413,7 +4381,6 @@ static void __paginginit free_area_init_
 		if (!size)
 			continue;
 
-		set_pageblock_order();
 		setup_usemap(pgdat, zone, size);
 		ret = init_currently_empty_zone(zone, zone_start_pfn,
 						size, MEMMAP_EARLY);
Index: linux-2.6/arch/ia64/mm/hugetlbpage.c
===================================================================
--- linux-2.6.orig/arch/ia64/mm/hugetlbpage.c
+++ linux-2.6/arch/ia64/mm/hugetlbpage.c
@@ -202,6 +202,10 @@ static int __init hugetlb_setup_sz(char
 	 * override here with new page shift.
 	 */
 	ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2);
+
+	/* update pageblock_order accordingly */
+	pageblock_order = ((HPAGE_SHIFT > PAGE_SHIFT) ? HUGETLB_PAGE_ORDER : (MAX_ORDER - 1))
+
 	return 0;
 }
 early_param("hugepagesz", hugetlb_setup_sz);
