]> Pileus Git - ~andy/linux/blob - mm/nobootmem.c
bootmem: Separate out CONFIG_NO_BOOTMEM code into nobootmem.c
[~andy/linux] / mm / nobootmem.c
1 /*
2  *  bootmem - A boot-time physical memory allocator and configurator
3  *
4  *  Copyright (C) 1999 Ingo Molnar
5  *                1999 Kanoj Sarcar, SGI
6  *                2008 Johannes Weiner
7  *
8  * Access to this subsystem has to be serialized externally (which is true
9  * for the boot process anyway).
10  */
11 #include <linux/init.h>
12 #include <linux/pfn.h>
13 #include <linux/slab.h>
14 #include <linux/bootmem.h>
15 #include <linux/module.h>
16 #include <linux/kmemleak.h>
17 #include <linux/range.h>
18 #include <linux/memblock.h>
19
20 #include <asm/bug.h>
21 #include <asm/io.h>
22 #include <asm/processor.h>
23
24 #include "internal.h"
25
26 unsigned long max_low_pfn;
27 unsigned long min_low_pfn;
28 unsigned long max_pfn;
29
30 #ifdef CONFIG_CRASH_DUMP
31 /*
32  * If we have booted due to a crash, max_pfn will be a very low value. We need
33  * to know the amount of memory that the previous kernel used.
34  */
35 unsigned long saved_max_pfn;
36 #endif
37
38 /*
39  * free_bootmem_late - free bootmem pages directly to page allocator
40  * @addr: starting address of the range
41  * @size: size of the range in bytes
42  *
43  * This is only useful when the bootmem allocator has already been torn
44  * down, but we are still initializing the system.  Pages are given directly
45  * to the page allocator, no bootmem metadata is updated because it is gone.
46  */
47 void __init free_bootmem_late(unsigned long addr, unsigned long size)
48 {
49         unsigned long cursor, end;
50
51         kmemleak_free_part(__va(addr), size);
52
53         cursor = PFN_UP(addr);
54         end = PFN_DOWN(addr + size);
55
56         for (; cursor < end; cursor++) {
57                 __free_pages_bootmem(pfn_to_page(cursor), 0);
58                 totalram_pages++;
59         }
60 }
61
62 static void __init __free_pages_memory(unsigned long start, unsigned long end)
63 {
64         int i;
65         unsigned long start_aligned, end_aligned;
66         int order = ilog2(BITS_PER_LONG);
67
68         start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
69         end_aligned = end & ~(BITS_PER_LONG - 1);
70
71         if (end_aligned <= start_aligned) {
72                 for (i = start; i < end; i++)
73                         __free_pages_bootmem(pfn_to_page(i), 0);
74
75                 return;
76         }
77
78         for (i = start; i < start_aligned; i++)
79                 __free_pages_bootmem(pfn_to_page(i), 0);
80
81         for (i = start_aligned; i < end_aligned; i += BITS_PER_LONG)
82                 __free_pages_bootmem(pfn_to_page(i), order);
83
84         for (i = end_aligned; i < end; i++)
85                 __free_pages_bootmem(pfn_to_page(i), 0);
86 }
87
88 unsigned long __init free_all_memory_core_early(int nodeid)
89 {
90         int i;
91         u64 start, end;
92         unsigned long count = 0;
93         struct range *range = NULL;
94         int nr_range;
95
96         nr_range = get_free_all_memory_range(&range, nodeid);
97
98         for (i = 0; i < nr_range; i++) {
99                 start = range[i].start;
100                 end = range[i].end;
101                 count += end - start;
102                 __free_pages_memory(start, end);
103         }
104
105         return count;
106 }
107
108 /**
109  * free_all_bootmem_node - release a node's free pages to the buddy allocator
110  * @pgdat: node to be released
111  *
112  * Returns the number of pages actually released.
113  */
114 unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
115 {
116         register_page_bootmem_info_node(pgdat);
117
118         /* free_all_memory_core_early(MAX_NUMNODES) will be called later */
119         return 0;
120 }
121
122 /**
123  * free_all_bootmem - release free pages to the buddy allocator
124  *
125  * Returns the number of pages actually released.
126  */
127 unsigned long __init free_all_bootmem(void)
128 {
129         /*
130          * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
131          *  because in some case like Node0 doesnt have RAM installed
132          *  low ram will be on Node1
133          * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
134          *  will be used instead of only Node0 related
135          */
136         return free_all_memory_core_early(MAX_NUMNODES);
137 }
138
139 /**
140  * free_bootmem_node - mark a page range as usable
141  * @pgdat: node the range resides on
142  * @physaddr: starting address of the range
143  * @size: size of the range in bytes
144  *
145  * Partial pages will be considered reserved and left as they are.
146  *
147  * The range must reside completely on the specified node.
148  */
149 void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
150                               unsigned long size)
151 {
152         kmemleak_free_part(__va(physaddr), size);
153         memblock_x86_free_range(physaddr, physaddr + size);
154 }
155
156 /**
157  * free_bootmem - mark a page range as usable
158  * @addr: starting address of the range
159  * @size: size of the range in bytes
160  *
161  * Partial pages will be considered reserved and left as they are.
162  *
163  * The range must be contiguous but may span node boundaries.
164  */
165 void __init free_bootmem(unsigned long addr, unsigned long size)
166 {
167         kmemleak_free_part(__va(addr), size);
168         memblock_x86_free_range(addr, addr + size);
169 }
170
171 static void * __init ___alloc_bootmem_nopanic(unsigned long size,
172                                         unsigned long align,
173                                         unsigned long goal,
174                                         unsigned long limit)
175 {
176         void *ptr;
177
178         if (WARN_ON_ONCE(slab_is_available()))
179                 return kzalloc(size, GFP_NOWAIT);
180
181 restart:
182
183         ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, goal, limit);
184
185         if (ptr)
186                 return ptr;
187
188         if (goal != 0) {
189                 goal = 0;
190                 goto restart;
191         }
192
193         return NULL;
194 }
195
196 /**
197  * __alloc_bootmem_nopanic - allocate boot memory without panicking
198  * @size: size of the request in bytes
199  * @align: alignment of the region
200  * @goal: preferred starting address of the region
201  *
202  * The goal is dropped if it can not be satisfied and the allocation will
203  * fall back to memory below @goal.
204  *
205  * Allocation may happen on any node in the system.
206  *
207  * Returns NULL on failure.
208  */
209 void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
210                                         unsigned long goal)
211 {
212         unsigned long limit = -1UL;
213
214         return ___alloc_bootmem_nopanic(size, align, goal, limit);
215 }
216
217 static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
218                                         unsigned long goal, unsigned long limit)
219 {
220         void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
221
222         if (mem)
223                 return mem;
224         /*
225          * Whoops, we cannot satisfy the allocation request.
226          */
227         printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
228         panic("Out of memory");
229         return NULL;
230 }
231
232 /**
233  * __alloc_bootmem - allocate boot memory
234  * @size: size of the request in bytes
235  * @align: alignment of the region
236  * @goal: preferred starting address of the region
237  *
238  * The goal is dropped if it can not be satisfied and the allocation will
239  * fall back to memory below @goal.
240  *
241  * Allocation may happen on any node in the system.
242  *
243  * The function panics if the request can not be satisfied.
244  */
245 void * __init __alloc_bootmem(unsigned long size, unsigned long align,
246                               unsigned long goal)
247 {
248         unsigned long limit = -1UL;
249
250         return ___alloc_bootmem(size, align, goal, limit);
251 }
252
253 /**
254  * __alloc_bootmem_node - allocate boot memory from a specific node
255  * @pgdat: node to allocate from
256  * @size: size of the request in bytes
257  * @align: alignment of the region
258  * @goal: preferred starting address of the region
259  *
260  * The goal is dropped if it can not be satisfied and the allocation will
261  * fall back to memory below @goal.
262  *
263  * Allocation may fall back to any node in the system if the specified node
264  * can not hold the requested memory.
265  *
266  * The function panics if the request can not be satisfied.
267  */
268 void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
269                                    unsigned long align, unsigned long goal)
270 {
271         void *ptr;
272
273         if (WARN_ON_ONCE(slab_is_available()))
274                 return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
275
276         ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
277                                          goal, -1ULL);
278         if (ptr)
279                 return ptr;
280
281         return __alloc_memory_core_early(MAX_NUMNODES, size, align,
282                                          goal, -1ULL);
283 }
284
285 void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
286                                    unsigned long align, unsigned long goal)
287 {
288 #ifdef MAX_DMA32_PFN
289         unsigned long end_pfn;
290
291         if (WARN_ON_ONCE(slab_is_available()))
292                 return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
293
294         /* update goal according ...MAX_DMA32_PFN */
295         end_pfn = pgdat->node_start_pfn + pgdat->node_spanned_pages;
296
297         if (end_pfn > MAX_DMA32_PFN + (128 >> (20 - PAGE_SHIFT)) &&
298             (goal >> PAGE_SHIFT) < MAX_DMA32_PFN) {
299                 void *ptr;
300                 unsigned long new_goal;
301
302                 new_goal = MAX_DMA32_PFN << PAGE_SHIFT;
303                 ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
304                                                  new_goal, -1ULL);
305                 if (ptr)
306                         return ptr;
307         }
308 #endif
309
310         return __alloc_bootmem_node(pgdat, size, align, goal);
311
312 }
313
314 #ifdef CONFIG_SPARSEMEM
315 /**
316  * alloc_bootmem_section - allocate boot memory from a specific section
317  * @size: size of the request in bytes
318  * @section_nr: sparse map section to allocate from
319  *
320  * Return NULL on failure.
321  */
322 void * __init alloc_bootmem_section(unsigned long size,
323                                     unsigned long section_nr)
324 {
325         unsigned long pfn, goal, limit;
326
327         pfn = section_nr_to_pfn(section_nr);
328         goal = pfn << PAGE_SHIFT;
329         limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT;
330
331         return __alloc_memory_core_early(early_pfn_to_nid(pfn), size,
332                                          SMP_CACHE_BYTES, goal, limit);
333 }
334 #endif
335
336 void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
337                                    unsigned long align, unsigned long goal)
338 {
339         void *ptr;
340
341         if (WARN_ON_ONCE(slab_is_available()))
342                 return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
343
344         ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
345                                                  goal, -1ULL);
346         if (ptr)
347                 return ptr;
348
349         return __alloc_bootmem_nopanic(size, align, goal);
350 }
351
352 #ifndef ARCH_LOW_ADDRESS_LIMIT
353 #define ARCH_LOW_ADDRESS_LIMIT  0xffffffffUL
354 #endif
355
356 /**
357  * __alloc_bootmem_low - allocate low boot memory
358  * @size: size of the request in bytes
359  * @align: alignment of the region
360  * @goal: preferred starting address of the region
361  *
362  * The goal is dropped if it can not be satisfied and the allocation will
363  * fall back to memory below @goal.
364  *
365  * Allocation may happen on any node in the system.
366  *
367  * The function panics if the request can not be satisfied.
368  */
369 void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
370                                   unsigned long goal)
371 {
372         return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
373 }
374
375 /**
376  * __alloc_bootmem_low_node - allocate low boot memory from a specific node
377  * @pgdat: node to allocate from
378  * @size: size of the request in bytes
379  * @align: alignment of the region
380  * @goal: preferred starting address of the region
381  *
382  * The goal is dropped if it can not be satisfied and the allocation will
383  * fall back to memory below @goal.
384  *
385  * Allocation may fall back to any node in the system if the specified node
386  * can not hold the requested memory.
387  *
388  * The function panics if the request can not be satisfied.
389  */
390 void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
391                                        unsigned long align, unsigned long goal)
392 {
393         void *ptr;
394
395         if (WARN_ON_ONCE(slab_is_available()))
396                 return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
397
398         ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
399                                 goal, ARCH_LOW_ADDRESS_LIMIT);
400         if (ptr)
401                 return ptr;
402
403         return  __alloc_memory_core_early(MAX_NUMNODES, size, align,
404                                 goal, ARCH_LOW_ADDRESS_LIMIT);
405 }