|
@@ -185,10 +185,23 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
|
|
|
|
|
|
while (start < end) {
|
|
|
unsigned long *map, idx, vec;
|
|
|
+ unsigned shift;
|
|
|
|
|
|
map = bdata->node_bootmem_map;
|
|
|
idx = start - bdata->node_min_pfn;
|
|
|
+ shift = idx & (BITS_PER_LONG - 1);
|
|
|
+ /*
|
|
|
+ * vec holds at most BITS_PER_LONG map bits,
|
|
|
+ * bit 0 corresponds to start.
|
|
|
+ */
|
|
|
vec = ~map[idx / BITS_PER_LONG];
|
|
|
+
|
|
|
+ if (shift) {
|
|
|
+ vec >>= shift;
|
|
|
+ if (end - start >= BITS_PER_LONG)
|
|
|
+ vec |= ~map[idx / BITS_PER_LONG + 1] <<
|
|
|
+ (BITS_PER_LONG - shift);
|
|
|
+ }
|
|
|
/*
|
|
|
* If we have a properly aligned and fully unreserved
|
|
|
* BITS_PER_LONG block of pages in front of us, free
|
|
@@ -201,19 +214,18 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
|
|
|
count += BITS_PER_LONG;
|
|
|
start += BITS_PER_LONG;
|
|
|
} else {
|
|
|
- unsigned long off = 0;
|
|
|
+ unsigned long cur = start;
|
|
|
|
|
|
- vec >>= start & (BITS_PER_LONG - 1);
|
|
|
- while (vec) {
|
|
|
+ start = ALIGN(start + 1, BITS_PER_LONG);
|
|
|
+ while (vec && cur != start) {
|
|
|
if (vec & 1) {
|
|
|
- page = pfn_to_page(start + off);
|
|
|
+ page = pfn_to_page(cur);
|
|
|
__free_pages_bootmem(page, 0);
|
|
|
count++;
|
|
|
}
|
|
|
vec >>= 1;
|
|
|
- off++;
|
|
|
+ ++cur;
|
|
|
}
|
|
|
- start = ALIGN(start + 1, BITS_PER_LONG);
|
|
|
}
|
|
|
}
|
|
|
|