Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10edf5b0 authored by Dennis Zhou (Facebook)'s avatar Dennis Zhou (Facebook) Committed by Tejun Heo
Browse files

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: default avatarDennis Zhou <dennisszhou@gmail.com>
Reviewed-by: default avatarJosef Bacik <jbacik@fb.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent b9c39442
Loading
Loading
Loading
Loading
+40 −33
Original line number Diff line number Diff line
@@ -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 */