diff options
author | Dennis Zhou (Facebook) | 2017-07-24 19:02:02 -0400 |
---|---|---|
committer | Tejun Heo | 2017-07-26 10:23:52 -0400 |
commit | 10edf5b0b6e238f9102c88df8b92ba7ce8fdcc46 (patch) | |
tree | da4dc57c75fc75f2b513eea56e1d2240fac49e9e /mm/percpu.c | |
parent | b9c39442ceffb202b98a88d492347eae125c5ba2 (diff) |
percpu: unify allocation of schunk and dchunk
Create a common allocator for first chunk initialization,
pcpu_alloc_first_chunk. Comments for this function will be added in a
later patch once the bitmap allocator is added.
Signed-off-by: Dennis Zhou <dennisszhou@gmail.com>
Reviewed-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'mm/percpu.c')
-rw-r--r-- | mm/percpu.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/mm/percpu.c b/mm/percpu.c index 851aa8109788..2e785a77ce14 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -708,6 +708,36 @@ static void pcpu_free_area(struct pcpu_chunk *chunk, int freeme, pcpu_chunk_relocate(chunk, oslot); } +static struct pcpu_chunk * __init pcpu_alloc_first_chunk(void *base_addr, + int start_offset, + int map_size, + int *map, + int init_map_size) +{ + struct pcpu_chunk *chunk; + + chunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0); + INIT_LIST_HEAD(&chunk->list); + INIT_LIST_HEAD(&chunk->map_extend_list); + chunk->base_addr = base_addr; + chunk->start_offset = start_offset; + chunk->map = map; + chunk->map_alloc = init_map_size; + + /* manage populated page bitmap */ + chunk->immutable = true; + bitmap_fill(chunk->populated, pcpu_unit_pages); + chunk->nr_populated = pcpu_unit_pages; + + chunk->contig_hint = chunk->free_size = map_size; + chunk->map[0] = 1; + chunk->map[1] = chunk->start_offset; + chunk->map[2] = (chunk->start_offset + chunk->free_size) | 1; + chunk->map_used = 2; + + return chunk; +} + static struct pcpu_chunk *pcpu_alloc_chunk(void) { struct pcpu_chunk *chunk; @@ -1570,6 +1600,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, unsigned int cpu; int *unit_map; int group, unit, i; + int map_size, start_offset; #define PCPU_SETUP_BUG_ON(cond) do { \ if (unlikely(cond)) { \ @@ -1678,44 +1709,20 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, * covers static area + reserved area (mostly used for module * static percpu allocation). */ - schunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0); - INIT_LIST_HEAD(&schunk->list); - INIT_LIST_HEAD(&schunk->map_extend_list); - schunk->base_addr = base_addr; - schunk->start_offset = ai->static_size; - schunk->map = smap; - schunk->map_alloc = ARRAY_SIZE(smap); - schunk->immutable = true; - bitmap_fill(schunk->populated, pcpu_unit_pages); - schunk->nr_populated = pcpu_unit_pages; - - schunk->free_size = ai->reserved_size ?: ai->dyn_size; - schunk->contig_hint = schunk->free_size; - schunk->map[0] = 1; - schunk->map[1] = schunk->start_offset; - schunk->map[2] = (ai->static_size + schunk->free_size) | 1; - schunk->map_used = 2; + start_offset = ai->static_size; + map_size = ai->reserved_size ?: ai->dyn_size; + schunk = pcpu_alloc_first_chunk(base_addr, start_offset, map_size, + smap, ARRAY_SIZE(smap)); /* init dynamic chunk if necessary */ if (ai->reserved_size) { pcpu_reserved_chunk = schunk; - dchunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0); - INIT_LIST_HEAD(&dchunk->list); - INIT_LIST_HEAD(&dchunk->map_extend_list); - dchunk->base_addr = base_addr; - dchunk->start_offset = ai->static_size + ai->reserved_size; - dchunk->map = dmap; - dchunk->map_alloc = ARRAY_SIZE(dmap); - dchunk->immutable = true; - bitmap_fill(dchunk->populated, pcpu_unit_pages); - dchunk->nr_populated = pcpu_unit_pages; - - dchunk->contig_hint = dchunk->free_size = ai->dyn_size; - dchunk->map[0] = 1; - dchunk->map[1] = dchunk->start_offset; - dchunk->map[2] = (dchunk->start_offset + dchunk->free_size) | 1; - dchunk->map_used = 2; + start_offset = ai->static_size + ai->reserved_size; + map_size = ai->dyn_size; + dchunk = pcpu_alloc_first_chunk(base_addr, start_offset, + map_size, dmap, + ARRAY_SIZE(dmap)); } /* link the first chunk in */ |