Branch data Line data Source code
1 : : /*
2 : : * Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
3 : : */
4 : : #ifndef _LINUX_BOOTMEM_H
5 : : #define _LINUX_BOOTMEM_H
6 : :
7 : : #include <linux/mmzone.h>
8 : : #include <linux/mm_types.h>
9 : : #include <asm/dma.h>
10 : :
11 : : /*
12 : : * simple boot-time physical memory area allocator.
13 : : */
14 : :
15 : : extern unsigned long max_low_pfn;
16 : : extern unsigned long min_low_pfn;
17 : :
18 : : /*
19 : : * highest page
20 : : */
21 : : extern unsigned long max_pfn;
22 : :
23 : : #ifndef CONFIG_NO_BOOTMEM
24 : : /*
25 : : * node_bootmem_map is a map pointer - the bits represent all physical
26 : : * memory pages (including holes) on the node.
27 : : */
28 : : typedef struct bootmem_data {
29 : : unsigned long node_min_pfn;
30 : : unsigned long node_low_pfn;
31 : : void *node_bootmem_map;
32 : : unsigned long last_end_off;
33 : : unsigned long hint_idx;
34 : : struct list_head list;
35 : : } bootmem_data_t;
36 : :
37 : : extern bootmem_data_t bootmem_node_data[];
38 : : #endif
39 : :
40 : : extern unsigned long bootmem_bootmap_pages(unsigned long);
41 : :
42 : : extern unsigned long init_bootmem_node(pg_data_t *pgdat,
43 : : unsigned long freepfn,
44 : : unsigned long startpfn,
45 : : unsigned long endpfn);
46 : : extern unsigned long init_bootmem(unsigned long addr, unsigned long memend);
47 : :
48 : : extern unsigned long free_all_bootmem(void);
49 : : extern void reset_all_zones_managed_pages(void);
50 : :
51 : : extern void free_bootmem_node(pg_data_t *pgdat,
52 : : unsigned long addr,
53 : : unsigned long size);
54 : : extern void free_bootmem(unsigned long physaddr, unsigned long size);
55 : : extern void free_bootmem_late(unsigned long physaddr, unsigned long size);
56 : :
57 : : /*
58 : : * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
59 : : * the architecture-specific code should honor this).
60 : : *
61 : : * If flags is 0, then the return value is always 0 (success). If
62 : : * flags contains BOOTMEM_EXCLUSIVE, then -EBUSY is returned if the
63 : : * memory already was reserved.
64 : : */
65 : : #define BOOTMEM_DEFAULT 0
66 : : #define BOOTMEM_EXCLUSIVE (1<<0)
67 : :
68 : : extern int reserve_bootmem(unsigned long addr,
69 : : unsigned long size,
70 : : int flags);
71 : : extern int reserve_bootmem_node(pg_data_t *pgdat,
72 : : unsigned long physaddr,
73 : : unsigned long size,
74 : : int flags);
75 : :
76 : : extern void *__alloc_bootmem(unsigned long size,
77 : : unsigned long align,
78 : : unsigned long goal);
79 : : extern void *__alloc_bootmem_nopanic(unsigned long size,
80 : : unsigned long align,
81 : : unsigned long goal);
82 : : extern void *__alloc_bootmem_node(pg_data_t *pgdat,
83 : : unsigned long size,
84 : : unsigned long align,
85 : : unsigned long goal);
86 : : void *__alloc_bootmem_node_high(pg_data_t *pgdat,
87 : : unsigned long size,
88 : : unsigned long align,
89 : : unsigned long goal);
90 : : extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat,
91 : : unsigned long size,
92 : : unsigned long align,
93 : : unsigned long goal);
94 : : void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
95 : : unsigned long size,
96 : : unsigned long align,
97 : : unsigned long goal,
98 : : unsigned long limit);
99 : : extern void *__alloc_bootmem_low(unsigned long size,
100 : : unsigned long align,
101 : : unsigned long goal);
102 : : void *__alloc_bootmem_low_nopanic(unsigned long size,
103 : : unsigned long align,
104 : : unsigned long goal);
105 : : extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
106 : : unsigned long size,
107 : : unsigned long align,
108 : : unsigned long goal);
109 : :
110 : : #ifdef CONFIG_NO_BOOTMEM
111 : : /* We are using top down, so it is safe to use 0 here */
112 : : #define BOOTMEM_LOW_LIMIT 0
113 : : #else
114 : : #define BOOTMEM_LOW_LIMIT __pa(MAX_DMA_ADDRESS)
115 : : #endif
116 : :
117 : : #define alloc_bootmem(x) \
118 : : __alloc_bootmem(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
119 : : #define alloc_bootmem_align(x, align) \
120 : : __alloc_bootmem(x, align, BOOTMEM_LOW_LIMIT)
121 : : #define alloc_bootmem_nopanic(x) \
122 : : __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
123 : : #define alloc_bootmem_pages(x) \
124 : : __alloc_bootmem(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
125 : : #define alloc_bootmem_pages_nopanic(x) \
126 : : __alloc_bootmem_nopanic(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
127 : : #define alloc_bootmem_node(pgdat, x) \
128 : : __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
129 : : #define alloc_bootmem_node_nopanic(pgdat, x) \
130 : : __alloc_bootmem_node_nopanic(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
131 : : #define alloc_bootmem_pages_node(pgdat, x) \
132 : : __alloc_bootmem_node(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
133 : : #define alloc_bootmem_pages_node_nopanic(pgdat, x) \
134 : : __alloc_bootmem_node_nopanic(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
135 : :
136 : : #define alloc_bootmem_low(x) \
137 : : __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0)
138 : : #define alloc_bootmem_low_pages_nopanic(x) \
139 : : __alloc_bootmem_low_nopanic(x, PAGE_SIZE, 0)
140 : : #define alloc_bootmem_low_pages(x) \
141 : : __alloc_bootmem_low(x, PAGE_SIZE, 0)
142 : : #define alloc_bootmem_low_pages_node(pgdat, x) \
143 : : __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0)
144 : :
145 : :
146 : : #if defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM)
147 : :
148 : : /* FIXME: use MEMBLOCK_ALLOC_* variants here */
149 : : #define BOOTMEM_ALLOC_ACCESSIBLE 0
150 : : #define BOOTMEM_ALLOC_ANYWHERE (~(phys_addr_t)0)
151 : :
152 : : /* FIXME: Move to memblock.h at a point where we remove nobootmem.c */
153 : : void *memblock_virt_alloc_try_nid_nopanic(phys_addr_t size,
154 : : phys_addr_t align, phys_addr_t min_addr,
155 : : phys_addr_t max_addr, int nid);
156 : : void *memblock_virt_alloc_try_nid(phys_addr_t size, phys_addr_t align,
157 : : phys_addr_t min_addr, phys_addr_t max_addr, int nid);
158 : : void __memblock_free_early(phys_addr_t base, phys_addr_t size);
159 : : void __memblock_free_late(phys_addr_t base, phys_addr_t size);
160 : :
161 : : static inline void * __init memblock_virt_alloc(
162 : : phys_addr_t size, phys_addr_t align)
163 : : {
164 : 0 : return memblock_virt_alloc_try_nid(size, align, BOOTMEM_LOW_LIMIT,
165 : : BOOTMEM_ALLOC_ACCESSIBLE,
166 : : NUMA_NO_NODE);
167 : : }
168 : :
169 : : static inline void * __init memblock_virt_alloc_nopanic(
170 : : phys_addr_t size, phys_addr_t align)
171 : : {
172 : 0 : return memblock_virt_alloc_try_nid_nopanic(size, align,
173 : : BOOTMEM_LOW_LIMIT,
174 : : BOOTMEM_ALLOC_ACCESSIBLE,
175 : : NUMA_NO_NODE);
176 : : }
177 : :
178 : : #ifndef ARCH_LOW_ADDRESS_LIMIT
179 : : #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL
180 : : #endif
181 : :
182 : : static inline void * __init memblock_virt_alloc_low(
183 : : phys_addr_t size, phys_addr_t align)
184 : : {
185 : : return memblock_virt_alloc_try_nid(size, align,
186 : : BOOTMEM_LOW_LIMIT,
187 : : ARCH_LOW_ADDRESS_LIMIT,
188 : : NUMA_NO_NODE);
189 : : }
190 : : static inline void * __init memblock_virt_alloc_low_nopanic(
191 : : phys_addr_t size, phys_addr_t align)
192 : : {
193 : 0 : return memblock_virt_alloc_try_nid_nopanic(size, align,
194 : : BOOTMEM_LOW_LIMIT,
195 : : ARCH_LOW_ADDRESS_LIMIT,
196 : : NUMA_NO_NODE);
197 : : }
198 : :
199 : : static inline void * __init memblock_virt_alloc_from_nopanic(
200 : : phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
201 : : {
202 : 0 : return memblock_virt_alloc_try_nid_nopanic(size, align, min_addr,
203 : : BOOTMEM_ALLOC_ACCESSIBLE,
204 : : NUMA_NO_NODE);
205 : : }
206 : :
207 : : static inline void * __init memblock_virt_alloc_node(
208 : : phys_addr_t size, int nid)
209 : : {
210 : : return memblock_virt_alloc_try_nid(size, 0, BOOTMEM_LOW_LIMIT,
211 : : BOOTMEM_ALLOC_ACCESSIBLE, nid);
212 : : }
213 : :
214 : : static inline void * __init memblock_virt_alloc_node_nopanic(
215 : : phys_addr_t size, int nid)
216 : : {
217 : 0 : return memblock_virt_alloc_try_nid_nopanic(size, 0, BOOTMEM_LOW_LIMIT,
218 : : BOOTMEM_ALLOC_ACCESSIBLE,
219 : : nid);
220 : : }
221 : :
222 : : static inline void __init memblock_free_early(
223 : : phys_addr_t base, phys_addr_t size)
224 : : {
225 : 0 : __memblock_free_early(base, size);
226 : : }
227 : :
228 : : static inline void __init memblock_free_early_nid(
229 : : phys_addr_t base, phys_addr_t size, int nid)
230 : : {
231 : : __memblock_free_early(base, size);
232 : : }
233 : :
234 : : static inline void __init memblock_free_late(
235 : : phys_addr_t base, phys_addr_t size)
236 : : {
237 : 0 : __memblock_free_late(base, size);
238 : : }
239 : :
240 : : #else
241 : :
242 : : #define BOOTMEM_ALLOC_ACCESSIBLE 0
243 : :
244 : :
245 : : /* Fall back to all the existing bootmem APIs */
246 : : static inline void * __init memblock_virt_alloc(
247 : : phys_addr_t size, phys_addr_t align)
248 : : {
249 : : if (!align)
250 : : align = SMP_CACHE_BYTES;
251 : : return __alloc_bootmem(size, align, BOOTMEM_LOW_LIMIT);
252 : : }
253 : :
254 : : static inline void * __init memblock_virt_alloc_nopanic(
255 : : phys_addr_t size, phys_addr_t align)
256 : : {
257 : : if (!align)
258 : : align = SMP_CACHE_BYTES;
259 : : return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT);
260 : : }
261 : :
262 : : static inline void * __init memblock_virt_alloc_low(
263 : : phys_addr_t size, phys_addr_t align)
264 : : {
265 : : if (!align)
266 : : align = SMP_CACHE_BYTES;
267 : : return __alloc_bootmem_low(size, align, 0);
268 : : }
269 : :
270 : : static inline void * __init memblock_virt_alloc_low_nopanic(
271 : : phys_addr_t size, phys_addr_t align)
272 : : {
273 : : if (!align)
274 : : align = SMP_CACHE_BYTES;
275 : : return __alloc_bootmem_low_nopanic(size, align, 0);
276 : : }
277 : :
278 : : static inline void * __init memblock_virt_alloc_from_nopanic(
279 : : phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
280 : : {
281 : : return __alloc_bootmem_nopanic(size, align, min_addr);
282 : : }
283 : :
284 : : static inline void * __init memblock_virt_alloc_node(
285 : : phys_addr_t size, int nid)
286 : : {
287 : : return __alloc_bootmem_node(NODE_DATA(nid), size, SMP_CACHE_BYTES,
288 : : BOOTMEM_LOW_LIMIT);
289 : : }
290 : :
291 : : static inline void * __init memblock_virt_alloc_node_nopanic(
292 : : phys_addr_t size, int nid)
293 : : {
294 : : return __alloc_bootmem_node_nopanic(NODE_DATA(nid), size,
295 : : SMP_CACHE_BYTES,
296 : : BOOTMEM_LOW_LIMIT);
297 : : }
298 : :
299 : : static inline void * __init memblock_virt_alloc_try_nid(phys_addr_t size,
300 : : phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid)
301 : : {
302 : : return __alloc_bootmem_node_high(NODE_DATA(nid), size, align,
303 : : min_addr);
304 : : }
305 : :
306 : : static inline void * __init memblock_virt_alloc_try_nid_nopanic(
307 : : phys_addr_t size, phys_addr_t align,
308 : : phys_addr_t min_addr, phys_addr_t max_addr, int nid)
309 : : {
310 : : return ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size, align,
311 : : min_addr, max_addr);
312 : : }
313 : :
314 : : static inline void __init memblock_free_early(
315 : : phys_addr_t base, phys_addr_t size)
316 : : {
317 : : free_bootmem(base, size);
318 : : }
319 : :
320 : : static inline void __init memblock_free_early_nid(
321 : : phys_addr_t base, phys_addr_t size, int nid)
322 : : {
323 : : free_bootmem_node(NODE_DATA(nid), base, size);
324 : : }
325 : :
326 : : static inline void __init memblock_free_late(
327 : : phys_addr_t base, phys_addr_t size)
328 : : {
329 : : free_bootmem_late(base, size);
330 : : }
331 : : #endif /* defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM) */
332 : :
333 : : #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
334 : : extern void *alloc_remap(int nid, unsigned long size);
335 : : #else
336 : : static inline void *alloc_remap(int nid, unsigned long size)
337 : : {
338 : : return NULL;
339 : : }
340 : : #endif /* CONFIG_HAVE_ARCH_ALLOC_REMAP */
341 : :
342 : : extern void *alloc_large_system_hash(const char *tablename,
343 : : unsigned long bucketsize,
344 : : unsigned long numentries,
345 : : int scale,
346 : : int flags,
347 : : unsigned int *_hash_shift,
348 : : unsigned int *_hash_mask,
349 : : unsigned long low_limit,
350 : : unsigned long high_limit);
351 : :
352 : : #define HASH_EARLY 0x00000001 /* Allocating during early boot? */
353 : : #define HASH_SMALL 0x00000002 /* sub-page allocation allowed, min
354 : : * shift passed via *_hash_shift */
355 : :
356 : : /* Only NUMA needs hash distribution. 64bit NUMA architectures have
357 : : * sufficient vmalloc space.
358 : : */
359 : : #if defined(CONFIG_NUMA) && defined(CONFIG_64BIT)
360 : : #define HASHDIST_DEFAULT 1
361 : : #else
362 : : #define HASHDIST_DEFAULT 0
363 : : #endif
364 : : extern int hashdist; /* Distribute hashes across NUMA nodes? */
365 : :
366 : :
367 : : #endif /* _LINUX_BOOTMEM_H */
|