Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bootmem: free/reserve helpers

Factor out the common operation of marking a range on the bitmap.

[akpm@linux-foundation.org: fix various warnings]
Signed-off-by: Johannes 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Johannes Weiner and committed by
Linus Torvalds
d747fa4b 5f2809e6

+43 -22
+43 -22
mm/bootmem.c
··· 225 225 return free_all_bootmem_core(NODE_DATA(0)->bdata); 226 226 } 227 227 228 + static 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 + 242 + static 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 + 228 266 static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, 229 267 unsigned long size) 230 268 { ··· 296 258 if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start)) 297 259 eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start); 298 260 299 - bdebug("nid=%td start=%lx end=%lx\n", bdata - bootmem_node_data, 300 - sidx + PFN_DOWN(bdata->node_boot_start), 301 - eidx + PFN_DOWN(bdata->node_boot_start)); 302 - 303 - for (i = sidx; i < eidx; i++) { 304 - if (unlikely(!test_and_clear_bit(i, bdata->node_bootmem_map))) 305 - BUG(); 306 - } 261 + __free(bdata, sidx, eidx); 307 262 } 308 263 309 264 /** ··· 398 367 if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start)) 399 368 eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start); 400 369 401 - bdebug("nid=%td start=%lx end=%lx flags=%x\n", 402 - bdata - bootmem_node_data, 403 - sidx + PFN_DOWN(bdata->node_boot_start), 404 - eidx + PFN_DOWN(bdata->node_boot_start), 405 - flags); 406 - 407 - for (i = sidx; i < eidx; i++) 408 - if (test_and_set_bit(i, bdata->node_bootmem_map)) 409 - bdebug("hm, page %lx reserved twice.\n", 410 - PFN_DOWN(bdata->node_boot_start) + i); 370 + return __reserve(bdata, sidx, eidx, flags); 411 371 } 412 372 413 373 /** ··· 533 511 /* 534 512 * Reserve the area now: 535 513 */ 536 - for (i = PFN_DOWN(start_off) + merge; 537 - i < PFN_UP(end_off); i++) 538 - if (test_and_set_bit(i, bdata->node_bootmem_map)) 539 - BUG(); 514 + if (__reserve(bdata, PFN_DOWN(start_off) + merge, 515 + PFN_UP(end_off), BOOTMEM_EXCLUSIVE)) 516 + BUG(); 540 517 541 518 region = phys_to_virt(bdata->node_boot_start + start_off); 542 519 memset(region, 0, size);