Skip to content

Commit

Permalink
percpu: introduce nr_empty_pop_pages to help empty page accounting
Browse files Browse the repository at this point in the history
pcpu_nr_empty_pop_pages is used to ensure there are a handful of free
pages around to serve atomic allocations. A new field, nr_empty_pop_pages,
is added to the pcpu_chunk struct to keep track of the number of empty
pages. This field is needed as the number of empty populated pages is
globally tracked and deltas are used to update in the bitmap allocator.
Pages that contain a hidden area are not considered to be empty. This
new field is exposed in percpu_stats.

Signed-off-by: Dennis Zhou <[email protected]>
Reviewed-by: Josef Bacik <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
dennisszhou authored and htejun committed Jul 26, 2017
1 parent 8ab16c4 commit 0cecf50
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 3 deletions.
1 change: 1 addition & 0 deletions mm/percpu-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct pcpu_chunk {

int nr_pages; /* # of pages served by this chunk */
int nr_populated; /* # of populated pages */
int nr_empty_pop_pages; /* # of empty populated pages */
unsigned long populated[]; /* populated bitmap */
};

Expand Down
1 change: 1 addition & 0 deletions mm/percpu-stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ static void chunk_map_stats(struct seq_file *m, struct pcpu_chunk *chunk,

P("nr_alloc", chunk->nr_alloc);
P("max_alloc_size", chunk->max_alloc_size);
P("empty_pop_pages", chunk->nr_empty_pop_pages);
P("free_size", chunk->free_size);
P("contig_hint", chunk->contig_hint);
P("sum_frag", sum_frag);
Expand Down
11 changes: 8 additions & 3 deletions mm/percpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,11 +757,14 @@ static struct pcpu_chunk * __init pcpu_alloc_first_chunk(unsigned long tmp_addr,
chunk->immutable = true;
bitmap_fill(chunk->populated, chunk->nr_pages);
chunk->nr_populated = chunk->nr_pages;
chunk->nr_empty_pop_pages = chunk->nr_pages;

chunk->contig_hint = chunk->free_size = map_size;

if (chunk->start_offset) {
/* hide the beginning of the bitmap */
chunk->nr_empty_pop_pages--;

chunk->map[0] = 1;
chunk->map[1] = chunk->start_offset;
chunk->map_used = 1;
Expand All @@ -773,6 +776,8 @@ static struct pcpu_chunk * __init pcpu_alloc_first_chunk(unsigned long tmp_addr,

if (chunk->end_offset) {
/* hide the end of the bitmap */
chunk->nr_empty_pop_pages--;

chunk->map[++chunk->map_used] = region_size | 1;
}

Expand Down Expand Up @@ -836,6 +841,7 @@ static void pcpu_chunk_populated(struct pcpu_chunk *chunk,

bitmap_set(chunk->populated, page_start, nr);
chunk->nr_populated += nr;
chunk->nr_empty_pop_pages += nr;
pcpu_nr_empty_pop_pages += nr;
}

Expand All @@ -858,6 +864,7 @@ static void pcpu_chunk_depopulated(struct pcpu_chunk *chunk,

bitmap_clear(chunk->populated, page_start, nr);
chunk->nr_populated -= nr;
chunk->nr_empty_pop_pages -= nr;
pcpu_nr_empty_pop_pages -= nr;
}

Expand Down Expand Up @@ -1782,9 +1789,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,

/* link the first chunk in */
pcpu_first_chunk = chunk;
i = (pcpu_first_chunk->start_offset) ? 1 : 0;
pcpu_nr_empty_pop_pages +=
pcpu_count_occupied_pages(pcpu_first_chunk, i);
pcpu_nr_empty_pop_pages = pcpu_first_chunk->nr_empty_pop_pages;
pcpu_chunk_relocate(pcpu_first_chunk, -1);

pcpu_stats_chunk_alloc();
Expand Down

0 comments on commit 0cecf50

Please sign in to comment.