aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/bootmem.h95
-rw-r--r--mm/bootmem.c81
2 files changed, 93 insertions, 83 deletions
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index b2067e4a4486..31e9abb6d977 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -38,29 +38,30 @@ typedef struct bootmem_data {
38 struct list_head list; 38 struct list_head list;
39} bootmem_data_t; 39} bootmem_data_t;
40 40
41extern unsigned long bootmem_bootmap_pages (unsigned long); 41extern unsigned long bootmem_bootmap_pages(unsigned long);
42extern unsigned long init_bootmem (unsigned long addr, unsigned long memend); 42extern unsigned long init_bootmem(unsigned long addr, unsigned long memend);
43extern void free_bootmem (unsigned long addr, unsigned long size); 43extern void free_bootmem(unsigned long addr, unsigned long size);
44extern void * __alloc_bootmem (unsigned long size, 44extern void *__alloc_bootmem(unsigned long size,
45 unsigned long align, 45 unsigned long align,
46 unsigned long goal); 46 unsigned long goal);
47extern void * __alloc_bootmem_nopanic (unsigned long size, 47extern void *__alloc_bootmem_nopanic(unsigned long size,
48 unsigned long align, 48 unsigned long align,
49 unsigned long goal); 49 unsigned long goal);
50extern void * __alloc_bootmem_low(unsigned long size, 50extern void *__alloc_bootmem_low(unsigned long size,
51 unsigned long align,
52 unsigned long goal);
53extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
54 unsigned long size,
55 unsigned long align,
56 unsigned long goal);
57extern void *__alloc_bootmem_core(struct bootmem_data *bdata,
58 unsigned long size,
51 unsigned long align, 59 unsigned long align,
52 unsigned long goal); 60 unsigned long goal,
53extern void * __alloc_bootmem_low_node(pg_data_t *pgdat, 61 unsigned long limit);
54 unsigned long size, 62
55 unsigned long align,
56 unsigned long goal);
57extern void * __alloc_bootmem_core(struct bootmem_data *bdata,
58 unsigned long size,
59 unsigned long align,
60 unsigned long goal,
61 unsigned long limit);
62#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE 63#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
63extern void reserve_bootmem (unsigned long addr, unsigned long size); 64extern void reserve_bootmem(unsigned long addr, unsigned long size);
64#define alloc_bootmem(x) \ 65#define alloc_bootmem(x) \
65 __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) 66 __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
66#define alloc_bootmem_low(x) \ 67#define alloc_bootmem_low(x) \
@@ -70,22 +71,24 @@ extern void reserve_bootmem (unsigned long addr, unsigned long size);
70#define alloc_bootmem_low_pages(x) \ 71#define alloc_bootmem_low_pages(x) \
71 __alloc_bootmem_low(x, PAGE_SIZE, 0) 72 __alloc_bootmem_low(x, PAGE_SIZE, 0)
72#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ 73#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
73extern unsigned long free_all_bootmem (void); 74
74extern void * __alloc_bootmem_node (pg_data_t *pgdat, 75extern unsigned long free_all_bootmem(void);
75 unsigned long size, 76extern unsigned long free_all_bootmem_node(pg_data_t *pgdat);
76 unsigned long align, 77extern void *__alloc_bootmem_node(pg_data_t *pgdat,
77 unsigned long goal); 78 unsigned long size,
78extern unsigned long init_bootmem_node (pg_data_t *pgdat, 79 unsigned long align,
79 unsigned long freepfn, 80 unsigned long goal);
80 unsigned long startpfn, 81extern unsigned long init_bootmem_node(pg_data_t *pgdat,
81 unsigned long endpfn); 82 unsigned long freepfn,
82extern void reserve_bootmem_node (pg_data_t *pgdat, 83 unsigned long startpfn,
83 unsigned long physaddr, 84 unsigned long endpfn);
84 unsigned long size); 85extern void reserve_bootmem_node(pg_data_t *pgdat,
85extern void free_bootmem_node (pg_data_t *pgdat, 86 unsigned long physaddr,
86 unsigned long addr, 87 unsigned long size);
87 unsigned long size); 88extern void free_bootmem_node(pg_data_t *pgdat,
88extern unsigned long free_all_bootmem_node (pg_data_t *pgdat); 89 unsigned long addr,
90 unsigned long size);
91
89#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE 92#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
90#define alloc_bootmem_node(pgdat, x) \ 93#define alloc_bootmem_node(pgdat, x) \
91 __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) 94 __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
@@ -102,19 +105,19 @@ static inline void *alloc_remap(int nid, unsigned long size)
102{ 105{
103 return NULL; 106 return NULL;
104} 107}
105#endif 108#endif /* CONFIG_HAVE_ARCH_ALLOC_REMAP */
106 109
107extern unsigned long __meminitdata nr_kernel_pages; 110extern unsigned long __meminitdata nr_kernel_pages;
108extern unsigned long nr_all_pages; 111extern unsigned long nr_all_pages;
109 112
110extern void * alloc_large_system_hash(const char *tablename, 113extern void *alloc_large_system_hash(const char *tablename,
111 unsigned long bucketsize, 114 unsigned long bucketsize,
112 unsigned long numentries, 115 unsigned long numentries,
113 int scale, 116 int scale,
114 int flags, 117 int flags,
115 unsigned int *_hash_shift, 118 unsigned int *_hash_shift,
116 unsigned int *_hash_mask, 119 unsigned int *_hash_mask,
117 unsigned long limit); 120 unsigned long limit);
118 121
119#define HASH_HIGHMEM 0x00000001 /* Consider highmem? */ 122#define HASH_HIGHMEM 0x00000001 /* Consider highmem? */
120#define HASH_EARLY 0x00000002 /* Allocating during early boot? */ 123#define HASH_EARLY 0x00000002 /* Allocating during early boot? */
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 23c3317c09ed..f0f85fa713ca 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -38,7 +38,7 @@ unsigned long saved_max_pfn;
38#endif 38#endif
39 39
40/* return the number of _pages_ that will be allocated for the boot bitmap */ 40/* return the number of _pages_ that will be allocated for the boot bitmap */
41unsigned long __init bootmem_bootmap_pages (unsigned long pages) 41unsigned long __init bootmem_bootmap_pages(unsigned long pages)
42{ 42{
43 unsigned long mapsize; 43 unsigned long mapsize;
44 44
@@ -48,12 +48,14 @@ unsigned long __init bootmem_bootmap_pages (unsigned long pages)
48 48
49 return mapsize; 49 return mapsize;
50} 50}
51
51/* 52/*
52 * link bdata in order 53 * link bdata in order
53 */ 54 */
54static void __init link_bootmem(bootmem_data_t *bdata) 55static void __init link_bootmem(bootmem_data_t *bdata)
55{ 56{
56 bootmem_data_t *ent; 57 bootmem_data_t *ent;
58
57 if (list_empty(&bdata_list)) { 59 if (list_empty(&bdata_list)) {
58 list_add(&bdata->list, &bdata_list); 60 list_add(&bdata->list, &bdata_list);
59 return; 61 return;
@@ -66,7 +68,6 @@ static void __init link_bootmem(bootmem_data_t *bdata)
66 } 68 }
67 } 69 }
68 list_add_tail(&bdata->list, &bdata_list); 70 list_add_tail(&bdata->list, &bdata_list);
69 return;
70} 71}
71 72
72/* 73/*
@@ -85,7 +86,7 @@ static unsigned long __init get_mapsize(bootmem_data_t *bdata)
85/* 86/*
86 * Called once to set up the allocator itself. 87 * Called once to set up the allocator itself.
87 */ 88 */
88static unsigned long __init init_bootmem_core (pg_data_t *pgdat, 89static unsigned long __init init_bootmem_core(pg_data_t *pgdat,
89 unsigned long mapstart, unsigned long start, unsigned long end) 90 unsigned long mapstart, unsigned long start, unsigned long end)
90{ 91{
91 bootmem_data_t *bdata = pgdat->bdata; 92 bootmem_data_t *bdata = pgdat->bdata;
@@ -185,7 +186,7 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
185 unsigned long i, start = 0, incr, eidx, end_pfn; 186 unsigned long i, start = 0, incr, eidx, end_pfn;
186 void *ret; 187 void *ret;
187 188
188 if(!size) { 189 if (!size) {
189 printk("__alloc_bootmem_core(): zero-sized request\n"); 190 printk("__alloc_bootmem_core(): zero-sized request\n");
190 BUG(); 191 BUG();
191 } 192 }
@@ -234,7 +235,7 @@ restart_scan:
234 for (j = i + 1; j < i + areasize; ++j) { 235 for (j = i + 1; j < i + areasize; ++j) {
235 if (j >= eidx) 236 if (j >= eidx)
236 goto fail_block; 237 goto fail_block;
237 if (test_bit (j, bdata->node_bootmem_map)) 238 if (test_bit(j, bdata->node_bootmem_map))
238 goto fail_block; 239 goto fail_block;
239 } 240 }
240 start = i; 241 start = i;
@@ -262,19 +263,21 @@ found:
262 bdata->last_offset && bdata->last_pos+1 == start) { 263 bdata->last_offset && bdata->last_pos+1 == start) {
263 offset = ALIGN(bdata->last_offset, align); 264 offset = ALIGN(bdata->last_offset, align);
264 BUG_ON(offset > PAGE_SIZE); 265 BUG_ON(offset > PAGE_SIZE);
265 remaining_size = PAGE_SIZE-offset; 266 remaining_size = PAGE_SIZE - offset;
266 if (size < remaining_size) { 267 if (size < remaining_size) {
267 areasize = 0; 268 areasize = 0;
268 /* last_pos unchanged */ 269 /* last_pos unchanged */
269 bdata->last_offset = offset+size; 270 bdata->last_offset = offset + size;
270 ret = phys_to_virt(bdata->last_pos*PAGE_SIZE + offset + 271 ret = phys_to_virt(bdata->last_pos * PAGE_SIZE +
271 bdata->node_boot_start); 272 offset +
273 bdata->node_boot_start);
272 } else { 274 } else {
273 remaining_size = size - remaining_size; 275 remaining_size = size - remaining_size;
274 areasize = (remaining_size+PAGE_SIZE-1)/PAGE_SIZE; 276 areasize = (remaining_size + PAGE_SIZE-1) / PAGE_SIZE;
275 ret = phys_to_virt(bdata->last_pos*PAGE_SIZE + offset + 277 ret = phys_to_virt(bdata->last_pos * PAGE_SIZE +
276 bdata->node_boot_start); 278 offset +
277 bdata->last_pos = start+areasize-1; 279 bdata->node_boot_start);
280 bdata->last_pos = start + areasize - 1;
278 bdata->last_offset = remaining_size; 281 bdata->last_offset = remaining_size;
279 } 282 }
280 bdata->last_offset &= ~PAGE_MASK; 283 bdata->last_offset &= ~PAGE_MASK;
@@ -287,7 +290,7 @@ found:
287 /* 290 /*
288 * Reserve the area now: 291 * Reserve the area now:
289 */ 292 */
290 for (i = start; i < start+areasize; i++) 293 for (i = start; i < start + areasize; i++)
291 if (unlikely(test_and_set_bit(i, bdata->node_bootmem_map))) 294 if (unlikely(test_and_set_bit(i, bdata->node_bootmem_map)))
292 BUG(); 295 BUG();
293 memset(ret, 0, size); 296 memset(ret, 0, size);
@@ -338,7 +341,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
338 } 341 }
339 } 342 }
340 } else { 343 } else {
341 i+=BITS_PER_LONG; 344 i += BITS_PER_LONG;
342 } 345 }
343 pfn += BITS_PER_LONG; 346 pfn += BITS_PER_LONG;
344 } 347 }
@@ -361,51 +364,51 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
361 return total; 364 return total;
362} 365}
363 366
364unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long freepfn, 367unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
365 unsigned long startpfn, unsigned long endpfn) 368 unsigned long startpfn, unsigned long endpfn)
366{ 369{
367 return(init_bootmem_core(pgdat, freepfn, startpfn, endpfn)); 370 return init_bootmem_core(pgdat, freepfn, startpfn, endpfn);
368} 371}
369 372
370void __init reserve_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, 373void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
371 unsigned long size) 374 unsigned long size)
372{ 375{
373 reserve_bootmem_core(pgdat->bdata, physaddr, size); 376 reserve_bootmem_core(pgdat->bdata, physaddr, size);
374} 377}
375 378
376void __init free_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, 379void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
377 unsigned long size) 380 unsigned long size)
378{ 381{
379 free_bootmem_core(pgdat->bdata, physaddr, size); 382 free_bootmem_core(pgdat->bdata, physaddr, size);
380} 383}
381 384
382unsigned long __init free_all_bootmem_node (pg_data_t *pgdat) 385unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
383{ 386{
384 return(free_all_bootmem_core(pgdat)); 387 return free_all_bootmem_core(pgdat);
385} 388}
386 389
387unsigned long __init init_bootmem (unsigned long start, unsigned long pages) 390unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
388{ 391{
389 max_low_pfn = pages; 392 max_low_pfn = pages;
390 min_low_pfn = start; 393 min_low_pfn = start;
391 return(init_bootmem_core(NODE_DATA(0), start, 0, pages)); 394 return init_bootmem_core(NODE_DATA(0), start, 0, pages);
392} 395}
393 396
394#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE 397#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
395void __init reserve_bootmem (unsigned long addr, unsigned long size) 398void __init reserve_bootmem(unsigned long addr, unsigned long size)
396{ 399{
397 reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size); 400 reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size);
398} 401}
399#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ 402#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
400 403
401void __init free_bootmem (unsigned long addr, unsigned long size) 404void __init free_bootmem(unsigned long addr, unsigned long size)
402{ 405{
403 free_bootmem_core(NODE_DATA(0)->bdata, addr, size); 406 free_bootmem_core(NODE_DATA(0)->bdata, addr, size);
404} 407}
405 408
406unsigned long __init free_all_bootmem (void) 409unsigned long __init free_all_bootmem(void)
407{ 410{
408 return(free_all_bootmem_core(NODE_DATA(0))); 411 return free_all_bootmem_core(NODE_DATA(0));
409} 412}
410 413
411void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align, 414void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
@@ -414,9 +417,11 @@ void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
414 bootmem_data_t *bdata; 417 bootmem_data_t *bdata;
415 void *ptr; 418 void *ptr;
416 419
417 list_for_each_entry(bdata, &bdata_list, list) 420 list_for_each_entry(bdata, &bdata_list, list) {
418 if ((ptr = __alloc_bootmem_core(bdata, size, align, goal, 0))) 421 ptr = __alloc_bootmem_core(bdata, size, align, goal, 0);
419 return(ptr); 422 if (ptr)
423 return ptr;
424 }
420 return NULL; 425 return NULL;
421} 426}
422 427
@@ -424,6 +429,7 @@ void * __init __alloc_bootmem(unsigned long size, unsigned long align,
424 unsigned long goal) 429 unsigned long goal)
425{ 430{
426 void *mem = __alloc_bootmem_nopanic(size,align,goal); 431 void *mem = __alloc_bootmem_nopanic(size,align,goal);
432
427 if (mem) 433 if (mem)
428 return mem; 434 return mem;
429 /* 435 /*
@@ -442,7 +448,7 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
442 448
443 ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal, 0); 449 ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal, 0);
444 if (ptr) 450 if (ptr)
445 return (ptr); 451 return ptr;
446 452
447 return __alloc_bootmem(size, align, goal); 453 return __alloc_bootmem(size, align, goal);
448} 454}
@@ -455,10 +461,11 @@ void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
455 bootmem_data_t *bdata; 461 bootmem_data_t *bdata;
456 void *ptr; 462 void *ptr;
457 463
458 list_for_each_entry(bdata, &bdata_list, list) 464 list_for_each_entry(bdata, &bdata_list, list) {
459 if ((ptr = __alloc_bootmem_core(bdata, size, 465 ptr = __alloc_bootmem_core(bdata, size, align, goal, LOW32LIMIT);
460 align, goal, LOW32LIMIT))) 466 if (ptr)
461 return(ptr); 467 return ptr;
468 }
462 469
463 /* 470 /*
464 * Whoops, we cannot satisfy the allocation request. 471 * Whoops, we cannot satisfy the allocation request.