Commit 41546c17 authored by Johannes Weiner's avatar Johannes Weiner Committed by Linus Torvalds

bootmem: clean up free_all_bootmem_core

Rewrite the code in a more concise way using less variables.

[akpm@linux-foundation.org: fix printk warnings]
Signed-off-by: default avatarJohannes Weiner <hannes@saeurebad.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 636cc40c
...@@ -144,66 +144,59 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages) ...@@ -144,66 +144,59 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
{ {
int aligned;
struct page *page; struct page *page;
unsigned long pfn; unsigned long start, end, pages, count = 0;
unsigned long i, count;
unsigned long idx, pages; if (!bdata->node_bootmem_map)
unsigned long *map; return 0;
int gofast = 0;
start = PFN_DOWN(bdata->node_boot_start);
BUG_ON(!bdata->node_bootmem_map); end = bdata->node_low_pfn;
count = 0;
/* first extant page of the node */
pfn = PFN_DOWN(bdata->node_boot_start);
idx = bdata->node_low_pfn - pfn;
map = bdata->node_bootmem_map;
/* /*
* Check if we are aligned to BITS_PER_LONG pages. If so, we might * If the start is aligned to the machines wordsize, we might
* be able to free page orders of that size at once. * be able to free pages in bulks of that order.
*/ */
if (!(pfn & (BITS_PER_LONG-1))) aligned = !(start & (BITS_PER_LONG - 1));
gofast = 1;
bdebug("nid=%td start=%lx end=%lx aligned=%d\n",
bdata - bootmem_node_data, start, end, aligned);
while (start < end) {
unsigned long *map, idx, vec;
for (i = 0; i < idx; ) { map = bdata->node_bootmem_map;
unsigned long v = ~map[i / BITS_PER_LONG]; idx = start - PFN_DOWN(bdata->node_boot_start);
vec = ~map[idx / BITS_PER_LONG];
if (gofast && v == ~0UL) { if (aligned && vec == ~0UL && start + BITS_PER_LONG < end) {
int order; int order = ilog2(BITS_PER_LONG);
page = pfn_to_page(pfn); __free_pages_bootmem(pfn_to_page(start), order);
count += BITS_PER_LONG; count += BITS_PER_LONG;
order = ffs(BITS_PER_LONG) - 1; } else {
__free_pages_bootmem(page, order); unsigned long off = 0;
i += BITS_PER_LONG;
page += BITS_PER_LONG; while (vec && off < BITS_PER_LONG) {
} else if (v) { if (vec & 1) {
unsigned long m; page = pfn_to_page(start + off);
page = pfn_to_page(pfn);
for (m = 1; m && i < idx; m<<=1, page++, i++) {
if (v & m) {
count++;
__free_pages_bootmem(page, 0); __free_pages_bootmem(page, 0);
count++;
} }
vec >>= 1;
off++;
} }
} else {
i += BITS_PER_LONG;
} }
pfn += BITS_PER_LONG; start += BITS_PER_LONG;
} }
/*
* Now free the allocator bitmap itself, it's not
* needed anymore:
*/
page = virt_to_page(bdata->node_bootmem_map); page = virt_to_page(bdata->node_bootmem_map);
pages = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start); pages = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start);
idx = bootmem_bootmap_pages(pages); pages = bootmem_bootmap_pages(pages);
for (i = 0; i < idx; i++, page++) count += pages;
__free_pages_bootmem(page, 0); while (pages--)
count += i; __free_pages_bootmem(page++, 0);
bdata->node_bootmem_map = NULL;
bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment