aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@saeurebad.de>2008-07-24 00:26:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:14 -0400
commit6b312c0e6e2f44b020e12953d1dd37eed60e3609 (patch)
tree4f2a1177b0013b411bf4799fb3c776128f5fa6f9 /mm
parentb61bfa3c462671c48a51fb5c31af337c5a996a04 (diff)
mm: fix free_all_bootmem_core alignment check
The check for node_boot_start is bogus because we start freeing at the corresponding pfn. So check if the pfn is properly aligned instead in a more readable way and adjust the documentation. Also remove an unneeded accounting variable. Signed-off-by: Johannes Weiner <hannes@saeurebad.de> Cc: Ingo Molnar <mingo@elte.hu> Cc: Yinghai Lu <yhlu.kernel@gmail.com> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Andy Whitcroft <apw@shadowen.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-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,