diff options
Diffstat (limited to 'mm/sparse.c')
-rw-r--r-- | mm/sparse.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/mm/sparse.c b/mm/sparse.c index 2ea8b3dbd0df..9a0a5f598469 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -400,7 +400,14 @@ static void __init sparse_early_usemaps_alloc_node(void *data, | |||
400 | } | 400 | } |
401 | } | 401 | } |
402 | 402 | ||
403 | #ifndef CONFIG_SPARSEMEM_VMEMMAP | 403 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
404 | unsigned long __init section_map_size(void) | ||
405 | |||
406 | { | ||
407 | return ALIGN(sizeof(struct page) * PAGES_PER_SECTION, PMD_SIZE); | ||
408 | } | ||
409 | |||
410 | #else | ||
404 | struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid, | 411 | struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid, |
405 | struct vmem_altmap *altmap) | 412 | struct vmem_altmap *altmap) |
406 | { | 413 | { |
@@ -457,6 +464,42 @@ void __init sparse_mem_maps_populate_node(struct page **map_map, | |||
457 | } | 464 | } |
458 | #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ | 465 | #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ |
459 | 466 | ||
467 | static void *sparsemap_buf __meminitdata; | ||
468 | static void *sparsemap_buf_end __meminitdata; | ||
469 | |||
470 | void __init sparse_buffer_init(unsigned long size, int nid) | ||
471 | { | ||
472 | WARN_ON(sparsemap_buf); /* forgot to call sparse_buffer_fini()? */ | ||
473 | sparsemap_buf = | ||
474 | memblock_virt_alloc_try_nid_raw(size, PAGE_SIZE, | ||
475 | __pa(MAX_DMA_ADDRESS), | ||
476 | BOOTMEM_ALLOC_ACCESSIBLE, nid); | ||
477 | sparsemap_buf_end = sparsemap_buf + size; | ||
478 | } | ||
479 | |||
480 | void __init sparse_buffer_fini(void) | ||
481 | { | ||
482 | unsigned long size = sparsemap_buf_end - sparsemap_buf; | ||
483 | |||
484 | if (sparsemap_buf && size > 0) | ||
485 | memblock_free_early(__pa(sparsemap_buf), size); | ||
486 | sparsemap_buf = NULL; | ||
487 | } | ||
488 | |||
489 | void * __meminit sparse_buffer_alloc(unsigned long size) | ||
490 | { | ||
491 | void *ptr = NULL; | ||
492 | |||
493 | if (sparsemap_buf) { | ||
494 | ptr = PTR_ALIGN(sparsemap_buf, size); | ||
495 | if (ptr + size > sparsemap_buf_end) | ||
496 | ptr = NULL; | ||
497 | else | ||
498 | sparsemap_buf = ptr + size; | ||
499 | } | ||
500 | return ptr; | ||
501 | } | ||
502 | |||
460 | #ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER | 503 | #ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER |
461 | static void __init sparse_early_mem_maps_alloc_node(void *data, | 504 | static void __init sparse_early_mem_maps_alloc_node(void *data, |
462 | unsigned long pnum_begin, | 505 | unsigned long pnum_begin, |