[PATCH] unexport hugetlb_total_pages
[pandora-kernel.git] / mm / bootmem.c
index 8ec4e4c..e8c5671 100644 (file)
@@ -61,17 +61,9 @@ static unsigned long __init init_bootmem_core (pg_data_t *pgdat,
 {
        bootmem_data_t *bdata = pgdat->bdata;
        unsigned long mapsize = ((end - start)+7)/8;
-       static struct pglist_data *pgdat_last;
-
-       pgdat->pgdat_next = NULL;
-       /* Add new nodes last so that bootmem always starts
-          searching in the first nodes, not the last ones */
-       if (pgdat_last)
-               pgdat_last->pgdat_next = pgdat;
-       else {
-               pgdat_list = pgdat;     
-               pgdat_last = pgdat;
-       }
+
+       pgdat->pgdat_next = pgdat_list;
+       pgdat_list = pgdat;
 
        mapsize = ALIGN(mapsize, sizeof(long));
        bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
@@ -162,10 +154,10 @@ static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr,
  */
 static void * __init
 __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
-               unsigned long align, unsigned long goal)
+             unsigned long align, unsigned long goal, unsigned long limit)
 {
        unsigned long offset, remaining_size, areasize, preferred;
-       unsigned long i, start = 0, incr, eidx;
+       unsigned long i, start = 0, incr, eidx, end_pfn = bdata->node_low_pfn;
        void *ret;
 
        if(!size) {
@@ -174,7 +166,14 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
        }
        BUG_ON(align & (align-1));
 
-       eidx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
+       if (limit && bdata->node_boot_start >= limit)
+               return NULL;
+
+        limit >>=PAGE_SHIFT;
+       if (limit && end_pfn > limit)
+               end_pfn = limit;
+
+       eidx = end_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
        offset = 0;
        if (align &&
            (bdata->node_boot_start & (align - 1UL)) != 0)
@@ -186,11 +185,12 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
         * first, then we try to allocate lower pages.
         */
        if (goal && (goal >= bdata->node_boot_start) && 
-           ((goal >> PAGE_SHIFT) < bdata->node_low_pfn)) {
+           ((goal >> PAGE_SHIFT) < end_pfn)) {
                preferred = goal - bdata->node_boot_start;
 
                if (bdata->last_success >= preferred)
-                       preferred = bdata->last_success;
+                       if (!limit || (limit && limit > bdata->last_success))
+                               preferred = bdata->last_success;
        } else
                preferred = 0;
 
@@ -305,6 +305,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
                                if (j + 16 < BITS_PER_LONG)
                                        prefetchw(page + j + 16);
                                __ClearPageReserved(page + j);
+                               set_page_count(page + j, 0);
                        }
                        __free_pages(page, order);
                        i += BITS_PER_LONG;
@@ -390,14 +391,15 @@ unsigned long __init free_all_bootmem (void)
        return(free_all_bootmem_core(NODE_DATA(0)));
 }
 
-void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
+void * __init __alloc_bootmem_limit (unsigned long size, unsigned long align, unsigned long goal,
+                               unsigned long limit)
 {
        pg_data_t *pgdat = pgdat_list;
        void *ptr;
 
        for_each_pgdat(pgdat)
                if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
-                                               align, goal)))
+                                                align, goal, limit)))
                        return(ptr);
 
        /*
@@ -408,14 +410,16 @@ void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned
        return NULL;
 }
 
-void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal)
+
+void * __init __alloc_bootmem_node_limit (pg_data_t *pgdat, unsigned long size, unsigned long align,
+                                    unsigned long goal, unsigned long limit)
 {
        void *ptr;
 
-       ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal);
+       ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal, limit);
        if (ptr)
                return (ptr);
 
-       return __alloc_bootmem(size, align, goal);
+       return __alloc_bootmem_limit(size, align, goal, limit);
 }