aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/bootmem.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 35b3cb667036..319a79bce7cd 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -377,7 +377,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
377 struct page *page; 377 struct page *page;
378 unsigned long pfn; 378 unsigned long pfn;
379 bootmem_data_t *bdata = pgdat->bdata; 379 bootmem_data_t *bdata = pgdat->bdata;
380 unsigned long i, count, total = 0; 380 unsigned long i, count;
381 unsigned long idx; 381 unsigned long idx;
382 unsigned long *map; 382 unsigned long *map;
383 int gofast = 0; 383 int gofast = 0;
@@ -389,10 +389,13 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
389 pfn = PFN_DOWN(bdata->node_boot_start); 389 pfn = PFN_DOWN(bdata->node_boot_start);
390 idx = bdata->node_low_pfn - pfn; 390 idx = bdata->node_low_pfn - pfn;
391 map = bdata->node_bootmem_map; 391 map = bdata->node_bootmem_map;
392 /* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */ 392 /*
393 if (bdata->node_boot_start == 0 || 393 * Check if we are aligned to BITS_PER_LONG pages. If so, we might
394 ffs(bdata->node_boot_start) - PAGE_SHIFT > ffs(BITS_PER_LONG)) 394 * be able to free page orders of that size at once.
395 */
396 if (!(pfn & (BITS_PER_LONG-1)))
395 gofast = 1; 397 gofast = 1;
398
396 for (i = 0; i < idx; ) { 399 for (i = 0; i < idx; ) {
397 unsigned long v = ~map[i / BITS_PER_LONG]; 400 unsigned long v = ~map[i / BITS_PER_LONG];
398 401
@@ -420,23 +423,19 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
420 } 423 }
421 pfn += BITS_PER_LONG; 424 pfn += BITS_PER_LONG;
422 } 425 }
423 total += count;
424 426
425 /* 427 /*
426 * Now free the allocator bitmap itself, it's not 428 * Now free the allocator bitmap itself, it's not
427 * needed anymore: 429 * needed anymore:
428 */ 430 */
429 page = virt_to_page(bdata->node_bootmem_map); 431 page = virt_to_page(bdata->node_bootmem_map);
430 count = 0;
431 idx = (get_mapsize(bdata) + PAGE_SIZE-1) >> PAGE_SHIFT; 432 idx = (get_mapsize(bdata) + PAGE_SIZE-1) >> PAGE_SHIFT;
432 for (i = 0; i < idx; i++, page++) { 433 for (i = 0; i < idx; i++, page++)
433 __free_pages_bootmem(page, 0); 434 __free_pages_bootmem(page, 0);
434 count++; 435 count += i;
435 }
436 total += count;
437 bdata->node_bootmem_map = NULL; 436 bdata->node_bootmem_map = NULL;
438 437
439 return total; 438 return count;
440} 439}
441 440
442unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, 441unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,