aboutsummaryrefslogtreecommitdiffstats
path: root/mm/bootmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/bootmem.c')
-rw-r--r--mm/bootmem.c65
1 files changed, 43 insertions, 22 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 94ea612deccf..9d03ff651359 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -225,6 +225,44 @@ unsigned long __init free_all_bootmem(void)
225 return free_all_bootmem_core(NODE_DATA(0)->bdata); 225 return free_all_bootmem_core(NODE_DATA(0)->bdata);
226} 226}
227 227
228static void __init __free(bootmem_data_t *bdata,
229 unsigned long sidx, unsigned long eidx)
230{
231 unsigned long idx;
232
233 bdebug("nid=%td start=%lx end=%lx\n", bdata - bootmem_node_data,
234 sidx + PFN_DOWN(bdata->node_boot_start),
235 eidx + PFN_DOWN(bdata->node_boot_start));
236
237 for (idx = sidx; idx < eidx; idx++)
238 if (!test_and_clear_bit(idx, bdata->node_bootmem_map))
239 BUG();
240}
241
242static int __init __reserve(bootmem_data_t *bdata, unsigned long sidx,
243 unsigned long eidx, int flags)
244{
245 unsigned long idx;
246 int exclusive = flags & BOOTMEM_EXCLUSIVE;
247
248 bdebug("nid=%td start=%lx end=%lx flags=%x\n",
249 bdata - bootmem_node_data,
250 sidx + PFN_DOWN(bdata->node_boot_start),
251 eidx + PFN_DOWN(bdata->node_boot_start),
252 flags);
253
254 for (idx = sidx; idx < eidx; idx++)
255 if (test_and_set_bit(idx, bdata->node_bootmem_map)) {
256 if (exclusive) {
257 __free(bdata, sidx, idx);
258 return -EBUSY;
259 }
260 bdebug("silent double reserve of PFN %lx\n",
261 idx + PFN_DOWN(bdata->node_boot_start));
262 }
263 return 0;
264}
265
228static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, 266static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr,
229 unsigned long size) 267 unsigned long size)
230{ 268{
@@ -258,14 +296,7 @@ static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr,
258 if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start)) 296 if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start))
259 eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start); 297 eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start);
260 298
261 bdebug("nid=%td start=%lx end=%lx\n", bdata - bootmem_node_data, 299 __free(bdata, sidx, eidx);
262 sidx + PFN_DOWN(bdata->node_boot_start),
263 eidx + PFN_DOWN(bdata->node_boot_start));
264
265 for (i = sidx; i < eidx; i++) {
266 if (unlikely(!test_and_clear_bit(i, bdata->node_bootmem_map)))
267 BUG();
268 }
269} 300}
270 301
271/** 302/**
@@ -367,16 +398,7 @@ static void __init reserve_bootmem_core(bootmem_data_t *bdata,
367 if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start)) 398 if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start))
368 eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start); 399 eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start);
369 400
370 bdebug("nid=%td start=%lx end=%lx flags=%x\n", 401 return __reserve(bdata, sidx, eidx, flags);
371 bdata - bootmem_node_data,
372 sidx + PFN_DOWN(bdata->node_boot_start),
373 eidx + PFN_DOWN(bdata->node_boot_start),
374 flags);
375
376 for (i = sidx; i < eidx; i++)
377 if (test_and_set_bit(i, bdata->node_bootmem_map))
378 bdebug("hm, page %lx reserved twice.\n",
379 PFN_DOWN(bdata->node_boot_start) + i);
380} 402}
381 403
382/** 404/**
@@ -511,10 +533,9 @@ find_block:
511 /* 533 /*
512 * Reserve the area now: 534 * Reserve the area now:
513 */ 535 */
514 for (i = PFN_DOWN(start_off) + merge; 536 if (__reserve(bdata, PFN_DOWN(start_off) + merge,
515 i < PFN_UP(end_off); i++) 537 PFN_UP(end_off), BOOTMEM_EXCLUSIVE))
516 if (test_and_set_bit(i, bdata->node_bootmem_map)) 538 BUG();
517 BUG();
518 539
519 region = phys_to_virt(bdata->node_boot_start + start_off); 540 region = phys_to_virt(bdata->node_boot_start + start_off);
520 memset(region, 0, size); 541 memset(region, 0, size);