diff options
-rw-r--r-- | include/linux/bootmem.h | 1 | ||||
-rw-r--r-- | mm/bootmem.c | 24 |
2 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index dd97fb8408a8..b10ec49ee2dd 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h | |||
@@ -53,6 +53,7 @@ extern void free_bootmem_node(pg_data_t *pgdat, | |||
53 | unsigned long addr, | 53 | unsigned long addr, |
54 | unsigned long size); | 54 | unsigned long size); |
55 | extern void free_bootmem(unsigned long addr, unsigned long size); | 55 | extern void free_bootmem(unsigned long addr, unsigned long size); |
56 | extern void free_bootmem_late(unsigned long addr, unsigned long size); | ||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE, | 59 | * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE, |
diff --git a/mm/bootmem.c b/mm/bootmem.c index 555d5d2731c6..d1dc23cc7f10 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -143,6 +143,30 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages) | |||
143 | return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages); | 143 | return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages); |
144 | } | 144 | } |
145 | 145 | ||
146 | /* | ||
147 | * free_bootmem_late - free bootmem pages directly to page allocator | ||
148 | * @addr: starting address of the range | ||
149 | * @size: size of the range in bytes | ||
150 | * | ||
151 | * This is only useful when the bootmem allocator has already been torn | ||
152 | * down, but we are still initializing the system. Pages are given directly | ||
153 | * to the page allocator, no bootmem metadata is updated because it is gone. | ||
154 | */ | ||
155 | void __init free_bootmem_late(unsigned long addr, unsigned long size) | ||
156 | { | ||
157 | unsigned long cursor, end; | ||
158 | |||
159 | kmemleak_free_part(__va(addr), size); | ||
160 | |||
161 | cursor = PFN_UP(addr); | ||
162 | end = PFN_DOWN(addr + size); | ||
163 | |||
164 | for (; cursor < end; cursor++) { | ||
165 | __free_pages_bootmem(pfn_to_page(cursor), 0); | ||
166 | totalram_pages++; | ||
167 | } | ||
168 | } | ||
169 | |||
146 | static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) | 170 | static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) |
147 | { | 171 | { |
148 | int aligned; | 172 | int aligned; |