]> err.no Git - linux-2.6/blobdiff - mm/bootmem.c
Merge master.kernel.org:/home/rmk/linux-2.6-serial
[linux-2.6] / mm / bootmem.c
index 260e703850d827d81356f64222a8beceb9f19b0c..c1330cc197835ae66bffaa2baacc032ace0020b4 100644 (file)
@@ -33,6 +33,14 @@ EXPORT_SYMBOL(max_pfn);              /* This is exported so
                                 * dma_get_required_mask(), which uses
                                 * it, can be an inline function */
 
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * If we have booted due to a crash, max_pfn will be a very low value. We need
+ * to know the amount of memory that the previous kernel used.
+ */
+unsigned long saved_max_pfn;
+#endif
+
 /* return the number of _pages_ that will be allocated for the boot bitmap */
 unsigned long __init bootmem_bootmap_pages (unsigned long pages)
 {
@@ -57,7 +65,7 @@ static unsigned long __init init_bootmem_core (pg_data_t *pgdat,
        pgdat->pgdat_next = pgdat_list;
        pgdat_list = pgdat;
 
-       mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
+       mapsize = ALIGN(mapsize, sizeof(long));
        bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
        bdata->node_boot_start = (start << PAGE_SHIFT);
        bdata->node_low_pfn = end;
@@ -178,7 +186,7 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
        } else
                preferred = 0;
 
-       preferred = ((preferred + align - 1) & ~(align - 1)) >> PAGE_SHIFT;
+       preferred = ALIGN(preferred, align) >> PAGE_SHIFT;
        preferred += offset;
        areasize = (size+PAGE_SIZE-1)/PAGE_SIZE;
        incr = align >> PAGE_SHIFT ? : 1;
@@ -219,7 +227,7 @@ found:
         */
        if (align < PAGE_SIZE &&
            bdata->last_offset && bdata->last_pos+1 == start) {
-               offset = (bdata->last_offset+align-1) & ~(align-1);
+               offset = ALIGN(bdata->last_offset, align);
                BUG_ON(offset > PAGE_SIZE);
                remaining_size = PAGE_SIZE-offset;
                if (size < remaining_size) {
@@ -256,6 +264,7 @@ found:
 static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
 {
        struct page *page;
+       unsigned long pfn;
        bootmem_data_t *bdata = pgdat->bdata;
        unsigned long i, count, total = 0;
        unsigned long idx;
@@ -266,7 +275,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
 
        count = 0;
        /* first extant page of the node */
-       page = virt_to_page(phys_to_virt(bdata->node_boot_start));
+       pfn = bdata->node_boot_start >> PAGE_SHIFT;
        idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
        map = bdata->node_bootmem_map;
        /* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
@@ -275,9 +284,11 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
                gofast = 1;
        for (i = 0; i < idx; ) {
                unsigned long v = ~map[i / BITS_PER_LONG];
+
                if (gofast && v == ~0UL) {
                        int j, order;
 
+                       page = pfn_to_page(pfn);
                        count += BITS_PER_LONG;
                        __ClearPageReserved(page);
                        order = ffs(BITS_PER_LONG) - 1;
@@ -292,6 +303,8 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
                        page += BITS_PER_LONG;
                } else if (v) {
                        unsigned long m;
+
+                       page = pfn_to_page(pfn);
                        for (m = 1; m && i < idx; m<<=1, page++, i++) {
                                if (v & m) {
                                        count++;
@@ -302,8 +315,8 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
                        }
                } else {
                        i+=BITS_PER_LONG;
-                       page += BITS_PER_LONG;
                }
+               pfn += BITS_PER_LONG;
        }
        total += count;