diff options
-rw-r--r-- | mm/bootmem.c | 150 |
1 files changed, 149 insertions, 1 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c index 286e12c536ae..105ad4cff2e1 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -47,7 +47,10 @@ static unsigned long __init get_mapsize(bootmem_data_t *bdata) | |||
47 | return ALIGN(mapsize, sizeof(long)); | 47 | return ALIGN(mapsize, sizeof(long)); |
48 | } | 48 | } |
49 | 49 | ||
50 | /* return the number of _pages_ that will be allocated for the boot bitmap */ | 50 | /** |
51 | * bootmem_bootmap_pages - calculate bitmap size in pages | ||
52 | * @pages: number of pages the bitmap has to represent | ||
53 | */ | ||
51 | unsigned long __init bootmem_bootmap_pages(unsigned long pages) | 54 | unsigned long __init bootmem_bootmap_pages(unsigned long pages) |
52 | { | 55 | { |
53 | unsigned long mapsize; | 56 | unsigned long mapsize; |
@@ -104,12 +107,28 @@ static unsigned long __init init_bootmem_core(bootmem_data_t *bdata, | |||
104 | return mapsize; | 107 | return mapsize; |
105 | } | 108 | } |
106 | 109 | ||
110 | /** | ||
111 | * init_bootmem_node - register a node as boot memory | ||
112 | * @pgdat: node to register | ||
113 | * @freepfn: pfn where the bitmap for this node is to be placed | ||
114 | * @startpfn: first pfn on the node | ||
115 | * @endpfn: first pfn after the node | ||
116 | * | ||
117 | * Returns the number of bytes needed to hold the bitmap for this node. | ||
118 | */ | ||
107 | unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, | 119 | unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, |
108 | unsigned long startpfn, unsigned long endpfn) | 120 | unsigned long startpfn, unsigned long endpfn) |
109 | { | 121 | { |
110 | return init_bootmem_core(pgdat->bdata, freepfn, startpfn, endpfn); | 122 | return init_bootmem_core(pgdat->bdata, freepfn, startpfn, endpfn); |
111 | } | 123 | } |
112 | 124 | ||
125 | /** | ||
126 | * init_bootmem - register boot memory | ||
127 | * @start: pfn where the bitmap is to be placed | ||
128 | * @pages: number of available physical pages | ||
129 | * | ||
130 | * Returns the number of bytes needed to hold the bitmap. | ||
131 | */ | ||
113 | unsigned long __init init_bootmem(unsigned long start, unsigned long pages) | 132 | unsigned long __init init_bootmem(unsigned long start, unsigned long pages) |
114 | { | 133 | { |
115 | max_low_pfn = pages; | 134 | max_low_pfn = pages; |
@@ -182,12 +201,23 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) | |||
182 | return count; | 201 | return count; |
183 | } | 202 | } |
184 | 203 | ||
204 | /** | ||
205 | * free_all_bootmem_node - release a node's free pages to the buddy allocator | ||
206 | * @pgdat: node to be released | ||
207 | * | ||
208 | * Returns the number of pages actually released. | ||
209 | */ | ||
185 | unsigned long __init free_all_bootmem_node(pg_data_t *pgdat) | 210 | unsigned long __init free_all_bootmem_node(pg_data_t *pgdat) |
186 | { | 211 | { |
187 | register_page_bootmem_info_node(pgdat); | 212 | register_page_bootmem_info_node(pgdat); |
188 | return free_all_bootmem_core(pgdat->bdata); | 213 | return free_all_bootmem_core(pgdat->bdata); |
189 | } | 214 | } |
190 | 215 | ||
216 | /** | ||
217 | * free_all_bootmem - release free pages to the buddy allocator | ||
218 | * | ||
219 | * Returns the number of pages actually released. | ||
220 | */ | ||
191 | unsigned long __init free_all_bootmem(void) | 221 | unsigned long __init free_all_bootmem(void) |
192 | { | 222 | { |
193 | return free_all_bootmem_core(NODE_DATA(0)->bdata); | 223 | return free_all_bootmem_core(NODE_DATA(0)->bdata); |
@@ -231,12 +261,32 @@ static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, | |||
231 | } | 261 | } |
232 | } | 262 | } |
233 | 263 | ||
264 | /** | ||
265 | * free_bootmem_node - mark a page range as usable | ||
266 | * @pgdat: node the range resides on | ||
267 | * @physaddr: starting address of the range | ||
268 | * @size: size of the range in bytes | ||
269 | * | ||
270 | * Partial pages will be considered reserved and left as they are. | ||
271 | * | ||
272 | * Only physical pages that actually reside on @pgdat are marked. | ||
273 | */ | ||
234 | void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | 274 | void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, |
235 | unsigned long size) | 275 | unsigned long size) |
236 | { | 276 | { |
237 | free_bootmem_core(pgdat->bdata, physaddr, size); | 277 | free_bootmem_core(pgdat->bdata, physaddr, size); |
238 | } | 278 | } |
239 | 279 | ||
280 | /** | ||
281 | * free_bootmem - mark a page range as usable | ||
282 | * @addr: starting address of the range | ||
283 | * @size: size of the range in bytes | ||
284 | * | ||
285 | * Partial pages will be considered reserved and left as they are. | ||
286 | * | ||
287 | * All physical pages within the range are marked, no matter what | ||
288 | * node they reside on. | ||
289 | */ | ||
240 | void __init free_bootmem(unsigned long addr, unsigned long size) | 290 | void __init free_bootmem(unsigned long addr, unsigned long size) |
241 | { | 291 | { |
242 | bootmem_data_t *bdata; | 292 | bootmem_data_t *bdata; |
@@ -319,6 +369,17 @@ static void __init reserve_bootmem_core(bootmem_data_t *bdata, | |||
319 | } | 369 | } |
320 | } | 370 | } |
321 | 371 | ||
372 | /** | ||
373 | * reserve_bootmem_node - mark a page range as reserved | ||
374 | * @pgdat: node the range resides on | ||
375 | * @physaddr: starting address of the range | ||
376 | * @size: size of the range in bytes | ||
377 | * @flags: reservation flags (see linux/bootmem.h) | ||
378 | * | ||
379 | * Partial pages will be reserved. | ||
380 | * | ||
381 | * Only physical pages that actually reside on @pgdat are marked. | ||
382 | */ | ||
322 | int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | 383 | int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, |
323 | unsigned long size, int flags) | 384 | unsigned long size, int flags) |
324 | { | 385 | { |
@@ -332,6 +393,17 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | |||
332 | } | 393 | } |
333 | 394 | ||
334 | #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE | 395 | #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE |
396 | /** | ||
397 | * reserve_bootmem - mark a page range as usable | ||
398 | * @addr: starting address of the range | ||
399 | * @size: size of the range in bytes | ||
400 | * @flags: reservation flags (see linux/bootmem.h) | ||
401 | * | ||
402 | * Partial pages will be reserved. | ||
403 | * | ||
404 | * All physical pages within the range are marked, no matter what | ||
405 | * node they reside on. | ||
406 | */ | ||
335 | int __init reserve_bootmem(unsigned long addr, unsigned long size, | 407 | int __init reserve_bootmem(unsigned long addr, unsigned long size, |
336 | int flags) | 408 | int flags) |
337 | { | 409 | { |
@@ -500,6 +572,19 @@ found: | |||
500 | return ret; | 572 | return ret; |
501 | } | 573 | } |
502 | 574 | ||
575 | /** | ||
576 | * __alloc_bootmem_nopanic - allocate boot memory without panicking | ||
577 | * @size: size of the request in bytes | ||
578 | * @align: alignment of the region | ||
579 | * @goal: preferred starting address of the region | ||
580 | * | ||
581 | * The goal is dropped if it can not be satisfied and the allocation will | ||
582 | * fall back to memory below @goal. | ||
583 | * | ||
584 | * Allocation may happen on any node in the system. | ||
585 | * | ||
586 | * Returns NULL on failure. | ||
587 | */ | ||
503 | void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align, | 588 | void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align, |
504 | unsigned long goal) | 589 | unsigned long goal) |
505 | { | 590 | { |
@@ -514,6 +599,19 @@ void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align, | |||
514 | return NULL; | 599 | return NULL; |
515 | } | 600 | } |
516 | 601 | ||
602 | /** | ||
603 | * __alloc_bootmem - allocate boot memory | ||
604 | * @size: size of the request in bytes | ||
605 | * @align: alignment of the region | ||
606 | * @goal: preferred starting address of the region | ||
607 | * | ||
608 | * The goal is dropped if it can not be satisfied and the allocation will | ||
609 | * fall back to memory below @goal. | ||
610 | * | ||
611 | * Allocation may happen on any node in the system. | ||
612 | * | ||
613 | * The function panics if the request can not be satisfied. | ||
614 | */ | ||
517 | void * __init __alloc_bootmem(unsigned long size, unsigned long align, | 615 | void * __init __alloc_bootmem(unsigned long size, unsigned long align, |
518 | unsigned long goal) | 616 | unsigned long goal) |
519 | { | 617 | { |
@@ -529,6 +627,21 @@ void * __init __alloc_bootmem(unsigned long size, unsigned long align, | |||
529 | return NULL; | 627 | return NULL; |
530 | } | 628 | } |
531 | 629 | ||
630 | /** | ||
631 | * __alloc_bootmem_node - allocate boot memory from a specific node | ||
632 | * @pgdat: node to allocate from | ||
633 | * @size: size of the request in bytes | ||
634 | * @align: alignment of the region | ||
635 | * @goal: preferred starting address of the region | ||
636 | * | ||
637 | * The goal is dropped if it can not be satisfied and the allocation will | ||
638 | * fall back to memory below @goal. | ||
639 | * | ||
640 | * Allocation may fall back to any node in the system if the specified node | ||
641 | * can not hold the requested memory. | ||
642 | * | ||
643 | * The function panics if the request can not be satisfied. | ||
644 | */ | ||
532 | void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, | 645 | void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, |
533 | unsigned long align, unsigned long goal) | 646 | unsigned long align, unsigned long goal) |
534 | { | 647 | { |
@@ -542,6 +655,13 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, | |||
542 | } | 655 | } |
543 | 656 | ||
544 | #ifdef CONFIG_SPARSEMEM | 657 | #ifdef CONFIG_SPARSEMEM |
658 | /** | ||
659 | * alloc_bootmem_section - allocate boot memory from a specific section | ||
660 | * @size: size of the request in bytes | ||
661 | * @section_nr: sparse map section to allocate from | ||
662 | * | ||
663 | * Return NULL on failure. | ||
664 | */ | ||
545 | void * __init alloc_bootmem_section(unsigned long size, | 665 | void * __init alloc_bootmem_section(unsigned long size, |
546 | unsigned long section_nr) | 666 | unsigned long section_nr) |
547 | { | 667 | { |
@@ -588,6 +708,19 @@ void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size, | |||
588 | #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL | 708 | #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL |
589 | #endif | 709 | #endif |
590 | 710 | ||
711 | /** | ||
712 | * __alloc_bootmem_low - allocate low boot memory | ||
713 | * @size: size of the request in bytes | ||
714 | * @align: alignment of the region | ||
715 | * @goal: preferred starting address of the region | ||
716 | * | ||
717 | * The goal is dropped if it can not be satisfied and the allocation will | ||
718 | * fall back to memory below @goal. | ||
719 | * | ||
720 | * Allocation may happen on any node in the system. | ||
721 | * | ||
722 | * The function panics if the request can not be satisfied. | ||
723 | */ | ||
591 | void * __init __alloc_bootmem_low(unsigned long size, unsigned long align, | 724 | void * __init __alloc_bootmem_low(unsigned long size, unsigned long align, |
592 | unsigned long goal) | 725 | unsigned long goal) |
593 | { | 726 | { |
@@ -609,6 +742,21 @@ void * __init __alloc_bootmem_low(unsigned long size, unsigned long align, | |||
609 | return NULL; | 742 | return NULL; |
610 | } | 743 | } |
611 | 744 | ||
745 | /** | ||
746 | * __alloc_bootmem_low_node - allocate low boot memory from a specific node | ||
747 | * @pgdat: node to allocate from | ||
748 | * @size: size of the request in bytes | ||
749 | * @align: alignment of the region | ||
750 | * @goal: preferred starting address of the region | ||
751 | * | ||
752 | * The goal is dropped if it can not be satisfied and the allocation will | ||
753 | * fall back to memory below @goal. | ||
754 | * | ||
755 | * Allocation may fall back to any node in the system if the specified node | ||
756 | * can not hold the requested memory. | ||
757 | * | ||
758 | * The function panics if the request can not be satisfied. | ||
759 | */ | ||
612 | void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size, | 760 | void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size, |
613 | unsigned long align, unsigned long goal) | 761 | unsigned long align, unsigned long goal) |
614 | { | 762 | { |