forked from Minki/linux
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>
This commit is contained in:
parent
b61bfa3c46
commit
6b312c0e6e
21
mm/bootmem.c
21
mm/bootmem.c
@ -377,7 +377,7 @@ 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 i, count;
|
||||
unsigned long idx;
|
||||
unsigned long *map;
|
||||
int gofast = 0;
|
||||
@ -389,10 +389,13 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
|
||||
pfn = PFN_DOWN(bdata->node_boot_start);
|
||||
idx = bdata->node_low_pfn - pfn;
|
||||
map = bdata->node_bootmem_map;
|
||||
/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
|
||||
if (bdata->node_boot_start == 0 ||
|
||||
ffs(bdata->node_boot_start) - PAGE_SHIFT > ffs(BITS_PER_LONG))
|
||||
/*
|
||||
* Check if we are aligned to BITS_PER_LONG pages. If so, we might
|
||||
* be able to free page orders of that size at once.
|
||||
*/
|
||||
if (!(pfn & (BITS_PER_LONG-1)))
|
||||
gofast = 1;
|
||||
|
||||
for (i = 0; i < idx; ) {
|
||||
unsigned long v = ~map[i / BITS_PER_LONG];
|
||||
|
||||
@ -420,23 +423,19 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
|
||||
}
|
||||
pfn += BITS_PER_LONG;
|
||||
}
|
||||
total += count;
|
||||
|
||||
/*
|
||||
* Now free the allocator bitmap itself, it's not
|
||||
* needed anymore:
|
||||
*/
|
||||
page = virt_to_page(bdata->node_bootmem_map);
|
||||
count = 0;
|
||||
idx = (get_mapsize(bdata) + PAGE_SIZE-1) >> PAGE_SHIFT;
|
||||
for (i = 0; i < idx; i++, page++) {
|
||||
for (i = 0; i < idx; i++, page++)
|
||||
__free_pages_bootmem(page, 0);
|
||||
count++;
|
||||
}
|
||||
total += count;
|
||||
count += i;
|
||||
bdata->node_bootmem_map = NULL;
|
||||
|
||||
return total;
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
|
||||
|
Loading…
Reference in New Issue
Block a user