diff options
Diffstat (limited to 'mm/bootmem.c')
-rw-r--r-- | mm/bootmem.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c index 00a96970b237..f6ff4337b424 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -111,11 +111,12 @@ static unsigned long __init init_bootmem_core(pg_data_t *pgdat, | |||
111 | * might be used for boot-time allocations - or it might get added | 111 | * might be used for boot-time allocations - or it might get added |
112 | * to the free page pool later on. | 112 | * to the free page pool later on. |
113 | */ | 113 | */ |
114 | static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long addr, | 114 | static int __init reserve_bootmem_core(bootmem_data_t *bdata, |
115 | unsigned long size) | 115 | unsigned long addr, unsigned long size, int flags) |
116 | { | 116 | { |
117 | unsigned long sidx, eidx; | 117 | unsigned long sidx, eidx; |
118 | unsigned long i; | 118 | unsigned long i; |
119 | int ret; | ||
119 | 120 | ||
120 | /* | 121 | /* |
121 | * round up, partially reserved pages are considered | 122 | * round up, partially reserved pages are considered |
@@ -133,7 +134,20 @@ static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long add | |||
133 | #ifdef CONFIG_DEBUG_BOOTMEM | 134 | #ifdef CONFIG_DEBUG_BOOTMEM |
134 | printk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE); | 135 | printk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE); |
135 | #endif | 136 | #endif |
137 | if (flags & BOOTMEM_EXCLUSIVE) { | ||
138 | ret = -EBUSY; | ||
139 | goto err; | ||
140 | } | ||
136 | } | 141 | } |
142 | |||
143 | return 0; | ||
144 | |||
145 | err: | ||
146 | /* unreserve memory we accidentally reserved */ | ||
147 | for (i--; i >= sidx; i--) | ||
148 | clear_bit(i, bdata->node_bootmem_map); | ||
149 | |||
150 | return ret; | ||
137 | } | 151 | } |
138 | 152 | ||
139 | static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, | 153 | static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, |
@@ -374,9 +388,9 @@ unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, | |||
374 | } | 388 | } |
375 | 389 | ||
376 | void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | 390 | void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, |
377 | unsigned long size) | 391 | unsigned long size, int flags) |
378 | { | 392 | { |
379 | reserve_bootmem_core(pgdat->bdata, physaddr, size); | 393 | reserve_bootmem_core(pgdat->bdata, physaddr, size, flags); |
380 | } | 394 | } |
381 | 395 | ||
382 | void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | 396 | void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, |
@@ -398,9 +412,10 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages) | |||
398 | } | 412 | } |
399 | 413 | ||
400 | #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE | 414 | #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE |
401 | void __init reserve_bootmem(unsigned long addr, unsigned long size) | 415 | int __init reserve_bootmem(unsigned long addr, unsigned long size, |
416 | int flags) | ||
402 | { | 417 | { |
403 | reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size); | 418 | return reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size, flags); |
404 | } | 419 | } |
405 | #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ | 420 | #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ |
406 | 421 | ||