.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * mm/percpu-debug.c |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2017 Facebook Inc. |
---|
5 | | - * Copyright (C) 2017 Dennis Zhou <dennisz@fb.com> |
---|
6 | | - * |
---|
7 | | - * This file is released under the GPLv2. |
---|
| 6 | + * Copyright (C) 2017 Dennis Zhou <dennis@kernel.org> |
---|
8 | 7 | * |
---|
9 | 8 | * Prints statistics about the percpu allocator and backing chunks. |
---|
10 | 9 | */ |
---|
.. | .. |
---|
35 | 34 | { |
---|
36 | 35 | struct pcpu_chunk *chunk; |
---|
37 | 36 | int slot, max_nr_alloc; |
---|
| 37 | + enum pcpu_chunk_type type; |
---|
38 | 38 | |
---|
39 | 39 | max_nr_alloc = 0; |
---|
40 | | - for (slot = 0; slot < pcpu_nr_slots; slot++) |
---|
41 | | - list_for_each_entry(chunk, &pcpu_slot[slot], list) |
---|
42 | | - max_nr_alloc = max(max_nr_alloc, chunk->nr_alloc); |
---|
| 40 | + for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++) |
---|
| 41 | + for (slot = 0; slot < pcpu_nr_slots; slot++) |
---|
| 42 | + list_for_each_entry(chunk, &pcpu_chunk_list(type)[slot], |
---|
| 43 | + list) |
---|
| 44 | + max_nr_alloc = max(max_nr_alloc, |
---|
| 45 | + chunk->nr_alloc); |
---|
43 | 46 | |
---|
44 | 47 | return max_nr_alloc; |
---|
45 | 48 | } |
---|
.. | .. |
---|
53 | 56 | static void chunk_map_stats(struct seq_file *m, struct pcpu_chunk *chunk, |
---|
54 | 57 | int *buffer) |
---|
55 | 58 | { |
---|
| 59 | + struct pcpu_block_md *chunk_md = &chunk->chunk_md; |
---|
56 | 60 | int i, last_alloc, as_len, start, end; |
---|
57 | 61 | int *alloc_sizes, *p; |
---|
58 | 62 | /* statistics */ |
---|
.. | .. |
---|
121 | 125 | P("nr_alloc", chunk->nr_alloc); |
---|
122 | 126 | P("max_alloc_size", chunk->max_alloc_size); |
---|
123 | 127 | P("empty_pop_pages", chunk->nr_empty_pop_pages); |
---|
124 | | - P("first_bit", chunk->first_bit); |
---|
| 128 | + P("first_bit", chunk_md->first_free); |
---|
125 | 129 | P("free_bytes", chunk->free_bytes); |
---|
126 | | - P("contig_bytes", chunk->contig_bits * PCPU_MIN_ALLOC_SIZE); |
---|
| 130 | + P("contig_bytes", chunk_md->contig_hint * PCPU_MIN_ALLOC_SIZE); |
---|
127 | 131 | P("sum_frag", sum_frag); |
---|
128 | 132 | P("max_frag", max_frag); |
---|
129 | 133 | P("cur_min_alloc", cur_min_alloc); |
---|
130 | 134 | P("cur_med_alloc", cur_med_alloc); |
---|
131 | 135 | P("cur_max_alloc", cur_max_alloc); |
---|
| 136 | +#ifdef CONFIG_MEMCG_KMEM |
---|
| 137 | + P("memcg_aware", pcpu_is_memcg_chunk(pcpu_chunk_type(chunk))); |
---|
| 138 | +#endif |
---|
132 | 139 | seq_putc(m, '\n'); |
---|
133 | 140 | } |
---|
134 | 141 | |
---|
.. | .. |
---|
137 | 144 | struct pcpu_chunk *chunk; |
---|
138 | 145 | int slot, max_nr_alloc; |
---|
139 | 146 | int *buffer; |
---|
| 147 | + enum pcpu_chunk_type type; |
---|
| 148 | + int nr_empty_pop_pages; |
---|
140 | 149 | |
---|
141 | 150 | alloc_buffer: |
---|
142 | 151 | spin_lock_irq(&pcpu_lock); |
---|
.. | .. |
---|
157 | 166 | goto alloc_buffer; |
---|
158 | 167 | } |
---|
159 | 168 | |
---|
160 | | -#define PL(X) \ |
---|
| 169 | + nr_empty_pop_pages = 0; |
---|
| 170 | + for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++) |
---|
| 171 | + nr_empty_pop_pages += pcpu_nr_empty_pop_pages[type]; |
---|
| 172 | + |
---|
| 173 | +#define PL(X) \ |
---|
161 | 174 | seq_printf(m, " %-20s: %12lld\n", #X, (long long int)pcpu_stats_ai.X) |
---|
162 | 175 | |
---|
163 | 176 | seq_printf(m, |
---|
.. | .. |
---|
188 | 201 | PU(nr_max_chunks); |
---|
189 | 202 | PU(min_alloc_size); |
---|
190 | 203 | PU(max_alloc_size); |
---|
191 | | - P("empty_pop_pages", pcpu_nr_empty_pop_pages); |
---|
| 204 | + P("empty_pop_pages", nr_empty_pop_pages); |
---|
192 | 205 | seq_putc(m, '\n'); |
---|
193 | 206 | |
---|
194 | 207 | #undef PU |
---|
.. | .. |
---|
202 | 215 | chunk_map_stats(m, pcpu_reserved_chunk, buffer); |
---|
203 | 216 | } |
---|
204 | 217 | |
---|
205 | | - for (slot = 0; slot < pcpu_nr_slots; slot++) { |
---|
206 | | - list_for_each_entry(chunk, &pcpu_slot[slot], list) { |
---|
207 | | - if (chunk == pcpu_first_chunk) { |
---|
208 | | - seq_puts(m, "Chunk: <- First Chunk\n"); |
---|
209 | | - chunk_map_stats(m, chunk, buffer); |
---|
210 | | - |
---|
211 | | - |
---|
212 | | - } else { |
---|
213 | | - seq_puts(m, "Chunk:\n"); |
---|
214 | | - chunk_map_stats(m, chunk, buffer); |
---|
| 218 | + for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++) { |
---|
| 219 | + for (slot = 0; slot < pcpu_nr_slots; slot++) { |
---|
| 220 | + list_for_each_entry(chunk, &pcpu_chunk_list(type)[slot], |
---|
| 221 | + list) { |
---|
| 222 | + if (chunk == pcpu_first_chunk) { |
---|
| 223 | + seq_puts(m, "Chunk: <- First Chunk\n"); |
---|
| 224 | + chunk_map_stats(m, chunk, buffer); |
---|
| 225 | + } else { |
---|
| 226 | + seq_puts(m, "Chunk:\n"); |
---|
| 227 | + chunk_map_stats(m, chunk, buffer); |
---|
| 228 | + } |
---|
215 | 229 | } |
---|
216 | | - |
---|
217 | 230 | } |
---|
218 | 231 | } |
---|
219 | 232 | |
---|