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:
committed by
Linus Torvalds
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;
|
struct page *page;
|
||||||
unsigned long pfn;
|
unsigned long pfn;
|
||||||
bootmem_data_t *bdata = pgdat->bdata;
|
bootmem_data_t *bdata = pgdat->bdata;
|
||||||
unsigned long i, count, total = 0;
|
unsigned long i, count;
|
||||||
unsigned long idx;
|
unsigned long idx;
|
||||||
unsigned long *map;
|
unsigned long *map;
|
||||||
int gofast = 0;
|
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);
|
pfn = PFN_DOWN(bdata->node_boot_start);
|
||||||
idx = bdata->node_low_pfn - pfn;
|
idx = bdata->node_low_pfn - pfn;
|
||||||
map = bdata->node_bootmem_map;
|
map = bdata->node_bootmem_map;
|
||||||
/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
|
/*
|
||||||
if (bdata->node_boot_start == 0 ||
|
* Check if we are aligned to BITS_PER_LONG pages. If so, we might
|
||||||
ffs(bdata->node_boot_start) - PAGE_SHIFT > ffs(BITS_PER_LONG))
|
* be able to free page orders of that size at once.
|
||||||
|
*/
|
||||||
|
if (!(pfn & (BITS_PER_LONG-1)))
|
||||||
gofast = 1;
|
gofast = 1;
|
||||||
|
|
||||||
for (i = 0; i < idx; ) {
|
for (i = 0; i < idx; ) {
|
||||||
unsigned long v = ~map[i / BITS_PER_LONG];
|
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;
|
pfn += BITS_PER_LONG;
|
||||||
}
|
}
|
||||||
total += count;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now free the allocator bitmap itself, it's not
|
* Now free the allocator bitmap itself, it's not
|
||||||
* needed anymore:
|
* needed anymore:
|
||||||
*/
|
*/
|
||||||
page = virt_to_page(bdata->node_bootmem_map);
|
page = virt_to_page(bdata->node_bootmem_map);
|
||||||
count = 0;
|
|
||||||
idx = (get_mapsize(bdata) + PAGE_SIZE-1) >> PAGE_SHIFT;
|
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);
|
__free_pages_bootmem(page, 0);
|
||||||
count++;
|
count += i;
|
||||||
}
|
|
||||||
total += count;
|
|
||||||
bdata->node_bootmem_map = NULL;
|
bdata->node_bootmem_map = NULL;
|
||||||
|
|
||||||
return total;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
|
unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
|
||||||
|
Reference in New Issue
Block a user