int start_offset; /* the overlap with the previous
region to have a page aligned
base_addr */
+ int end_offset; /* additional area required to
+ have the region end page
+ aligned */
int nr_populated; /* # of populated pages */
unsigned long populated[]; /* populated bitmap */
};
static void chunk_map_stats(struct seq_file *m, struct pcpu_chunk *chunk,
int *buffer)
{
- int i, s_index, last_alloc, alloc_sign, as_len;
+ int i, s_index, e_index, last_alloc, alloc_sign, as_len;
int *alloc_sizes, *p;
/* statistics */
int sum_frag = 0, max_frag = 0;
alloc_sizes = buffer;
s_index = (chunk->start_offset) ? 1 : 0;
+ e_index = chunk->map_used - ((chunk->end_offset) ? 1 : 0);
/* find last allocation */
last_alloc = -1;
- for (i = chunk->map_used - 1; i >= s_index; i--) {
+ for (i = e_index - 1; i >= s_index; i--) {
if (chunk->map[i] & 1) {
last_alloc = i;
break;
int init_map_size)
{
struct pcpu_chunk *chunk;
+ int region_size;
+
+ region_size = PFN_ALIGN(start_offset + map_size);
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->end_offset = region_size - chunk->start_offset - map_size;
chunk->map = map;
chunk->map_alloc = init_map_size;
chunk->map[2] = (chunk->start_offset + chunk->free_size) | 1;
chunk->map_used = 2;
+ if (chunk->end_offset) {
+ /* hide the end of the bitmap */
+ chunk->map[++chunk->map_used] = region_size | 1;
+ }
+
return chunk;
}