Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf cpumap: Give CPUs their own type

A common problem is confusing CPU map indices with the CPU, by wrapping
the CPU with a struct then this is avoided. This approach is similar to
atomic_t.

Committer notes:

To make it build with BUILD_BPF_SKEL=1 these files needed the
conversions to 'struct perf_cpu' usage:

tools/perf/util/bpf_counter.c
tools/perf/util/bpf_counter_cgroup.c
tools/perf/util/bpf_ftrace.c

Also perf_env__get_cpu() was removed back in "perf cpumap: Switch
cpu_map__build_map to cpu function".

Additionally these needed to be fixed for the ARM builds to complete:

tools/perf/arch/arm/util/cs-etm.c
tools/perf/arch/arm64/util/pmu.c

Suggested-by: John Garry <john.garry@huawei.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Clarke <pc@us.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Vineet Singh <vineet.singh@intel.com>
Cc: coresight@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: zhengjun.xing@intel.com
Link: https://lore.kernel.org/r/20220105061351.120843-49-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
6d18804b ce37ab3e

+431 -356
+59 -44
tools/lib/perf/cpumap.c
··· 10 10 #include <ctype.h> 11 11 #include <limits.h> 12 12 13 - struct perf_cpu_map *perf_cpu_map__dummy_new(void) 13 + static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus) 14 14 { 15 - struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int)); 15 + struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus); 16 16 17 17 if (cpus != NULL) { 18 - cpus->nr = 1; 19 - cpus->map[0] = -1; 18 + cpus->nr = nr_cpus; 20 19 refcount_set(&cpus->refcnt, 1); 20 + 21 21 } 22 + return cpus; 23 + } 24 + 25 + struct perf_cpu_map *perf_cpu_map__dummy_new(void) 26 + { 27 + struct perf_cpu_map *cpus = perf_cpu_map__alloc(1); 28 + 29 + if (cpus) 30 + cpus->map[0].cpu = -1; 22 31 23 32 return cpus; 24 33 } ··· 63 54 if (nr_cpus < 0) 64 55 return NULL; 65 56 66 - cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int)); 57 + cpus = perf_cpu_map__alloc(nr_cpus); 67 58 if (cpus != NULL) { 68 59 int i; 69 60 70 61 for (i = 0; i < nr_cpus; ++i) 71 - cpus->map[i] = i; 72 - 73 - cpus->nr = nr_cpus; 74 - refcount_set(&cpus->refcnt, 1); 62 + cpus->map[i].cpu = i; 75 63 } 76 64 77 65 return cpus; ··· 79 73 return cpu_map__default_new(); 80 74 } 81 75 82 - static int cmp_int(const void *a, const void *b) 76 + 77 + static int cmp_cpu(const void *a, const void *b) 83 78 { 84 - return *(const int *)a - *(const int*)b; 79 + const struct perf_cpu *cpu_a = a, *cpu_b = b; 80 + 81 + return cpu_a->cpu - cpu_b->cpu; 85 82 } 86 83 87 - static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) 84 + static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, const struct perf_cpu *tmp_cpus) 88 85 { 89 - size_t payload_size = nr_cpus * sizeof(int); 90 - struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); 86 + size_t payload_size = nr_cpus * sizeof(struct perf_cpu); 87 + struct perf_cpu_map *cpus = perf_cpu_map__alloc(nr_cpus); 91 88 int i, j; 92 89 93 90 if (cpus != NULL) { 94 91 memcpy(cpus->map, tmp_cpus, payload_size); 95 - qsort(cpus->map, nr_cpus, sizeof(int), cmp_int); 92 + qsort(cpus->map, nr_cpus, sizeof(struct perf_cpu), cmp_cpu); 96 93 /* Remove dups */ 97 94 j = 0; 98 95 for (i = 0; i < nr_cpus; i++) { 99 - if (i == 0 || cpus->map[i] != cpus->map[i - 1]) 100 - cpus->map[j++] = cpus->map[i]; 96 + if (i == 0 || cpus->map[i].cpu != cpus->map[i - 1].cpu) 97 + cpus->map[j++].cpu = cpus->map[i].cpu; 101 98 } 102 99 cpus->nr = j; 103 100 assert(j <= nr_cpus); 104 - refcount_set(&cpus->refcnt, 1); 105 101 } 106 - 107 102 return cpus; 108 103 } 109 104 ··· 112 105 { 113 106 struct perf_cpu_map *cpus = NULL; 114 107 int nr_cpus = 0; 115 - int *tmp_cpus = NULL, *tmp; 108 + struct perf_cpu *tmp_cpus = NULL, *tmp; 116 109 int max_entries = 0; 117 110 int n, cpu, prev; 118 111 char sep; ··· 131 124 132 125 if (new_max >= max_entries) { 133 126 max_entries = new_max + MAX_NR_CPUS / 2; 134 - tmp = realloc(tmp_cpus, max_entries * sizeof(int)); 127 + tmp = realloc(tmp_cpus, max_entries * sizeof(struct perf_cpu)); 135 128 if (tmp == NULL) 136 129 goto out_free_tmp; 137 130 tmp_cpus = tmp; 138 131 } 139 132 140 133 while (++prev < cpu) 141 - tmp_cpus[nr_cpus++] = prev; 134 + tmp_cpus[nr_cpus++].cpu = prev; 142 135 } 143 136 if (nr_cpus == max_entries) { 144 137 max_entries += MAX_NR_CPUS; 145 - tmp = realloc(tmp_cpus, max_entries * sizeof(int)); 138 + tmp = realloc(tmp_cpus, max_entries * sizeof(struct perf_cpu)); 146 139 if (tmp == NULL) 147 140 goto out_free_tmp; 148 141 tmp_cpus = tmp; 149 142 } 150 143 151 - tmp_cpus[nr_cpus++] = cpu; 144 + tmp_cpus[nr_cpus++].cpu = cpu; 152 145 if (n == 2 && sep == '-') 153 146 prev = cpu; 154 147 else ··· 186 179 unsigned long start_cpu, end_cpu = 0; 187 180 char *p = NULL; 188 181 int i, nr_cpus = 0; 189 - int *tmp_cpus = NULL, *tmp; 182 + struct perf_cpu *tmp_cpus = NULL, *tmp; 190 183 int max_entries = 0; 191 184 192 185 if (!cpu_list) ··· 227 220 for (; start_cpu <= end_cpu; start_cpu++) { 228 221 /* check for duplicates */ 229 222 for (i = 0; i < nr_cpus; i++) 230 - if (tmp_cpus[i] == (int)start_cpu) 223 + if (tmp_cpus[i].cpu == (int)start_cpu) 231 224 goto invalid; 232 225 233 226 if (nr_cpus == max_entries) { 234 227 max_entries += MAX_NR_CPUS; 235 - tmp = realloc(tmp_cpus, max_entries * sizeof(int)); 228 + tmp = realloc(tmp_cpus, max_entries * sizeof(struct perf_cpu)); 236 229 if (tmp == NULL) 237 230 goto invalid; 238 231 tmp_cpus = tmp; 239 232 } 240 - tmp_cpus[nr_cpus++] = (int)start_cpu; 233 + tmp_cpus[nr_cpus++].cpu = (int)start_cpu; 241 234 } 242 235 if (*p) 243 236 ++p; ··· 257 250 return cpus; 258 251 } 259 252 260 - int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx) 253 + struct perf_cpu perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx) 261 254 { 255 + struct perf_cpu result = { 256 + .cpu = -1 257 + }; 258 + 262 259 if (cpus && idx < cpus->nr) 263 260 return cpus->map[idx]; 264 261 265 - return -1; 262 + return result; 266 263 } 267 264 268 265 int perf_cpu_map__nr(const struct perf_cpu_map *cpus) ··· 276 265 277 266 bool perf_cpu_map__empty(const struct perf_cpu_map *map) 278 267 { 279 - return map ? map->map[0] == -1 : true; 268 + return map ? map->map[0].cpu == -1 : true; 280 269 } 281 270 282 - int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu) 271 + int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu) 283 272 { 284 273 int low, high; 285 274 ··· 289 278 low = 0; 290 279 high = cpus->nr; 291 280 while (low < high) { 292 - int idx = (low + high) / 2, 293 - cpu_at_idx = cpus->map[idx]; 281 + int idx = (low + high) / 2; 282 + struct perf_cpu cpu_at_idx = cpus->map[idx]; 294 283 295 - if (cpu_at_idx == cpu) 284 + if (cpu_at_idx.cpu == cpu.cpu) 296 285 return idx; 297 286 298 - if (cpu_at_idx > cpu) 287 + if (cpu_at_idx.cpu > cpu.cpu) 299 288 high = idx; 300 289 else 301 290 low = idx + 1; ··· 304 293 return -1; 305 294 } 306 295 307 - bool perf_cpu_map__has(const struct perf_cpu_map *cpus, int cpu) 296 + bool perf_cpu_map__has(const struct perf_cpu_map *cpus, struct perf_cpu cpu) 308 297 { 309 298 return perf_cpu_map__idx(cpus, cpu) != -1; 310 299 } 311 300 312 - int perf_cpu_map__max(struct perf_cpu_map *map) 301 + struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map) 313 302 { 303 + struct perf_cpu result = { 304 + .cpu = -1 305 + }; 306 + 314 307 // cpu_map__trim_new() qsort()s it, cpu_map__default_new() sorts it as well. 315 - return map->nr > 0 ? map->map[map->nr - 1] : -1; 308 + return map->nr > 0 ? map->map[map->nr - 1] : result; 316 309 } 317 310 318 311 /* ··· 330 315 struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, 331 316 struct perf_cpu_map *other) 332 317 { 333 - int *tmp_cpus; 318 + struct perf_cpu *tmp_cpus; 334 319 int tmp_len; 335 320 int i, j, k; 336 321 struct perf_cpu_map *merged; ··· 344 329 if (!other) 345 330 return orig; 346 331 if (orig->nr == other->nr && 347 - !memcmp(orig->map, other->map, orig->nr * sizeof(int))) 332 + !memcmp(orig->map, other->map, orig->nr * sizeof(struct perf_cpu))) 348 333 return orig; 349 334 350 335 tmp_len = orig->nr + other->nr; 351 - tmp_cpus = malloc(tmp_len * sizeof(int)); 336 + tmp_cpus = malloc(tmp_len * sizeof(struct perf_cpu)); 352 337 if (!tmp_cpus) 353 338 return NULL; 354 339 355 340 /* Standard merge algorithm from wikipedia */ 356 341 i = j = k = 0; 357 342 while (i < orig->nr && j < other->nr) { 358 - if (orig->map[i] <= other->map[j]) { 359 - if (orig->map[i] == other->map[j]) 343 + if (orig->map[i].cpu <= other->map[j].cpu) { 344 + if (orig->map[i].cpu == other->map[j].cpu) 360 345 j++; 361 346 tmp_cpus[k++] = orig->map[i++]; 362 347 } else
+2 -2
tools/lib/perf/evlist.c
··· 407 407 408 408 static int 409 409 perf_evlist__mmap_cb_mmap(struct perf_mmap *map, struct perf_mmap_param *mp, 410 - int output, int cpu) 410 + int output, struct perf_cpu cpu) 411 411 { 412 412 return perf_mmap__mmap(map, mp, output, cpu); 413 413 } ··· 426 426 int idx, struct perf_mmap_param *mp, int cpu_idx, 427 427 int thread, int *_output, int *_output_overwrite) 428 428 { 429 - int evlist_cpu = perf_cpu_map__cpu(evlist->cpus, cpu_idx); 429 + struct perf_cpu evlist_cpu = perf_cpu_map__cpu(evlist->cpus, cpu_idx); 430 430 struct perf_evsel *evsel; 431 431 int revent; 432 432
+5 -4
tools/lib/perf/evsel.c
··· 78 78 79 79 static int 80 80 sys_perf_event_open(struct perf_event_attr *attr, 81 - pid_t pid, int cpu, int group_fd, 81 + pid_t pid, struct perf_cpu cpu, int group_fd, 82 82 unsigned long flags) 83 83 { 84 - return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); 84 + return syscall(__NR_perf_event_open, attr, pid, cpu.cpu, group_fd, flags); 85 85 } 86 86 87 87 static int get_group_fd(struct perf_evsel *evsel, int cpu_map_idx, int thread, int *group_fd) ··· 113 113 int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, 114 114 struct perf_thread_map *threads) 115 115 { 116 - int cpu, idx, thread, err = 0; 116 + struct perf_cpu cpu; 117 + int idx, thread, err = 0; 117 118 118 119 if (cpus == NULL) { 119 120 static struct perf_cpu_map *empty_cpu_map; ··· 253 252 for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { 254 253 int *fd = FD(evsel, idx, thread); 255 254 struct perf_mmap *map; 256 - int cpu = perf_cpu_map__cpu(evsel->cpus, idx); 255 + struct perf_cpu cpu = perf_cpu_map__cpu(evsel->cpus, idx); 257 256 258 257 if (fd == NULL || *fd < 0) 259 258 continue;
+7 -2
tools/lib/perf/include/internal/cpumap.h
··· 4 4 5 5 #include <linux/refcount.h> 6 6 7 + /** A wrapper around a CPU to avoid confusion with the perf_cpu_map's map's indices. */ 8 + struct perf_cpu { 9 + int cpu; 10 + }; 11 + 7 12 /** 8 13 * A sized, reference counted, sorted array of integers representing CPU 9 14 * numbers. This is commonly used to capture which CPUs a PMU is associated ··· 21 16 /** Length of the map array. */ 22 17 int nr; 23 18 /** The CPU values. */ 24 - int map[]; 19 + struct perf_cpu map[]; 25 20 }; 26 21 27 22 #ifndef MAX_NR_CPUS 28 23 #define MAX_NR_CPUS 2048 29 24 #endif 30 25 31 - int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu); 26 + int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu); 32 27 33 28 #endif /* __LIBPERF_INTERNAL_CPUMAP_H */
+2 -1
tools/lib/perf/include/internal/evlist.h
··· 4 4 5 5 #include <linux/list.h> 6 6 #include <api/fd/array.h> 7 + #include <internal/cpumap.h> 7 8 #include <internal/evsel.h> 8 9 9 10 #define PERF_EVLIST__HLIST_BITS 8 ··· 37 36 typedef struct perf_mmap* 38 37 (*perf_evlist_mmap__cb_get_t)(struct perf_evlist*, bool, int); 39 38 typedef int 40 - (*perf_evlist_mmap__cb_mmap_t)(struct perf_mmap*, struct perf_mmap_param*, int, int); 39 + (*perf_evlist_mmap__cb_mmap_t)(struct perf_mmap*, struct perf_mmap_param*, int, struct perf_cpu); 41 40 42 41 struct perf_evlist_mmap_ops { 43 42 perf_evlist_mmap__cb_idx_t idx;
+2 -2
tools/lib/perf/include/internal/evsel.h
··· 6 6 #include <linux/perf_event.h> 7 7 #include <stdbool.h> 8 8 #include <sys/types.h> 9 + #include <internal/cpumap.h> 9 10 10 - struct perf_cpu_map; 11 11 struct perf_thread_map; 12 12 struct xyarray; 13 13 ··· 27 27 * queue number. 28 28 */ 29 29 int idx; 30 - int cpu; 30 + struct perf_cpu cpu; 31 31 pid_t tid; 32 32 33 33 /* Holds total ID period value for PERF_SAMPLE_READ processing. */
+3 -2
tools/lib/perf/include/internal/mmap.h
··· 6 6 #include <linux/refcount.h> 7 7 #include <linux/types.h> 8 8 #include <stdbool.h> 9 + #include <internal/cpumap.h> 9 10 10 11 /* perf sample has 16 bits size limit */ 11 12 #define PERF_SAMPLE_MAX_SIZE (1 << 16) ··· 25 24 void *base; 26 25 int mask; 27 26 int fd; 28 - int cpu; 27 + struct perf_cpu cpu; 29 28 refcount_t refcnt; 30 29 u64 prev; 31 30 u64 start; ··· 47 46 void perf_mmap__init(struct perf_mmap *map, struct perf_mmap *prev, 48 47 bool overwrite, libperf_unmap_cb_t unmap_cb); 49 48 int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp, 50 - int fd, int cpu); 49 + int fd, struct perf_cpu cpu); 51 50 void perf_mmap__munmap(struct perf_mmap *map); 52 51 void perf_mmap__get(struct perf_mmap *map); 53 52 void perf_mmap__put(struct perf_mmap *map);
+4 -5
tools/lib/perf/include/perf/cpumap.h
··· 3 3 #define __LIBPERF_CPUMAP_H 4 4 5 5 #include <perf/core.h> 6 + #include <perf/cpumap.h> 6 7 #include <stdio.h> 7 8 #include <stdbool.h> 8 - 9 - struct perf_cpu_map; 10 9 11 10 LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); 12 11 LIBPERF_API struct perf_cpu_map *perf_cpu_map__default_new(void); ··· 15 16 LIBPERF_API struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig, 16 17 struct perf_cpu_map *other); 17 18 LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); 18 - LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx); 19 + LIBPERF_API struct perf_cpu perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx); 19 20 LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus); 20 21 LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map); 21 - LIBPERF_API int perf_cpu_map__max(struct perf_cpu_map *map); 22 - LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, int cpu); 22 + LIBPERF_API struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map); 23 + LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu); 23 24 24 25 #define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \ 25 26 for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \
+1 -1
tools/lib/perf/mmap.c
··· 32 32 } 33 33 34 34 int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp, 35 - int fd, int cpu) 35 + int fd, struct perf_cpu cpu) 36 36 { 37 37 map->prev = 0; 38 38 map->mask = mp->mask;
+23 -12
tools/perf/arch/arm/util/cs-etm.c
··· 203 203 struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); 204 204 205 205 /* Set option of each CPU we have */ 206 - for (i = 0; i < cpu__max_cpu(); i++) { 207 - if (!perf_cpu_map__has(event_cpus, i) || 208 - !perf_cpu_map__has(online_cpus, i)) 206 + for (i = 0; i < cpu__max_cpu().cpu; i++) { 207 + struct perf_cpu cpu = { .cpu = i, }; 208 + 209 + if (!perf_cpu_map__has(event_cpus, cpu) || 210 + !perf_cpu_map__has(online_cpus, cpu)) 209 211 continue; 210 212 211 213 if (option & BIT(ETM_OPT_CTXTID)) { ··· 524 522 525 523 /* cpu map is not empty, we have specific CPUs to work with */ 526 524 if (!perf_cpu_map__empty(event_cpus)) { 527 - for (i = 0; i < cpu__max_cpu(); i++) { 528 - if (!perf_cpu_map__has(event_cpus, i) || 529 - !perf_cpu_map__has(online_cpus, i)) 525 + for (i = 0; i < cpu__max_cpu().cpu; i++) { 526 + struct perf_cpu cpu = { .cpu = i, }; 527 + 528 + if (!perf_cpu_map__has(event_cpus, cpu) || 529 + !perf_cpu_map__has(online_cpus, cpu)) 530 530 continue; 531 531 532 532 if (cs_etm_is_ete(itr, i)) ··· 540 536 } 541 537 } else { 542 538 /* get configuration for all CPUs in the system */ 543 - for (i = 0; i < cpu__max_cpu(); i++) { 544 - if (!perf_cpu_map__has(online_cpus, i)) 539 + for (i = 0; i < cpu__max_cpu().cpu; i++) { 540 + struct perf_cpu cpu = { .cpu = i, }; 541 + 542 + if (!perf_cpu_map__has(online_cpus, cpu)) 545 543 continue; 546 544 547 545 if (cs_etm_is_ete(itr, i)) ··· 728 722 } else { 729 723 /* Make sure all specified CPUs are online */ 730 724 for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) { 731 - if (perf_cpu_map__has(event_cpus, i) && 732 - !perf_cpu_map__has(online_cpus, i)) 725 + struct perf_cpu cpu = { .cpu = i, }; 726 + 727 + if (perf_cpu_map__has(event_cpus, cpu) && 728 + !perf_cpu_map__has(online_cpus, cpu)) 733 729 return -EINVAL; 734 730 } 735 731 ··· 751 743 752 744 offset = CS_ETM_SNAPSHOT + 1; 753 745 754 - for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++) 755 - if (perf_cpu_map__has(cpu_map, i)) 746 + for (i = 0; i < cpu__max_cpu().cpu && offset < priv_size; i++) { 747 + struct perf_cpu cpu = { .cpu = i, }; 748 + 749 + if (perf_cpu_map__has(cpu_map, cpu)) 756 750 cs_etm_get_metadata(i, &offset, itr, info); 751 + } 757 752 758 753 perf_cpu_map__put(online_cpus); 759 754
+1 -1
tools/perf/arch/arm64/util/pmu.c
··· 15 15 * The cpumap should cover all CPUs. Otherwise, some CPUs may 16 16 * not support some events or have different event IDs. 17 17 */ 18 - if (pmu->cpus->nr != cpu__max_cpu()) 18 + if (pmu->cpus->nr != cpu__max_cpu().cpu) 19 19 return NULL; 20 20 21 21 return perf_pmu__find_map(pmu);
+1 -1
tools/perf/bench/epoll-ctl.c
··· 253 253 254 254 if (!noaffinity) { 255 255 CPU_ZERO(&cpuset); 256 - CPU_SET(cpu->map[i % cpu->nr], &cpuset); 256 + CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset); 257 257 258 258 ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset); 259 259 if (ret)
+1 -1
tools/perf/bench/epoll-wait.c
··· 342 342 343 343 if (!noaffinity) { 344 344 CPU_ZERO(&cpuset); 345 - CPU_SET(cpu->map[i % cpu->nr], &cpuset); 345 + CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset); 346 346 347 347 ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset); 348 348 if (ret)
+1 -1
tools/perf/bench/futex-hash.c
··· 177 177 goto errmem; 178 178 179 179 CPU_ZERO(&cpuset); 180 - CPU_SET(cpu->map[i % cpu->nr], &cpuset); 180 + CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset); 181 181 182 182 ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset); 183 183 if (ret)
+1 -1
tools/perf/bench/futex-lock-pi.c
··· 136 136 worker[i].futex = &global_futex; 137 137 138 138 CPU_ZERO(&cpuset); 139 - CPU_SET(cpu->map[i % cpu->nr], &cpuset); 139 + CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset); 140 140 141 141 if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) 142 142 err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
+1 -1
tools/perf/bench/futex-requeue.c
··· 131 131 /* create and block all threads */ 132 132 for (i = 0; i < params.nthreads; i++) { 133 133 CPU_ZERO(&cpuset); 134 - CPU_SET(cpu->map[i % cpu->nr], &cpuset); 134 + CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset); 135 135 136 136 if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) 137 137 err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
+1 -1
tools/perf/bench/futex-wake-parallel.c
··· 152 152 /* create and block all threads */ 153 153 for (i = 0; i < params.nthreads; i++) { 154 154 CPU_ZERO(&cpuset); 155 - CPU_SET(cpu->map[i % cpu->nr], &cpuset); 155 + CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset); 156 156 157 157 if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) 158 158 err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
+1 -1
tools/perf/bench/futex-wake.c
··· 105 105 /* create and block all threads */ 106 106 for (i = 0; i < params.nthreads; i++) { 107 107 CPU_ZERO(&cpuset); 108 - CPU_SET(cpu->map[i % cpu->nr], &cpuset); 108 + CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset); 109 109 110 110 if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset)) 111 111 err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
+7 -6
tools/perf/builtin-c2c.c
··· 2015 2015 { 2016 2016 struct numa_node *n; 2017 2017 unsigned long **nodes; 2018 - int node, cpu, idx; 2018 + int node, idx; 2019 + struct perf_cpu cpu; 2019 2020 int *cpu2node; 2020 2021 2021 2022 if (c2c.node_info > 2) ··· 2039 2038 if (!cpu2node) 2040 2039 return -ENOMEM; 2041 2040 2042 - for (cpu = 0; cpu < c2c.cpus_cnt; cpu++) 2043 - cpu2node[cpu] = -1; 2041 + for (idx = 0; idx < c2c.cpus_cnt; idx++) 2042 + cpu2node[idx] = -1; 2044 2043 2045 2044 c2c.cpu2node = cpu2node; 2046 2045 ··· 2059 2058 continue; 2060 2059 2061 2060 perf_cpu_map__for_each_cpu(cpu, idx, map) { 2062 - set_bit(cpu, set); 2061 + set_bit(cpu.cpu, set); 2063 2062 2064 - if (WARN_ONCE(cpu2node[cpu] != -1, "node/cpu topology bug")) 2063 + if (WARN_ONCE(cpu2node[cpu.cpu] != -1, "node/cpu topology bug")) 2065 2064 return -EINVAL; 2066 2065 2067 - cpu2node[cpu] = node; 2066 + cpu2node[cpu.cpu] = node; 2068 2067 } 2069 2068 } 2070 2069
+1 -1
tools/perf/builtin-ftrace.c
··· 281 281 int ret; 282 282 int last_cpu; 283 283 284 - last_cpu = perf_cpu_map__cpu(cpumap, cpumap->nr - 1); 284 + last_cpu = perf_cpu_map__cpu(cpumap, cpumap->nr - 1).cpu; 285 285 mask_size = last_cpu / 4 + 2; /* one more byte for EOS */ 286 286 mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */ 287 287
+1 -1
tools/perf/builtin-kmem.c
··· 192 192 int ret = evsel__process_alloc_event(evsel, sample); 193 193 194 194 if (!ret) { 195 - int node1 = cpu__get_node(sample->cpu), 195 + int node1 = cpu__get_node((struct perf_cpu){.cpu = sample->cpu}), 196 196 node2 = evsel__intval(evsel, sample, "node"); 197 197 198 198 if (node1 != node2)
+1 -1
tools/perf/builtin-record.c
··· 2796 2796 symbol__init(NULL); 2797 2797 2798 2798 if (rec->opts.affinity != PERF_AFFINITY_SYS) { 2799 - rec->affinity_mask.nbits = cpu__max_cpu(); 2799 + rec->affinity_mask.nbits = cpu__max_cpu().cpu; 2800 2800 rec->affinity_mask.bits = bitmap_zalloc(rec->affinity_mask.nbits); 2801 2801 if (!rec->affinity_mask.bits) { 2802 2802 pr_err("Failed to allocate thread mask for %zd cpus\n", rec->affinity_mask.nbits);
+36 -29
tools/perf/builtin-sched.c
··· 167 167 168 168 struct perf_sched_map { 169 169 DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS); 170 - int *comp_cpus; 170 + struct perf_cpu *comp_cpus; 171 171 bool comp; 172 172 struct perf_thread_map *color_pids; 173 173 const char *color_pids_str; ··· 191 191 * Track the current task - that way we can know whether there's any 192 192 * weird events, such as a task being switched away that is not current. 193 193 */ 194 - int max_cpu; 194 + struct perf_cpu max_cpu; 195 195 u32 curr_pid[MAX_CPUS]; 196 196 struct thread *curr_thread[MAX_CPUS]; 197 197 char next_shortname1; ··· 1535 1535 int new_shortname; 1536 1536 u64 timestamp0, timestamp = sample->time; 1537 1537 s64 delta; 1538 - int i, this_cpu = sample->cpu; 1538 + int i; 1539 + struct perf_cpu this_cpu = { 1540 + .cpu = sample->cpu, 1541 + }; 1539 1542 int cpus_nr; 1540 1543 bool new_cpu = false; 1541 1544 const char *color = PERF_COLOR_NORMAL; 1542 1545 char stimestamp[32]; 1543 1546 1544 - BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); 1547 + BUG_ON(this_cpu.cpu >= MAX_CPUS || this_cpu.cpu < 0); 1545 1548 1546 - if (this_cpu > sched->max_cpu) 1549 + if (this_cpu.cpu > sched->max_cpu.cpu) 1547 1550 sched->max_cpu = this_cpu; 1548 1551 1549 1552 if (sched->map.comp) { 1550 1553 cpus_nr = bitmap_weight(sched->map.comp_cpus_mask, MAX_CPUS); 1551 - if (!test_and_set_bit(this_cpu, sched->map.comp_cpus_mask)) { 1554 + if (!test_and_set_bit(this_cpu.cpu, sched->map.comp_cpus_mask)) { 1552 1555 sched->map.comp_cpus[cpus_nr++] = this_cpu; 1553 1556 new_cpu = true; 1554 1557 } 1555 1558 } else 1556 - cpus_nr = sched->max_cpu; 1559 + cpus_nr = sched->max_cpu.cpu; 1557 1560 1558 - timestamp0 = sched->cpu_last_switched[this_cpu]; 1559 - sched->cpu_last_switched[this_cpu] = timestamp; 1561 + timestamp0 = sched->cpu_last_switched[this_cpu.cpu]; 1562 + sched->cpu_last_switched[this_cpu.cpu] = timestamp; 1560 1563 if (timestamp0) 1561 1564 delta = timestamp - timestamp0; 1562 1565 else ··· 1580 1577 return -1; 1581 1578 } 1582 1579 1583 - sched->curr_thread[this_cpu] = thread__get(sched_in); 1580 + sched->curr_thread[this_cpu.cpu] = thread__get(sched_in); 1584 1581 1585 1582 printf(" "); 1586 1583 ··· 1611 1608 } 1612 1609 1613 1610 for (i = 0; i < cpus_nr; i++) { 1614 - int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i; 1615 - struct thread *curr_thread = sched->curr_thread[cpu]; 1611 + struct perf_cpu cpu = { 1612 + .cpu = sched->map.comp ? sched->map.comp_cpus[i].cpu : i, 1613 + }; 1614 + struct thread *curr_thread = sched->curr_thread[cpu.cpu]; 1616 1615 struct thread_runtime *curr_tr; 1617 1616 const char *pid_color = color; 1618 1617 const char *cpu_color = color; ··· 1628 1623 if (sched->map.color_cpus && perf_cpu_map__has(sched->map.color_cpus, cpu)) 1629 1624 cpu_color = COLOR_CPUS; 1630 1625 1631 - if (cpu != this_cpu) 1626 + if (cpu.cpu != this_cpu.cpu) 1632 1627 color_fprintf(stdout, color, " "); 1633 1628 else 1634 1629 color_fprintf(stdout, cpu_color, "*"); 1635 1630 1636 - if (sched->curr_thread[cpu]) { 1637 - curr_tr = thread__get_runtime(sched->curr_thread[cpu]); 1631 + if (sched->curr_thread[cpu.cpu]) { 1632 + curr_tr = thread__get_runtime(sched->curr_thread[cpu.cpu]); 1638 1633 if (curr_tr == NULL) { 1639 1634 thread__put(sched_in); 1640 1635 return -1; ··· 1934 1929 1935 1930 static void timehist_header(struct perf_sched *sched) 1936 1931 { 1937 - u32 ncpus = sched->max_cpu + 1; 1932 + u32 ncpus = sched->max_cpu.cpu + 1; 1938 1933 u32 i, j; 1939 1934 1940 1935 printf("%15s %6s ", "time", "cpu"); ··· 2013 2008 struct thread_runtime *tr = thread__priv(thread); 2014 2009 const char *next_comm = evsel__strval(evsel, sample, "next_comm"); 2015 2010 const u32 next_pid = evsel__intval(evsel, sample, "next_pid"); 2016 - u32 max_cpus = sched->max_cpu + 1; 2011 + u32 max_cpus = sched->max_cpu.cpu + 1; 2017 2012 char tstr[64]; 2018 2013 char nstr[30]; 2019 2014 u64 wait_time; ··· 2394 2389 timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr)); 2395 2390 printf("%15s [%04d] ", tstr, sample->cpu); 2396 2391 if (sched->show_cpu_visual) 2397 - printf(" %*s ", sched->max_cpu + 1, ""); 2392 + printf(" %*s ", sched->max_cpu.cpu + 1, ""); 2398 2393 2399 2394 printf(" %-*s ", comm_width, timehist_get_commstr(thread)); 2400 2395 ··· 2454 2449 { 2455 2450 struct thread *thread; 2456 2451 char tstr[64]; 2457 - u32 max_cpus = sched->max_cpu + 1; 2452 + u32 max_cpus; 2458 2453 u32 ocpu, dcpu; 2459 2454 2460 2455 if (sched->summary_only) 2461 2456 return; 2462 2457 2463 - max_cpus = sched->max_cpu + 1; 2458 + max_cpus = sched->max_cpu.cpu + 1; 2464 2459 ocpu = evsel__intval(evsel, sample, "orig_cpu"); 2465 2460 dcpu = evsel__intval(evsel, sample, "dest_cpu"); 2466 2461 ··· 2923 2918 2924 2919 printf(" Total scheduling time (msec): "); 2925 2920 print_sched_time(hist_time, 2); 2926 - printf(" (x %d)\n", sched->max_cpu); 2921 + printf(" (x %d)\n", sched->max_cpu.cpu); 2927 2922 } 2928 2923 2929 2924 typedef int (*sched_handler)(struct perf_tool *tool, ··· 2940 2935 { 2941 2936 struct perf_sched *sched = container_of(tool, struct perf_sched, tool); 2942 2937 int err = 0; 2943 - int this_cpu = sample->cpu; 2938 + struct perf_cpu this_cpu = { 2939 + .cpu = sample->cpu, 2940 + }; 2944 2941 2945 - if (this_cpu > sched->max_cpu) 2942 + if (this_cpu.cpu > sched->max_cpu.cpu) 2946 2943 sched->max_cpu = this_cpu; 2947 2944 2948 2945 if (evsel->handler != NULL) { ··· 3061 3054 goto out; 3062 3055 3063 3056 /* pre-allocate struct for per-CPU idle stats */ 3064 - sched->max_cpu = session->header.env.nr_cpus_online; 3065 - if (sched->max_cpu == 0) 3066 - sched->max_cpu = 4; 3067 - if (init_idle_threads(sched->max_cpu)) 3057 + sched->max_cpu.cpu = session->header.env.nr_cpus_online; 3058 + if (sched->max_cpu.cpu == 0) 3059 + sched->max_cpu.cpu = 4; 3060 + if (init_idle_threads(sched->max_cpu.cpu)) 3068 3061 goto out; 3069 3062 3070 3063 /* summary_only implies summary option, but don't overwrite summary if set */ ··· 3216 3209 { 3217 3210 struct perf_cpu_map *map; 3218 3211 3219 - sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF); 3212 + sched->max_cpu.cpu = sysconf(_SC_NPROCESSORS_CONF); 3220 3213 3221 3214 if (sched->map.comp) { 3222 - sched->map.comp_cpus = zalloc(sched->max_cpu * sizeof(int)); 3215 + sched->map.comp_cpus = zalloc(sched->max_cpu.cpu * sizeof(int)); 3223 3216 if (!sched->map.comp_cpus) 3224 3217 return -1; 3225 3218 }
+3 -2
tools/perf/builtin-script.c
··· 2115 2115 static void __process_stat(struct evsel *counter, u64 tstamp) 2116 2116 { 2117 2117 int nthreads = perf_thread_map__nr(counter->core.threads); 2118 - int idx, cpu, thread; 2118 + int idx, thread; 2119 + struct perf_cpu cpu; 2119 2120 static int header_printed; 2120 2121 2121 2122 if (counter->core.system_wide) ··· 2135 2134 counts = perf_counts(counter->counts, idx, thread); 2136 2135 2137 2136 printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n", 2138 - cpu, 2137 + cpu.cpu, 2139 2138 perf_thread_map__pid(counter->core.threads, thread), 2140 2139 counts->val, 2141 2140 counts->ena,
+34 -33
tools/perf/builtin-stat.c
··· 234 234 return false; 235 235 236 236 for (int i = 0; i < a->core.cpus->nr; i++) { 237 - if (a->core.cpus->map[i] != b->core.cpus->map[i]) 237 + if (a->core.cpus->map[i].cpu != b->core.cpus->map[i].cpu) 238 238 return false; 239 239 } 240 240 ··· 331 331 struct perf_counts_values *count) 332 332 { 333 333 struct perf_sample_id *sid = SID(counter, cpu_map_idx, thread); 334 - int cpu = perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx); 334 + struct perf_cpu cpu = perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx); 335 335 336 336 return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count, 337 337 process_synthesized_event, NULL); ··· 396 396 fprintf(stat_config.output, 397 397 "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 398 398 evsel__name(counter), 399 - perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx), 399 + perf_cpu_map__cpu(evsel__cpus(counter), 400 + cpu_map_idx).cpu, 400 401 count->val, count->ena, count->run); 401 402 } 402 403 } ··· 1329 1328 }; 1330 1329 1331 1330 static struct aggr_cpu_id perf_stat__get_socket(struct perf_stat_config *config __maybe_unused, 1332 - int cpu) 1331 + struct perf_cpu cpu) 1333 1332 { 1334 1333 return aggr_cpu_id__socket(cpu, /*data=*/NULL); 1335 1334 } 1336 1335 1337 1336 static struct aggr_cpu_id perf_stat__get_die(struct perf_stat_config *config __maybe_unused, 1338 - int cpu) 1337 + struct perf_cpu cpu) 1339 1338 { 1340 1339 return aggr_cpu_id__die(cpu, /*data=*/NULL); 1341 1340 } 1342 1341 1343 1342 static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused, 1344 - int cpu) 1343 + struct perf_cpu cpu) 1345 1344 { 1346 1345 return aggr_cpu_id__core(cpu, /*data=*/NULL); 1347 1346 } 1348 1347 1349 1348 static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __maybe_unused, 1350 - int cpu) 1349 + struct perf_cpu cpu) 1351 1350 { 1352 1351 return aggr_cpu_id__node(cpu, /*data=*/NULL); 1353 1352 } 1354 1353 1355 1354 static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config, 1356 - aggr_get_id_t get_id, int cpu) 1355 + aggr_get_id_t get_id, struct perf_cpu cpu) 1357 1356 { 1358 1357 struct aggr_cpu_id id = aggr_cpu_id__empty(); 1359 1358 1360 - if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu])) 1361 - config->cpus_aggr_map->map[cpu] = get_id(config, cpu); 1359 + if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu.cpu])) 1360 + config->cpus_aggr_map->map[cpu.cpu] = get_id(config, cpu); 1362 1361 1363 - id = config->cpus_aggr_map->map[cpu]; 1362 + id = config->cpus_aggr_map->map[cpu.cpu]; 1364 1363 return id; 1365 1364 } 1366 1365 1367 1366 static struct aggr_cpu_id perf_stat__get_socket_cached(struct perf_stat_config *config, 1368 - int cpu) 1367 + struct perf_cpu cpu) 1369 1368 { 1370 1369 return perf_stat__get_aggr(config, perf_stat__get_socket, cpu); 1371 1370 } 1372 1371 1373 1372 static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *config, 1374 - int cpu) 1373 + struct perf_cpu cpu) 1375 1374 { 1376 1375 return perf_stat__get_aggr(config, perf_stat__get_die, cpu); 1377 1376 } 1378 1377 1379 1378 static struct aggr_cpu_id perf_stat__get_core_cached(struct perf_stat_config *config, 1380 - int cpu) 1379 + struct perf_cpu cpu) 1381 1380 { 1382 1381 return perf_stat__get_aggr(config, perf_stat__get_core, cpu); 1383 1382 } 1384 1383 1385 1384 static struct aggr_cpu_id perf_stat__get_node_cached(struct perf_stat_config *config, 1386 - int cpu) 1385 + struct perf_cpu cpu) 1387 1386 { 1388 1387 return perf_stat__get_aggr(config, perf_stat__get_node, cpu); 1389 1388 } ··· 1468 1467 * taking the highest cpu number to be the size of 1469 1468 * the aggregation translate cpumap. 1470 1469 */ 1471 - nr = perf_cpu_map__max(evsel_list->core.cpus); 1470 + nr = perf_cpu_map__max(evsel_list->core.cpus).cpu; 1472 1471 stat_config.cpus_aggr_map = cpu_aggr_map__empty_new(nr + 1); 1473 1472 return stat_config.cpus_aggr_map ? 0 : -ENOMEM; 1474 1473 } ··· 1496 1495 stat_config.cpus_aggr_map = NULL; 1497 1496 } 1498 1497 1499 - static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data) 1498 + static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(struct perf_cpu cpu, void *data) 1500 1499 { 1501 1500 struct perf_env *env = data; 1502 1501 struct aggr_cpu_id id = aggr_cpu_id__empty(); 1503 1502 1504 - if (cpu != -1) 1505 - id.socket = env->cpu[cpu].socket_id; 1503 + if (cpu.cpu != -1) 1504 + id.socket = env->cpu[cpu.cpu].socket_id; 1506 1505 1507 1506 return id; 1508 1507 } 1509 1508 1510 - static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data) 1509 + static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(struct perf_cpu cpu, void *data) 1511 1510 { 1512 1511 struct perf_env *env = data; 1513 1512 struct aggr_cpu_id id = aggr_cpu_id__empty(); 1514 1513 1515 - if (cpu != -1) { 1514 + if (cpu.cpu != -1) { 1516 1515 /* 1517 1516 * die_id is relative to socket, so start 1518 1517 * with the socket ID and then add die to 1519 1518 * make a unique ID. 1520 1519 */ 1521 - id.socket = env->cpu[cpu].socket_id; 1522 - id.die = env->cpu[cpu].die_id; 1520 + id.socket = env->cpu[cpu.cpu].socket_id; 1521 + id.die = env->cpu[cpu.cpu].die_id; 1523 1522 } 1524 1523 1525 1524 return id; 1526 1525 } 1527 1526 1528 - static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data) 1527 + static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data) 1529 1528 { 1530 1529 struct perf_env *env = data; 1531 1530 struct aggr_cpu_id id = aggr_cpu_id__empty(); 1532 1531 1533 - if (cpu != -1) { 1532 + if (cpu.cpu != -1) { 1534 1533 /* 1535 1534 * core_id is relative to socket and die, 1536 1535 * we need a global id. So we set 1537 1536 * socket, die id and core id 1538 1537 */ 1539 - id.socket = env->cpu[cpu].socket_id; 1540 - id.die = env->cpu[cpu].die_id; 1541 - id.core = env->cpu[cpu].core_id; 1538 + id.socket = env->cpu[cpu.cpu].socket_id; 1539 + id.die = env->cpu[cpu.cpu].die_id; 1540 + id.core = env->cpu[cpu.cpu].core_id; 1542 1541 } 1543 1542 1544 1543 return id; 1545 1544 } 1546 1545 1547 - static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data) 1546 + static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(struct perf_cpu cpu, void *data) 1548 1547 { 1549 1548 struct aggr_cpu_id id = aggr_cpu_id__empty(); 1550 1549 ··· 1553 1552 } 1554 1553 1555 1554 static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, 1556 - int cpu) 1555 + struct perf_cpu cpu) 1557 1556 { 1558 1557 return perf_env__get_socket_aggr_by_cpu(cpu, &perf_stat.session->header.env); 1559 1558 } 1560 1559 static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused, 1561 - int cpu) 1560 + struct perf_cpu cpu) 1562 1561 { 1563 1562 return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env); 1564 1563 } 1565 1564 1566 1565 static struct aggr_cpu_id perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused, 1567 - int cpu) 1566 + struct perf_cpu cpu) 1568 1567 { 1569 1568 return perf_env__get_core_aggr_by_cpu(cpu, &perf_stat.session->header.env); 1570 1569 } 1571 1570 1572 1571 static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused, 1573 - int cpu) 1572 + struct perf_cpu cpu) 1574 1573 { 1575 1574 return perf_env__get_node_aggr_by_cpu(cpu, &perf_stat.session->header.env); 1576 1575 }
+3 -3
tools/perf/tests/attr.c
··· 65 65 66 66 #define WRITE_ASS(field, fmt) __WRITE_ASS(field, fmt, attr->field) 67 67 68 - static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, 68 + static int store_event(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu, 69 69 int fd, int group_fd, unsigned long flags) 70 70 { 71 71 FILE *file; ··· 93 93 /* syscall arguments */ 94 94 __WRITE_ASS(fd, "d", fd); 95 95 __WRITE_ASS(group_fd, "d", group_fd); 96 - __WRITE_ASS(cpu, "d", cpu); 96 + __WRITE_ASS(cpu, "d", cpu.cpu); 97 97 __WRITE_ASS(pid, "d", pid); 98 98 __WRITE_ASS(flags, "lu", flags); 99 99 ··· 144 144 return 0; 145 145 } 146 146 147 - void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, 147 + void test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu, 148 148 int fd, int group_fd, unsigned long flags) 149 149 { 150 150 int errno_saved = errno;
+1 -1
tools/perf/tests/bitmap.c
··· 18 18 19 19 if (map && bm) { 20 20 for (i = 0; i < map->nr; i++) 21 - set_bit(map->map[i], bm); 21 + set_bit(map->map[i].cpu, bm); 22 22 } 23 23 24 24 if (map)
+3 -3
tools/perf/tests/cpumap.c
··· 38 38 TEST_ASSERT_VAL("wrong nr", map->nr == 20); 39 39 40 40 for (i = 0; i < 20; i++) { 41 - TEST_ASSERT_VAL("wrong cpu", map->map[i] == i); 41 + TEST_ASSERT_VAL("wrong cpu", map->map[i].cpu == i); 42 42 } 43 43 44 44 perf_cpu_map__put(map); ··· 67 67 68 68 map = cpu_map__new_data(data); 69 69 TEST_ASSERT_VAL("wrong nr", map->nr == 2); 70 - TEST_ASSERT_VAL("wrong cpu", map->map[0] == 1); 71 - TEST_ASSERT_VAL("wrong cpu", map->map[1] == 256); 70 + TEST_ASSERT_VAL("wrong cpu", map->map[0].cpu == 1); 71 + TEST_ASSERT_VAL("wrong cpu", map->map[1].cpu == 256); 72 72 TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1); 73 73 perf_cpu_map__put(map); 74 74 return 0;
+3 -3
tools/perf/tests/event_update.c
··· 76 76 TEST_ASSERT_VAL("wrong id", ev->id == 123); 77 77 TEST_ASSERT_VAL("wrong type", ev->type == PERF_EVENT_UPDATE__CPUS); 78 78 TEST_ASSERT_VAL("wrong cpus", map->nr == 3); 79 - TEST_ASSERT_VAL("wrong cpus", map->map[0] == 1); 80 - TEST_ASSERT_VAL("wrong cpus", map->map[1] == 2); 81 - TEST_ASSERT_VAL("wrong cpus", map->map[2] == 3); 79 + TEST_ASSERT_VAL("wrong cpus", map->map[0].cpu == 1); 80 + TEST_ASSERT_VAL("wrong cpus", map->map[1].cpu == 2); 81 + TEST_ASSERT_VAL("wrong cpus", map->map[2].cpu == 3); 82 82 perf_cpu_map__put(map); 83 83 return 0; 84 84 }
+1 -1
tools/perf/tests/mem2node.c
··· 31 31 32 32 if (map && bm) { 33 33 for (i = 0; i < map->nr; i++) { 34 - set_bit(map->map[i], bm); 34 + set_bit(map->map[i].cpu, bm); 35 35 } 36 36 } 37 37
+2 -2
tools/perf/tests/mmap-basic.c
··· 59 59 } 60 60 61 61 CPU_ZERO(&cpu_set); 62 - CPU_SET(cpus->map[0], &cpu_set); 62 + CPU_SET(cpus->map[0].cpu, &cpu_set); 63 63 sched_setaffinity(0, sizeof(cpu_set), &cpu_set); 64 64 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { 65 65 pr_debug("sched_setaffinity() failed on CPU %d: %s ", 66 - cpus->map[0], str_error_r(errno, sbuf, sizeof(sbuf))); 66 + cpus->map[0].cpu, str_error_r(errno, sbuf, sizeof(sbuf))); 67 67 goto out_free_cpus; 68 68 } 69 69
+9 -8
tools/perf/tests/openat-syscall-all-cpus.c
··· 22 22 static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __maybe_unused, 23 23 int subtest __maybe_unused) 24 24 { 25 - int err = -1, fd, idx, cpu; 25 + int err = -1, fd, idx; 26 + struct perf_cpu cpu; 26 27 struct perf_cpu_map *cpus; 27 28 struct evsel *evsel; 28 29 unsigned int nr_openat_calls = 111, i; ··· 67 66 * without CPU_ALLOC. 1024 cpus in 2010 still seems 68 67 * a reasonable upper limit tho :-) 69 68 */ 70 - if (cpu >= CPU_SETSIZE) { 71 - pr_debug("Ignoring CPU %d\n", cpu); 69 + if (cpu.cpu >= CPU_SETSIZE) { 70 + pr_debug("Ignoring CPU %d\n", cpu.cpu); 72 71 continue; 73 72 } 74 73 75 - CPU_SET(cpu, &cpu_set); 74 + CPU_SET(cpu.cpu, &cpu_set); 76 75 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { 77 76 pr_debug("sched_setaffinity() failed on CPU %d: %s ", 78 - cpu, 77 + cpu.cpu, 79 78 str_error_r(errno, sbuf, sizeof(sbuf))); 80 79 goto out_close_fd; 81 80 } ··· 83 82 fd = openat(0, "/etc/passwd", O_RDONLY); 84 83 close(fd); 85 84 } 86 - CPU_CLR(cpu, &cpu_set); 85 + CPU_CLR(cpu.cpu, &cpu_set); 87 86 } 88 87 89 88 evsel->core.cpus = perf_cpu_map__get(cpus); ··· 93 92 perf_cpu_map__for_each_cpu(cpu, idx, cpus) { 94 93 unsigned int expected; 95 94 96 - if (cpu >= CPU_SETSIZE) 95 + if (cpu.cpu >= CPU_SETSIZE) 97 96 continue; 98 97 99 98 if (evsel__read_on_cpu(evsel, idx, 0) < 0) { ··· 105 104 expected = nr_openat_calls + idx; 106 105 if (perf_counts(evsel->counts, idx, 0)->val != expected) { 107 106 pr_debug("evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", 108 - expected, cpu, perf_counts(evsel->counts, idx, 0)->val); 107 + expected, cpu.cpu, perf_counts(evsel->counts, idx, 0)->val); 109 108 err = -1; 110 109 } 111 110 }
+2 -1
tools/perf/tests/stat.c
··· 87 87 count.run = 300; 88 88 89 89 TEST_ASSERT_VAL("failed to synthesize stat_config", 90 - !perf_event__synthesize_stat(NULL, 1, 2, 3, &count, process_stat_event, NULL)); 90 + !perf_event__synthesize_stat(NULL, (struct perf_cpu){.cpu = 1}, 2, 3, 91 + &count, process_stat_event, NULL)); 91 92 92 93 return 0; 93 94 }
+16 -14
tools/perf/tests/topology.c
··· 112 112 TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu); 113 113 114 114 for (i = 0; i < session->header.env.nr_cpus_avail; i++) { 115 - if (!perf_cpu_map__has(map, i)) 115 + struct perf_cpu cpu = { .cpu = i }; 116 + 117 + if (!perf_cpu_map__has(map, cpu)) 116 118 continue; 117 119 pr_debug("CPU %d, core %d, socket %d\n", i, 118 120 session->header.env.cpu[i].core_id, ··· 124 122 // Test that CPU ID contains socket, die, core and CPU 125 123 for (i = 0; i < map->nr; i++) { 126 124 id = aggr_cpu_id__cpu(perf_cpu_map__cpu(map, i), NULL); 127 - TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match", map->map[i] == id.cpu); 125 + TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match", map->map[i].cpu == id.cpu.cpu); 128 126 129 127 TEST_ASSERT_VAL("Cpu map - Core ID doesn't match", 130 - session->header.env.cpu[map->map[i]].core_id == id.core); 128 + session->header.env.cpu[map->map[i].cpu].core_id == id.core); 131 129 TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match", 132 - session->header.env.cpu[map->map[i]].socket_id == id.socket); 130 + session->header.env.cpu[map->map[i].cpu].socket_id == id.socket); 133 131 134 132 TEST_ASSERT_VAL("Cpu map - Die ID doesn't match", 135 - session->header.env.cpu[map->map[i]].die_id == id.die); 133 + session->header.env.cpu[map->map[i].cpu].die_id == id.die); 136 134 TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node == -1); 137 135 TEST_ASSERT_VAL("Cpu map - Thread is set", id.thread == -1); 138 136 } ··· 141 139 for (i = 0; i < map->nr; i++) { 142 140 id = aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL); 143 141 TEST_ASSERT_VAL("Core map - Core ID doesn't match", 144 - session->header.env.cpu[map->map[i]].core_id == id.core); 142 + session->header.env.cpu[map->map[i].cpu].core_id == id.core); 145 143 146 144 TEST_ASSERT_VAL("Core map - Socket ID doesn't match", 147 - session->header.env.cpu[map->map[i]].socket_id == id.socket); 145 + session->header.env.cpu[map->map[i].cpu].socket_id == id.socket); 148 146 149 147 TEST_ASSERT_VAL("Core map - Die ID doesn't match", 150 - session->header.env.cpu[map->map[i]].die_id == id.die); 148 + session->header.env.cpu[map->map[i].cpu].die_id == id.die); 151 149 TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1); 152 150 TEST_ASSERT_VAL("Core map - Thread is set", id.thread == -1); 153 151 } ··· 156 154 for (i = 0; i < map->nr; i++) { 157 155 id = aggr_cpu_id__die(perf_cpu_map__cpu(map, i), NULL); 158 156 TEST_ASSERT_VAL("Die map - Socket ID doesn't match", 159 - session->header.env.cpu[map->map[i]].socket_id == id.socket); 157 + session->header.env.cpu[map->map[i].cpu].socket_id == id.socket); 160 158 161 159 TEST_ASSERT_VAL("Die map - Die ID doesn't match", 162 - session->header.env.cpu[map->map[i]].die_id == id.die); 160 + session->header.env.cpu[map->map[i].cpu].die_id == id.die); 163 161 164 162 TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1); 165 163 TEST_ASSERT_VAL("Die map - Core is set", id.core == -1); 166 - TEST_ASSERT_VAL("Die map - CPU is set", id.cpu == -1); 164 + TEST_ASSERT_VAL("Die map - CPU is set", id.cpu.cpu == -1); 167 165 TEST_ASSERT_VAL("Die map - Thread is set", id.thread == -1); 168 166 } 169 167 ··· 171 169 for (i = 0; i < map->nr; i++) { 172 170 id = aggr_cpu_id__socket(perf_cpu_map__cpu(map, i), NULL); 173 171 TEST_ASSERT_VAL("Socket map - Socket ID doesn't match", 174 - session->header.env.cpu[map->map[i]].socket_id == id.socket); 172 + session->header.env.cpu[map->map[i].cpu].socket_id == id.socket); 175 173 176 174 TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1); 177 175 TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1); 178 176 TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1); 179 - TEST_ASSERT_VAL("Socket map - CPU is set", id.cpu == -1); 177 + TEST_ASSERT_VAL("Socket map - CPU is set", id.cpu.cpu == -1); 180 178 TEST_ASSERT_VAL("Socket map - Thread is set", id.thread == -1); 181 179 } 182 180 ··· 188 186 TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1); 189 187 TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1); 190 188 TEST_ASSERT_VAL("Node map - Core is set", id.core == -1); 191 - TEST_ASSERT_VAL("Node map - CPU is set", id.cpu == -1); 189 + TEST_ASSERT_VAL("Node map - CPU is set", id.cpu.cpu == -1); 192 190 TEST_ASSERT_VAL("Node map - Thread is set", id.thread == -1); 193 191 } 194 192 perf_session__delete(session);
+1 -1
tools/perf/util/affinity.c
··· 11 11 12 12 static int get_cpu_set_size(void) 13 13 { 14 - int sz = cpu__max_cpu() + 8 - 1; 14 + int sz = cpu__max_cpu().cpu + 8 - 1; 15 15 /* 16 16 * sched_getaffinity doesn't like masks smaller than the kernel. 17 17 * Hopefully that's big enough.
+6 -6
tools/perf/util/auxtrace.c
··· 123 123 mm->prev = 0; 124 124 mm->idx = mp->idx; 125 125 mm->tid = mp->tid; 126 - mm->cpu = mp->cpu; 126 + mm->cpu = mp->cpu.cpu; 127 127 128 128 if (!mp->len) { 129 129 mm->base = NULL; ··· 180 180 else 181 181 mp->tid = -1; 182 182 } else { 183 - mp->cpu = -1; 183 + mp->cpu.cpu = -1; 184 184 mp->tid = perf_thread_map__pid(evlist->core.threads, idx); 185 185 } 186 186 } ··· 292 292 if (!queue->set) { 293 293 queue->set = true; 294 294 queue->tid = buffer->tid; 295 - queue->cpu = buffer->cpu; 295 + queue->cpu = buffer->cpu.cpu; 296 296 } 297 297 298 298 buffer->buffer_nr = queues->next_buffer_nr++; ··· 339 339 return 0; 340 340 } 341 341 342 - static bool filter_cpu(struct perf_session *session, int cpu) 342 + static bool filter_cpu(struct perf_session *session, struct perf_cpu cpu) 343 343 { 344 344 unsigned long *cpu_bitmap = session->itrace_synth_opts->cpu_bitmap; 345 345 346 - return cpu_bitmap && cpu != -1 && !test_bit(cpu, cpu_bitmap); 346 + return cpu_bitmap && cpu.cpu != -1 && !test_bit(cpu.cpu, cpu_bitmap); 347 347 } 348 348 349 349 static int auxtrace_queues__add_buffer(struct auxtrace_queues *queues, ··· 399 399 struct auxtrace_buffer buffer = { 400 400 .pid = -1, 401 401 .tid = event->auxtrace.tid, 402 - .cpu = event->auxtrace.cpu, 402 + .cpu = { event->auxtrace.cpu }, 403 403 .data_offset = data_offset, 404 404 .offset = event->auxtrace.offset, 405 405 .reference = event->auxtrace.reference,
+3 -2
tools/perf/util/auxtrace.h
··· 15 15 #include <linux/list.h> 16 16 #include <linux/perf_event.h> 17 17 #include <linux/types.h> 18 + #include <internal/cpumap.h> 18 19 #include <asm/bitsperlong.h> 19 20 #include <asm/barrier.h> 20 21 ··· 241 240 size_t size; 242 241 pid_t pid; 243 242 pid_t tid; 244 - int cpu; 243 + struct perf_cpu cpu; 245 244 void *data; 246 245 off_t data_offset; 247 246 void *mmap_addr; ··· 351 350 int prot; 352 351 int idx; 353 352 pid_t tid; 354 - int cpu; 353 + struct perf_cpu cpu; 355 354 }; 356 355 357 356 /**
+7 -5
tools/perf/util/bpf_counter.c
··· 540 540 filter_type == BPERF_FILTER_TGID) 541 541 key = evsel->core.threads->map[i].pid; 542 542 else if (filter_type == BPERF_FILTER_CPU) 543 - key = evsel->core.cpus->map[i]; 543 + key = evsel->core.cpus->map[i].cpu; 544 544 else 545 545 break; 546 546 ··· 584 584 585 585 num_cpu = all_cpu_map->nr; 586 586 for (i = 0; i < num_cpu; i++) { 587 - cpu = all_cpu_map->map[i]; 587 + cpu = all_cpu_map->map[i].cpu; 588 588 bperf_trigger_reading(evsel->bperf_leader_prog_fd, cpu); 589 589 } 590 590 return 0; ··· 605 605 static int bperf__read(struct evsel *evsel) 606 606 { 607 607 struct bperf_follower_bpf *skel = evsel->follower_skel; 608 - __u32 num_cpu_bpf = cpu__max_cpu(); 608 + __u32 num_cpu_bpf = cpu__max_cpu().cpu; 609 609 struct bpf_perf_event_value values[num_cpu_bpf]; 610 610 int reading_map_fd, err = 0; 611 611 __u32 i; ··· 615 615 reading_map_fd = bpf_map__fd(skel->maps.accum_readings); 616 616 617 617 for (i = 0; i < bpf_map__max_entries(skel->maps.accum_readings); i++) { 618 + struct perf_cpu entry; 618 619 __u32 cpu; 619 620 620 621 err = bpf_map_lookup_elem(reading_map_fd, &i, values); ··· 625 624 case BPERF_FILTER_GLOBAL: 626 625 assert(i == 0); 627 626 628 - perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) { 627 + perf_cpu_map__for_each_cpu(entry, j, all_cpu_map) { 628 + cpu = entry.cpu; 629 629 perf_counts(evsel->counts, cpu, 0)->val = values[cpu].counter; 630 630 perf_counts(evsel->counts, cpu, 0)->ena = values[cpu].enabled; 631 631 perf_counts(evsel->counts, cpu, 0)->run = values[cpu].running; 632 632 } 633 633 break; 634 634 case BPERF_FILTER_CPU: 635 - cpu = evsel->core.cpus->map[i]; 635 + cpu = evsel->core.cpus->map[i].cpu; 636 636 perf_counts(evsel->counts, i, 0)->val = values[cpu].counter; 637 637 perf_counts(evsel->counts, i, 0)->ena = values[cpu].enabled; 638 638 perf_counts(evsel->counts, i, 0)->run = values[cpu].running;
+5 -5
tools/perf/util/bpf_counter_cgroup.c
··· 48 48 struct cgroup *cgrp, *leader_cgrp; 49 49 __u32 i, cpu; 50 50 __u32 nr_cpus = evlist->core.all_cpus->nr; 51 - int total_cpus = cpu__max_cpu(); 51 + int total_cpus = cpu__max_cpu().cpu; 52 52 int map_size, map_fd; 53 53 int prog_fd, err; 54 54 ··· 125 125 for (cpu = 0; cpu < nr_cpus; cpu++) { 126 126 int fd = FD(evsel, cpu); 127 127 __u32 idx = evsel->core.idx * total_cpus + 128 - evlist->core.all_cpus->map[cpu]; 128 + evlist->core.all_cpus->map[cpu].cpu; 129 129 130 130 err = bpf_map_update_elem(map_fd, &idx, &fd, 131 131 BPF_ANY); ··· 212 212 int prog_fd = bpf_program__fd(skel->progs.trigger_read); 213 213 214 214 for (i = 0; i < nr_cpus; i++) { 215 - cpu = evlist->core.all_cpus->map[i]; 215 + cpu = evlist->core.all_cpus->map[i].cpu; 216 216 bperf_trigger_reading(prog_fd, cpu); 217 217 } 218 218 ··· 245 245 { 246 246 struct evlist *evlist = evsel->evlist; 247 247 int i, cpu, nr_cpus = evlist->core.all_cpus->nr; 248 - int total_cpus = cpu__max_cpu(); 248 + int total_cpus = cpu__max_cpu().cpu; 249 249 struct perf_counts_values *counts; 250 250 struct bpf_perf_event_value *values; 251 251 int reading_map_fd, err = 0; ··· 272 272 } 273 273 274 274 for (i = 0; i < nr_cpus; i++) { 275 - cpu = evlist->core.all_cpus->map[i]; 275 + cpu = evlist->core.all_cpus->map[i].cpu; 276 276 277 277 counts = perf_counts(evsel->counts, i, 0); 278 278 counts->val = values[cpu].counter;
+2 -2
tools/perf/util/bpf_ftrace.c
··· 63 63 fd = bpf_map__fd(skel->maps.cpu_filter); 64 64 65 65 for (i = 0; i < ncpus; i++) { 66 - cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i); 66 + cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i).cpu; 67 67 bpf_map_update_elem(fd, &cpu, &val, BPF_ANY); 68 68 } 69 69 } ··· 122 122 int i, fd, err; 123 123 u32 idx; 124 124 u64 *hist; 125 - int ncpus = cpu__max_cpu(); 125 + int ncpus = cpu__max_cpu().cpu; 126 126 127 127 fd = bpf_map__fd(skel->maps.latency); 128 128
+47 -44
tools/perf/util/cpumap.c
··· 13 13 #include <linux/ctype.h> 14 14 #include <linux/zalloc.h> 15 15 16 - static int max_cpu_num; 17 - static int max_present_cpu_num; 16 + static struct perf_cpu max_cpu_num; 17 + static struct perf_cpu max_present_cpu_num; 18 18 static int max_node_num; 19 19 /** 20 20 * The numa node X as read from /sys/devices/system/node/nodeX indexed by the ··· 37 37 * otherwise it would become 65535. 38 38 */ 39 39 if (cpus->cpu[i] == (u16) -1) 40 - map->map[i] = -1; 40 + map->map[i].cpu = -1; 41 41 else 42 - map->map[i] = (int) cpus->cpu[i]; 42 + map->map[i].cpu = (int) cpus->cpu[i]; 43 43 } 44 44 } 45 45 ··· 58 58 int cpu, i = 0; 59 59 60 60 for_each_set_bit(cpu, mask->mask, nbits) 61 - map->map[i++] = cpu; 61 + map->map[i++].cpu = cpu; 62 62 } 63 63 return map; 64 64 ··· 91 91 92 92 cpus->nr = nr; 93 93 for (i = 0; i < nr; i++) 94 - cpus->map[i] = -1; 94 + cpus->map[i].cpu = -1; 95 95 96 96 refcount_set(&cpus->refcnt, 1); 97 97 } ··· 126 126 return sysfs__read_int(path, value); 127 127 } 128 128 129 - int cpu__get_socket_id(int cpu) 129 + int cpu__get_socket_id(struct perf_cpu cpu) 130 130 { 131 - int value, ret = cpu__get_topology_int(cpu, "physical_package_id", &value); 131 + int value, ret = cpu__get_topology_int(cpu.cpu, "physical_package_id", &value); 132 132 return ret ?: value; 133 133 } 134 134 135 - struct aggr_cpu_id aggr_cpu_id__socket(int cpu, void *data __maybe_unused) 135 + struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu cpu, void *data __maybe_unused) 136 136 { 137 137 struct aggr_cpu_id id = aggr_cpu_id__empty(); 138 138 ··· 161 161 aggr_cpu_id_get_t get_id, 162 162 void *data) 163 163 { 164 - int cpu, idx; 164 + int idx; 165 + struct perf_cpu cpu; 165 166 struct cpu_aggr_map *c = cpu_aggr_map__empty_new(cpus->nr); 166 167 167 168 if (!c) ··· 202 201 203 202 } 204 203 205 - int cpu__get_die_id(int cpu) 204 + int cpu__get_die_id(struct perf_cpu cpu) 206 205 { 207 - int value, ret = cpu__get_topology_int(cpu, "die_id", &value); 206 + int value, ret = cpu__get_topology_int(cpu.cpu, "die_id", &value); 208 207 209 208 return ret ?: value; 210 209 } 211 210 212 - struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data) 211 + struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data) 213 212 { 214 213 struct aggr_cpu_id id; 215 214 int die; ··· 232 231 return id; 233 232 } 234 233 235 - int cpu__get_core_id(int cpu) 234 + int cpu__get_core_id(struct perf_cpu cpu) 236 235 { 237 - int value, ret = cpu__get_topology_int(cpu, "core_id", &value); 236 + int value, ret = cpu__get_topology_int(cpu.cpu, "core_id", &value); 238 237 return ret ?: value; 239 238 } 240 239 241 - struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data) 240 + struct aggr_cpu_id aggr_cpu_id__core(struct perf_cpu cpu, void *data) 242 241 { 243 242 struct aggr_cpu_id id; 244 243 int core = cpu__get_core_id(cpu); ··· 257 256 258 257 } 259 258 260 - struct aggr_cpu_id aggr_cpu_id__cpu(int cpu, void *data) 259 + struct aggr_cpu_id aggr_cpu_id__cpu(struct perf_cpu cpu, void *data) 261 260 { 262 261 struct aggr_cpu_id id; 263 262 ··· 271 270 272 271 } 273 272 274 - struct aggr_cpu_id aggr_cpu_id__node(int cpu, void *data __maybe_unused) 273 + struct aggr_cpu_id aggr_cpu_id__node(struct perf_cpu cpu, void *data __maybe_unused) 275 274 { 276 275 struct aggr_cpu_id id = aggr_cpu_id__empty(); 277 276 ··· 319 318 int ret = -1; 320 319 321 320 /* set up default */ 322 - max_cpu_num = 4096; 323 - max_present_cpu_num = 4096; 321 + max_cpu_num.cpu = 4096; 322 + max_present_cpu_num.cpu = 4096; 324 323 325 324 mnt = sysfs__mountpoint(); 326 325 if (!mnt) ··· 333 332 goto out; 334 333 } 335 334 336 - ret = get_max_num(path, &max_cpu_num); 335 + ret = get_max_num(path, &max_cpu_num.cpu); 337 336 if (ret) 338 337 goto out; 339 338 ··· 344 343 goto out; 345 344 } 346 345 347 - ret = get_max_num(path, &max_present_cpu_num); 346 + ret = get_max_num(path, &max_present_cpu_num.cpu); 348 347 349 348 out: 350 349 if (ret) 351 - pr_err("Failed to read max cpus, using default of %d\n", max_cpu_num); 350 + pr_err("Failed to read max cpus, using default of %d\n", max_cpu_num.cpu); 352 351 } 353 352 354 353 /* Determine highest possible node in the system for sparse allocation */ ··· 387 386 return max_node_num; 388 387 } 389 388 390 - int cpu__max_cpu(void) 389 + struct perf_cpu cpu__max_cpu(void) 391 390 { 392 - if (unlikely(!max_cpu_num)) 391 + if (unlikely(!max_cpu_num.cpu)) 393 392 set_max_cpu_num(); 394 393 395 394 return max_cpu_num; 396 395 } 397 396 398 - int cpu__max_present_cpu(void) 397 + struct perf_cpu cpu__max_present_cpu(void) 399 398 { 400 - if (unlikely(!max_present_cpu_num)) 399 + if (unlikely(!max_present_cpu_num.cpu)) 401 400 set_max_cpu_num(); 402 401 403 402 return max_present_cpu_num; 404 403 } 405 404 406 405 407 - int cpu__get_node(int cpu) 406 + int cpu__get_node(struct perf_cpu cpu) 408 407 { 409 408 if (unlikely(cpunode_map == NULL)) { 410 409 pr_debug("cpu_map not initialized\n"); 411 410 return -1; 412 411 } 413 412 414 - return cpunode_map[cpu]; 413 + return cpunode_map[cpu.cpu]; 415 414 } 416 415 417 416 static int init_cpunode_map(void) ··· 421 420 set_max_cpu_num(); 422 421 set_max_node_num(); 423 422 424 - cpunode_map = calloc(max_cpu_num, sizeof(int)); 423 + cpunode_map = calloc(max_cpu_num.cpu, sizeof(int)); 425 424 if (!cpunode_map) { 426 425 pr_err("%s: calloc failed\n", __func__); 427 426 return -1; 428 427 } 429 428 430 - for (i = 0; i < max_cpu_num; i++) 429 + for (i = 0; i < max_cpu_num.cpu; i++) 431 430 cpunode_map[i] = -1; 432 431 433 432 return 0; ··· 488 487 489 488 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size) 490 489 { 491 - int i, cpu, start = -1; 490 + int i, start = -1; 492 491 bool first = true; 493 492 size_t ret = 0; 494 493 495 494 #define COMMA first ? "" : "," 496 495 497 496 for (i = 0; i < map->nr + 1; i++) { 497 + struct perf_cpu cpu = { .cpu = INT_MAX }; 498 498 bool last = i == map->nr; 499 499 500 - cpu = last ? INT_MAX : map->map[i]; 500 + if (!last) 501 + cpu = map->map[i]; 501 502 502 503 if (start == -1) { 503 504 start = i; 504 505 if (last) { 505 506 ret += snprintf(buf + ret, size - ret, 506 507 "%s%d", COMMA, 507 - map->map[i]); 508 + map->map[i].cpu); 508 509 } 509 - } else if (((i - start) != (cpu - map->map[start])) || last) { 510 + } else if (((i - start) != (cpu.cpu - map->map[start].cpu)) || last) { 510 511 int end = i - 1; 511 512 512 513 if (start == end) { 513 514 ret += snprintf(buf + ret, size - ret, 514 515 "%s%d", COMMA, 515 - map->map[start]); 516 + map->map[start].cpu); 516 517 } else { 517 518 ret += snprintf(buf + ret, size - ret, 518 519 "%s%d-%d", COMMA, 519 - map->map[start], map->map[end]); 520 + map->map[start].cpu, map->map[end].cpu); 520 521 } 521 522 first = false; 522 523 start = i; ··· 545 542 int i, cpu; 546 543 char *ptr = buf; 547 544 unsigned char *bitmap; 548 - int last_cpu = perf_cpu_map__cpu(map, map->nr - 1); 545 + struct perf_cpu last_cpu = perf_cpu_map__cpu(map, map->nr - 1); 549 546 550 547 if (buf == NULL) 551 548 return 0; 552 549 553 - bitmap = zalloc(last_cpu / 8 + 1); 550 + bitmap = zalloc(last_cpu.cpu / 8 + 1); 554 551 if (bitmap == NULL) { 555 552 buf[0] = '\0'; 556 553 return 0; 557 554 } 558 555 559 556 for (i = 0; i < map->nr; i++) { 560 - cpu = perf_cpu_map__cpu(map, i); 557 + cpu = perf_cpu_map__cpu(map, i).cpu; 561 558 bitmap[cpu / 8] |= 1 << (cpu % 8); 562 559 } 563 560 564 - for (cpu = last_cpu / 4 * 4; cpu >= 0; cpu -= 4) { 561 + for (cpu = last_cpu.cpu / 4 * 4; cpu >= 0; cpu -= 4) { 565 562 unsigned char bits = bitmap[cpu / 8]; 566 563 567 564 if (cpu % 8) ··· 597 594 a->socket == b->socket && 598 595 a->die == b->die && 599 596 a->core == b->core && 600 - a->cpu == b->cpu; 597 + a->cpu.cpu == b->cpu.cpu; 601 598 } 602 599 603 600 bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a) ··· 607 604 a->socket == -1 && 608 605 a->die == -1 && 609 606 a->core == -1 && 610 - a->cpu == -1; 607 + a->cpu.cpu == -1; 611 608 } 612 609 613 610 struct aggr_cpu_id aggr_cpu_id__empty(void) ··· 618 615 .socket = -1, 619 616 .die = -1, 620 617 .core = -1, 621 - .cpu = -1 618 + .cpu = (struct perf_cpu){ .cpu = -1 }, 622 619 }; 623 620 return ret; 624 621 }
+13 -13
tools/perf/util/cpumap.h
··· 23 23 /** The core id as read from /sys/devices/system/cpu/cpuX/topology/core_id. */ 24 24 int core; 25 25 /** CPU aggregation, note there is one CPU for each SMT thread. */ 26 - int cpu; 26 + struct perf_cpu cpu; 27 27 }; 28 28 29 29 /** A collection of aggr_cpu_id values, the "built" version is sorted and uniqued. */ ··· 48 48 int cpu__setup_cpunode_map(void); 49 49 50 50 int cpu__max_node(void); 51 - int cpu__max_cpu(void); 52 - int cpu__max_present_cpu(void); 51 + struct perf_cpu cpu__max_cpu(void); 52 + struct perf_cpu cpu__max_present_cpu(void); 53 53 /** 54 54 * cpu__get_node - Returns the numa node X as read from 55 55 * /sys/devices/system/node/nodeX for the given CPU. 56 56 */ 57 - int cpu__get_node(int cpu); 57 + int cpu__get_node(struct perf_cpu cpu); 58 58 /** 59 59 * cpu__get_socket_id - Returns the socket number as read from 60 60 * /sys/devices/system/cpu/cpuX/topology/physical_package_id for the given CPU. 61 61 */ 62 - int cpu__get_socket_id(int cpu); 62 + int cpu__get_socket_id(struct perf_cpu cpu); 63 63 /** 64 64 * cpu__get_die_id - Returns the die id as read from 65 65 * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU. 66 66 */ 67 - int cpu__get_die_id(int cpu); 67 + int cpu__get_die_id(struct perf_cpu cpu); 68 68 /** 69 69 * cpu__get_core_id - Returns the core id as read from 70 70 * /sys/devices/system/cpu/cpuX/topology/core_id for the given CPU. 71 71 */ 72 - int cpu__get_core_id(int cpu); 72 + int cpu__get_core_id(struct perf_cpu cpu); 73 73 74 74 /** 75 75 * cpu_aggr_map__empty_new - Create a cpu_aggr_map of size nr with every entry ··· 77 77 */ 78 78 struct cpu_aggr_map *cpu_aggr_map__empty_new(int nr); 79 79 80 - typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(int cpu, void *data); 80 + typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(struct perf_cpu cpu, void *data); 81 81 82 82 /** 83 83 * cpu_aggr_map__new - Create a cpu_aggr_map with an aggr_cpu_id for each cpu in ··· 98 98 * the socket for cpu. The function signature is compatible with 99 99 * aggr_cpu_id_get_t. 100 100 */ 101 - struct aggr_cpu_id aggr_cpu_id__socket(int cpu, void *data); 101 + struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu cpu, void *data); 102 102 /** 103 103 * aggr_cpu_id__die - Create an aggr_cpu_id with the die and socket populated 104 104 * with the die and socket for cpu. The function signature is compatible with 105 105 * aggr_cpu_id_get_t. 106 106 */ 107 - struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data); 107 + struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data); 108 108 /** 109 109 * aggr_cpu_id__core - Create an aggr_cpu_id with the core, die and socket 110 110 * populated with the core, die and socket for cpu. The function signature is 111 111 * compatible with aggr_cpu_id_get_t. 112 112 */ 113 - struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data); 113 + struct aggr_cpu_id aggr_cpu_id__core(struct perf_cpu cpu, void *data); 114 114 /** 115 115 * aggr_cpu_id__core - Create an aggr_cpu_id with the cpu, core, die and socket 116 116 * populated with the cpu, core, die and socket for cpu. The function signature 117 117 * is compatible with aggr_cpu_id_get_t. 118 118 */ 119 - struct aggr_cpu_id aggr_cpu_id__cpu(int cpu, void *data); 119 + struct aggr_cpu_id aggr_cpu_id__cpu(struct perf_cpu cpu, void *data); 120 120 /** 121 121 * aggr_cpu_id__node - Create an aggr_cpu_id with the numa node populated for 122 122 * cpu. The function signature is compatible with aggr_cpu_id_get_t. 123 123 */ 124 - struct aggr_cpu_id aggr_cpu_id__node(int cpu, void *data); 124 + struct aggr_cpu_id aggr_cpu_id__node(struct perf_cpu cpu, void *data); 125 125 126 126 #endif /* __PERF_CPUMAP_H */
+3 -3
tools/perf/util/cputopo.c
··· 187 187 struct perf_cpu_map *map; 188 188 bool has_die = has_die_topology(); 189 189 190 - ncpus = cpu__max_present_cpu(); 190 + ncpus = cpu__max_present_cpu().cpu; 191 191 192 192 /* build online CPU map */ 193 193 map = perf_cpu_map__new(NULL); ··· 218 218 tp->core_cpus_list = addr; 219 219 220 220 for (i = 0; i < nr; i++) { 221 - if (!perf_cpu_map__has(map, i)) 221 + if (!perf_cpu_map__has(map, (struct perf_cpu){ .cpu = i })) 222 222 continue; 223 223 224 224 ret = build_cpu_topology(tp, i); ··· 333 333 tp->nr = nr; 334 334 335 335 for (i = 0; i < nr; i++) { 336 - if (load_numa_node(&tp->nodes[i], node_map->map[i])) { 336 + if (load_numa_node(&tp->nodes[i], node_map->map[i].cpu)) { 337 337 numa_topology__delete(tp); 338 338 tp = NULL; 339 339 break;
+16 -13
tools/perf/util/env.c
··· 285 285 286 286 int perf_env__read_cpu_topology_map(struct perf_env *env) 287 287 { 288 - int cpu, nr_cpus; 288 + int idx, nr_cpus; 289 289 290 290 if (env->cpu != NULL) 291 291 return 0; 292 292 293 293 if (env->nr_cpus_avail == 0) 294 - env->nr_cpus_avail = cpu__max_present_cpu(); 294 + env->nr_cpus_avail = cpu__max_present_cpu().cpu; 295 295 296 296 nr_cpus = env->nr_cpus_avail; 297 297 if (nr_cpus == -1) ··· 301 301 if (env->cpu == NULL) 302 302 return -ENOMEM; 303 303 304 - for (cpu = 0; cpu < nr_cpus; ++cpu) { 305 - env->cpu[cpu].core_id = cpu__get_core_id(cpu); 306 - env->cpu[cpu].socket_id = cpu__get_socket_id(cpu); 307 - env->cpu[cpu].die_id = cpu__get_die_id(cpu); 304 + for (idx = 0; idx < nr_cpus; ++idx) { 305 + struct perf_cpu cpu = { .cpu = idx }; 306 + 307 + env->cpu[idx].core_id = cpu__get_core_id(cpu); 308 + env->cpu[idx].socket_id = cpu__get_socket_id(cpu); 309 + env->cpu[idx].die_id = cpu__get_die_id(cpu); 308 310 } 309 311 310 312 env->nr_cpus_avail = nr_cpus; ··· 383 381 static int perf_env__read_nr_cpus_avail(struct perf_env *env) 384 382 { 385 383 if (env->nr_cpus_avail == 0) 386 - env->nr_cpus_avail = cpu__max_present_cpu(); 384 + env->nr_cpus_avail = cpu__max_present_cpu().cpu; 387 385 388 386 return env->nr_cpus_avail ? 0 : -ENOENT; 389 387 } ··· 489 487 return env->pmu_mappings; 490 488 } 491 489 492 - int perf_env__numa_node(struct perf_env *env, int cpu) 490 + int perf_env__numa_node(struct perf_env *env, struct perf_cpu cpu) 493 491 { 494 492 if (!env->nr_numa_map) { 495 493 struct numa_node *nn; ··· 497 495 498 496 for (i = 0; i < env->nr_numa_nodes; i++) { 499 497 nn = &env->numa_nodes[i]; 500 - nr = max(nr, perf_cpu_map__max(nn->map)); 498 + nr = max(nr, perf_cpu_map__max(nn->map).cpu); 501 499 } 502 500 503 501 nr++; ··· 516 514 env->nr_numa_map = nr; 517 515 518 516 for (i = 0; i < env->nr_numa_nodes; i++) { 519 - int tmp, j; 517 + struct perf_cpu tmp; 518 + int j; 520 519 521 520 nn = &env->numa_nodes[i]; 522 - perf_cpu_map__for_each_cpu(j, tmp, nn->map) 523 - env->numa_map[j] = i; 521 + perf_cpu_map__for_each_cpu(tmp, j, nn->map) 522 + env->numa_map[tmp.cpu] = i; 524 523 } 525 524 } 526 525 527 - return cpu >= 0 && cpu < env->nr_numa_map ? env->numa_map[cpu] : -1; 526 + return cpu.cpu >= 0 && cpu.cpu < env->nr_numa_map ? env->numa_map[cpu.cpu] : -1; 528 527 }
+2 -1
tools/perf/util/env.h
··· 4 4 5 5 #include <linux/types.h> 6 6 #include <linux/rbtree.h> 7 + #include "cpumap.h" 7 8 #include "rwsem.h" 8 9 9 10 struct perf_cpu_map; ··· 171 170 bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node); 172 171 struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id); 173 172 174 - int perf_env__numa_node(struct perf_env *env, int cpu); 173 + int perf_env__numa_node(struct perf_env *env, struct perf_cpu cpu); 175 174 #endif /* __PERF_ENV_H */
+4 -4
tools/perf/util/evlist.c
··· 350 350 .cpu_map_idx = 0, 351 351 .evlist_cpu_map_idx = 0, 352 352 .evlist_cpu_map_nr = perf_cpu_map__nr(evlist->core.all_cpus), 353 - .cpu = -1, 353 + .cpu = (struct perf_cpu){ .cpu = -1}, 354 354 .affinity = affinity, 355 355 }; 356 356 357 357 if (itr.affinity) { 358 358 itr.cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0); 359 - affinity__set(itr.affinity, itr.cpu); 359 + affinity__set(itr.affinity, itr.cpu.cpu); 360 360 itr.cpu_map_idx = perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu); 361 361 /* 362 362 * If this CPU isn't in the evsel's cpu map then advance through ··· 385 385 perf_cpu_map__cpu(evlist_cpu_itr->container->core.all_cpus, 386 386 evlist_cpu_itr->evlist_cpu_map_idx); 387 387 if (evlist_cpu_itr->affinity) 388 - affinity__set(evlist_cpu_itr->affinity, evlist_cpu_itr->cpu); 388 + affinity__set(evlist_cpu_itr->affinity, evlist_cpu_itr->cpu.cpu); 389 389 evlist_cpu_itr->cpu_map_idx = 390 390 perf_cpu_map__idx(evlist_cpu_itr->evsel->core.cpus, 391 391 evlist_cpu_itr->cpu); ··· 819 819 820 820 static int 821 821 perf_evlist__mmap_cb_mmap(struct perf_mmap *_map, struct perf_mmap_param *_mp, 822 - int output, int cpu) 822 + int output, struct perf_cpu cpu) 823 823 { 824 824 struct mmap *map = container_of(_map, struct mmap, core); 825 825 struct mmap_params *mp = container_of(_mp, struct mmap_params, core);
+1 -1
tools/perf/util/evlist.h
··· 344 344 /** The number of CPU map entries in evlist->core.all_cpus. */ 345 345 int evlist_cpu_map_nr; 346 346 /** The current CPU of the iterator. */ 347 - int cpu; 347 + struct perf_cpu cpu; 348 348 /** If present, used to set the affinity when switching between CPUs. */ 349 349 struct affinity *affinity; 350 350 };
+3 -3
tools/perf/util/evsel.c
··· 1594 1594 static int evsel__match_other_cpu(struct evsel *evsel, struct evsel *other, 1595 1595 int cpu_map_idx) 1596 1596 { 1597 - int cpu; 1597 + struct perf_cpu cpu; 1598 1598 1599 1599 cpu = perf_cpu_map__cpu(evsel->core.cpus, cpu_map_idx); 1600 1600 return perf_cpu_map__idx(other->core.cpus, cpu); ··· 2020 2020 test_attr__ready(); 2021 2021 2022 2022 pr_debug2_peo("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx", 2023 - pid, cpus->map[idx], group_fd, evsel->open_flags); 2023 + pid, cpus->map[idx].cpu, group_fd, evsel->open_flags); 2024 2024 2025 - fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[idx], 2025 + fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[idx].cpu, 2026 2026 group_fd, evsel->open_flags); 2027 2027 2028 2028 FD(evsel, idx, thread) = fd;
+1 -1
tools/perf/util/expr.c
··· 410 410 return smt_on() > 0 ? 1.0 : 0.0; 411 411 412 412 if (!strcmp("#num_cpus", literal)) 413 - return cpu__max_present_cpu(); 413 + return cpu__max_present_cpu().cpu; 414 414 415 415 /* 416 416 * Assume that topology strings are consistent, such as CPUs "0-1"
+3 -3
tools/perf/util/header.c
··· 472 472 u32 nrc, nra; 473 473 int ret; 474 474 475 - nrc = cpu__max_present_cpu(); 475 + nrc = cpu__max_present_cpu().cpu; 476 476 477 477 nr = sysconf(_SC_NPROCESSORS_ONLN); 478 478 if (nr < 0) ··· 1163 1163 u32 nr, cpu; 1164 1164 u16 level; 1165 1165 1166 - nr = cpu__max_cpu(); 1166 + nr = cpu__max_cpu().cpu; 1167 1167 1168 1168 for (cpu = 0; cpu < nr; cpu++) { 1169 1169 for (level = 0; level < MAX_CACHE_LVL; level++) { ··· 1195 1195 static int write_cache(struct feat_fd *ff, 1196 1196 struct evlist *evlist __maybe_unused) 1197 1197 { 1198 - u32 max_caches = cpu__max_cpu() * MAX_CACHE_LVL; 1198 + u32 max_caches = cpu__max_cpu().cpu * MAX_CACHE_LVL; 1199 1199 struct cpu_cache_level caches[max_caches]; 1200 1200 u32 cnt = 0, i, version = 1; 1201 1201 int ret;
+10 -9
tools/perf/util/mmap.c
··· 94 94 } 95 95 } 96 96 97 - static int perf_mmap__aio_bind(struct mmap *map, int idx, int cpu, int affinity) 97 + static int perf_mmap__aio_bind(struct mmap *map, int idx, struct perf_cpu cpu, int affinity) 98 98 { 99 99 void *data; 100 100 size_t mmap_len; ··· 138 138 } 139 139 140 140 static int perf_mmap__aio_bind(struct mmap *map __maybe_unused, int idx __maybe_unused, 141 - int cpu __maybe_unused, int affinity __maybe_unused) 141 + struct perf_cpu cpu __maybe_unused, int affinity __maybe_unused) 142 142 { 143 143 return 0; 144 144 } ··· 240 240 241 241 static void build_node_mask(int node, struct mmap_cpu_mask *mask) 242 242 { 243 - int c, cpu, nr_cpus; 243 + int idx, nr_cpus; 244 + struct perf_cpu cpu; 244 245 const struct perf_cpu_map *cpu_map = NULL; 245 246 246 247 cpu_map = cpu_map__online(); ··· 249 248 return; 250 249 251 250 nr_cpus = perf_cpu_map__nr(cpu_map); 252 - for (c = 0; c < nr_cpus; c++) { 253 - cpu = cpu_map->map[c]; /* map c index to online cpu index */ 251 + for (idx = 0; idx < nr_cpus; idx++) { 252 + cpu = cpu_map->map[idx]; /* map c index to online cpu index */ 254 253 if (cpu__get_node(cpu) == node) 255 - set_bit(cpu, mask->bits); 254 + set_bit(cpu.cpu, mask->bits); 256 255 } 257 256 } 258 257 259 258 static int perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params *mp) 260 259 { 261 - map->affinity_mask.nbits = cpu__max_cpu(); 260 + map->affinity_mask.nbits = cpu__max_cpu().cpu; 262 261 map->affinity_mask.bits = bitmap_zalloc(map->affinity_mask.nbits); 263 262 if (!map->affinity_mask.bits) 264 263 return -1; ··· 266 265 if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1) 267 266 build_node_mask(cpu__get_node(map->core.cpu), &map->affinity_mask); 268 267 else if (mp->affinity == PERF_AFFINITY_CPU) 269 - set_bit(map->core.cpu, map->affinity_mask.bits); 268 + set_bit(map->core.cpu.cpu, map->affinity_mask.bits); 270 269 271 270 return 0; 272 271 } 273 272 274 - int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) 273 + int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, struct perf_cpu cpu) 275 274 { 276 275 if (perf_mmap__mmap(&map->core, &mp->core, fd, cpu)) { 277 276 pr_debug2("failed to mmap perf event ring buffer, error %d\n",
+2 -1
tools/perf/util/mmap.h
··· 7 7 #include <linux/types.h> 8 8 #include <linux/ring_buffer.h> 9 9 #include <linux/bitops.h> 10 + #include <perf/cpumap.h> 10 11 #include <stdbool.h> 11 12 #include <pthread.h> // for cpu_set_t 12 13 #ifdef HAVE_AIO_SUPPORT ··· 53 52 struct auxtrace_mmap_params auxtrace_mp; 54 53 }; 55 54 56 - int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu); 55 + int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, struct perf_cpu cpu); 57 56 void mmap__munmap(struct mmap *map); 58 57 59 58 union perf_event *perf_mmap__read_forward(struct mmap *map);
+9 -6
tools/perf/util/perf_api_probe.c
··· 11 11 12 12 typedef void (*setup_probe_fn_t)(struct evsel *evsel); 13 13 14 - static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) 14 + static int perf_do_probe_api(setup_probe_fn_t fn, struct perf_cpu cpu, const char *str) 15 15 { 16 16 struct evlist *evlist; 17 17 struct evsel *evsel; ··· 29 29 evsel = evlist__first(evlist); 30 30 31 31 while (1) { 32 - fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags); 32 + fd = sys_perf_event_open(&evsel->core.attr, pid, cpu.cpu, -1, flags); 33 33 if (fd < 0) { 34 34 if (pid == -1 && errno == EACCES) { 35 35 pid = 0; ··· 43 43 44 44 fn(evsel); 45 45 46 - fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags); 46 + fd = sys_perf_event_open(&evsel->core.attr, pid, cpu.cpu, -1, flags); 47 47 if (fd < 0) { 48 48 if (errno == EINVAL) 49 49 err = -EINVAL; ··· 61 61 { 62 62 const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL}; 63 63 struct perf_cpu_map *cpus; 64 - int cpu, ret, i = 0; 64 + struct perf_cpu cpu; 65 + int ret, i = 0; 65 66 66 67 cpus = perf_cpu_map__new(NULL); 67 68 if (!cpus) ··· 137 136 .exclude_kernel = 1, 138 137 }; 139 138 struct perf_cpu_map *cpus; 140 - int cpu, fd; 139 + struct perf_cpu cpu; 140 + int fd; 141 141 142 142 cpus = perf_cpu_map__new(NULL); 143 143 if (!cpus) 144 144 return false; 145 + 145 146 cpu = cpus->map[0]; 146 147 perf_cpu_map__put(cpus); 147 148 148 - fd = sys_perf_event_open(&attr, -1, cpu, -1, 0); 149 + fd = sys_perf_event_open(&attr, -1, cpu.cpu, -1, 0); 149 150 if (fd < 0) 150 151 return false; 151 152 close(fd);
+2 -2
tools/perf/util/python.c
··· 1057 1057 for (i = 0; i < evlist->core.nr_mmaps; i++) { 1058 1058 struct mmap *md = &evlist->mmap[i]; 1059 1059 1060 - if (md->core.cpu == cpu) 1060 + if (md->core.cpu.cpu == cpu) 1061 1061 return md; 1062 1062 } 1063 1063 ··· 1443 1443 * Dummy, to avoid dragging all the test_attr infrastructure in the python 1444 1444 * binding. 1445 1445 */ 1446 - void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, 1446 + void test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu, 1447 1447 int fd, int group_fd, unsigned long flags) 1448 1448 { 1449 1449 }
+7 -4
tools/perf/util/record.c
··· 106 106 if (opts->group) 107 107 evlist__set_leader(evlist); 108 108 109 - if (evlist->core.cpus->map[0] < 0) 109 + if (evlist->core.cpus->map[0].cpu < 0) 110 110 opts->no_inherit = true; 111 111 112 112 use_comm_exec = perf_can_comm_exec(); ··· 229 229 { 230 230 struct evlist *temp_evlist; 231 231 struct evsel *evsel; 232 - int err, fd, cpu; 232 + int err, fd; 233 + struct perf_cpu cpu = { .cpu = 0 }; 233 234 bool ret = false; 234 235 pid_t pid = -1; 235 236 ··· 247 246 if (!evlist || perf_cpu_map__empty(evlist->core.cpus)) { 248 247 struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); 249 248 250 - cpu = cpus ? cpus->map[0] : 0; 249 + if (cpus) 250 + cpu = cpus->map[0]; 251 + 251 252 perf_cpu_map__put(cpus); 252 253 } else { 253 254 cpu = evlist->core.cpus->map[0]; 254 255 } 255 256 256 257 while (1) { 257 - fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, 258 + fd = sys_perf_event_open(&evsel->core.attr, pid, cpu.cpu, -1, 258 259 perf_event_open_cloexec_flag()); 259 260 if (fd < 0) { 260 261 if (pid == -1 && errno == EACCES) {
+3 -3
tools/perf/util/scripting-engines/trace-event-python.c
··· 1555 1555 } 1556 1556 1557 1557 static void 1558 - process_stat(struct evsel *counter, int cpu, int thread, u64 tstamp, 1558 + process_stat(struct evsel *counter, struct perf_cpu cpu, int thread, u64 tstamp, 1559 1559 struct perf_counts_values *count) 1560 1560 { 1561 1561 PyObject *handler, *t; ··· 1575 1575 return; 1576 1576 } 1577 1577 1578 - PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu)); 1578 + PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu.cpu)); 1579 1579 PyTuple_SetItem(t, n++, _PyLong_FromLong(thread)); 1580 1580 1581 1581 tuple_set_u64(t, n++, tstamp); ··· 1599 1599 int cpu, thread; 1600 1600 1601 1601 if (config->aggr_mode == AGGR_GLOBAL) { 1602 - process_stat(counter, -1, -1, tstamp, 1602 + process_stat(counter, (struct perf_cpu){ .cpu = -1 }, -1, tstamp, 1603 1603 &counter->counts->aggr); 1604 1604 return; 1605 1605 }
+5 -5
tools/perf/util/session.c
··· 2538 2538 } 2539 2539 2540 2540 for (i = 0; i < map->nr; i++) { 2541 - int cpu = map->map[i]; 2541 + struct perf_cpu cpu = map->map[i]; 2542 2542 2543 - if (cpu >= nr_cpus) { 2543 + if (cpu.cpu >= nr_cpus) { 2544 2544 pr_err("Requested CPU %d too large. " 2545 - "Consider raising MAX_NR_CPUS\n", cpu); 2545 + "Consider raising MAX_NR_CPUS\n", cpu.cpu); 2546 2546 goto out_delete_map; 2547 2547 } 2548 2548 2549 - set_bit(cpu, cpu_bitmap); 2549 + set_bit(cpu.cpu, cpu_bitmap); 2550 2550 } 2551 2551 2552 2552 err = 0; ··· 2598 2598 if (!sid) 2599 2599 return -ENOENT; 2600 2600 sid->idx = e->idx; 2601 - sid->cpu = e->cpu; 2601 + sid->cpu.cpu = e->cpu; 2602 2602 sid->tid = e->tid; 2603 2603 } 2604 2604 return 0;
+20 -14
tools/perf/util/stat-display.c
··· 121 121 id.die, 122 122 config->csv_output ? 0 : -3, 123 123 id.core, config->csv_sep); 124 - } else if (id.cpu > -1) { 124 + } else if (id.cpu.cpu > -1) { 125 125 fprintf(config->output, "CPU%*d%s", 126 126 config->csv_output ? 0 : -7, 127 - id.cpu, config->csv_sep); 127 + id.cpu.cpu, config->csv_sep); 128 128 } 129 129 break; 130 130 case AGGR_THREAD: ··· 331 331 struct evsel *evsel, const struct aggr_cpu_id *id) 332 332 { 333 333 struct perf_cpu_map *cpus = evsel__cpus(evsel); 334 - int cpu, idx; 334 + struct perf_cpu cpu; 335 + int idx; 335 336 336 337 if (config->aggr_mode == AGGR_NONE) 337 338 return perf_cpu_map__idx(cpus, id->cpu); ··· 514 513 static void aggr_update_shadow(struct perf_stat_config *config, 515 514 struct evlist *evlist) 516 515 { 517 - int cpu, idx, s; 516 + int idx, s; 517 + struct perf_cpu cpu; 518 518 struct aggr_cpu_id s2, id; 519 519 u64 val; 520 520 struct evsel *counter; ··· 635 633 struct evsel *counter, void *data, bool first) 636 634 { 637 635 struct aggr_data *ad = data; 638 - int idx, cpu; 636 + int idx; 637 + struct perf_cpu cpu; 639 638 struct perf_cpu_map *cpus; 640 639 struct aggr_cpu_id s2; 641 640 ··· 669 666 static void print_counter_aggrdata(struct perf_stat_config *config, 670 667 struct evsel *counter, int s, 671 668 char *prefix, bool metric_only, 672 - bool *first, int cpu) 669 + bool *first, struct perf_cpu cpu) 673 670 { 674 671 struct aggr_data ad; 675 672 FILE *output = config->output; ··· 699 696 fprintf(output, "%s", prefix); 700 697 701 698 uval = val * counter->scale; 702 - if (cpu != -1) 699 + if (cpu.cpu != -1) 703 700 id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); 704 701 705 702 printout(config, id, nr, counter, uval, ··· 734 731 first = true; 735 732 evlist__for_each_entry(evlist, counter) { 736 733 print_counter_aggrdata(config, counter, s, 737 - prefix, metric_only, 738 - &first, /*cpu=*/-1); 734 + prefix, metric_only, 735 + &first, (struct perf_cpu){ .cpu = -1 }); 739 736 } 740 737 if (metric_only) 741 738 fputc('\n', output); ··· 896 893 FILE *output = config->output; 897 894 u64 ena, run, val; 898 895 double uval; 899 - int idx, cpu; 896 + int idx; 897 + struct perf_cpu cpu; 900 898 struct aggr_cpu_id id; 901 899 902 900 perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) { ··· 925 921 struct evlist *evlist, 926 922 char *prefix) 927 923 { 928 - int all_idx, cpu; 924 + int all_idx; 925 + struct perf_cpu cpu; 929 926 930 927 perf_cpu_map__for_each_cpu(cpu, all_idx, evlist->core.cpus) { 931 928 struct evsel *counter; ··· 1216 1211 struct aggr_cpu_id s2, id; 1217 1212 struct perf_cpu_map *cpus; 1218 1213 bool first = true; 1219 - int idx, cpu; 1214 + int idx; 1215 + struct perf_cpu cpu; 1220 1216 1221 1217 cpus = evsel__cpus(counter); 1222 1218 perf_cpu_map__for_each_cpu(cpu, idx, cpus) { ··· 1253 1247 fprintf(output, "%s", prefix); 1254 1248 1255 1249 print_counter_aggrdata(config, counter, s, 1256 - prefix, metric_only, 1257 - &first, /*cpu=*/-1); 1250 + prefix, metric_only, 1251 + &first, (struct perf_cpu){ .cpu = -1 }); 1258 1252 } 1259 1253 1260 1254 if (metric_only)
+1 -1
tools/perf/util/stat.c
··· 297 297 { 298 298 struct hashmap *mask = counter->per_pkg_mask; 299 299 struct perf_cpu_map *cpus = evsel__cpus(counter); 300 - int cpu = perf_cpu_map__cpu(cpus, cpu_map_idx); 300 + struct perf_cpu cpu = perf_cpu_map__cpu(cpus, cpu_map_idx); 301 301 int s, d, ret = 0; 302 302 uint64_t *key; 303 303
+1 -1
tools/perf/util/stat.h
··· 108 108 struct rblist value_list; 109 109 }; 110 110 111 - typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *config, int cpu); 111 + typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *config, struct perf_cpu cpu); 112 112 113 113 struct perf_stat_config { 114 114 enum aggr_mode aggr_mode;
+3 -3
tools/perf/util/svghelper.c
··· 728 728 int i; 729 729 int ret = 0; 730 730 struct perf_cpu_map *m; 731 - int c; 731 + struct perf_cpu c; 732 732 733 733 m = perf_cpu_map__new(s); 734 734 if (!m) ··· 736 736 737 737 for (i = 0; i < m->nr; i++) { 738 738 c = m->map[i]; 739 - if (c >= nr_cpus) { 739 + if (c.cpu >= nr_cpus) { 740 740 ret = -1; 741 741 break; 742 742 } 743 743 744 - set_bit(c, cpumask_bits(b)); 744 + set_bit(c.cpu, cpumask_bits(b)); 745 745 } 746 746 747 747 perf_cpu_map__put(m);
+6 -6
tools/perf/util/synthetic-events.c
··· 1191 1191 cpus->nr = map->nr; 1192 1192 1193 1193 for (i = 0; i < map->nr; i++) 1194 - cpus->cpu[i] = map->map[i]; 1194 + cpus->cpu[i] = map->map[i].cpu; 1195 1195 } 1196 1196 1197 1197 static void synthesize_mask(struct perf_record_record_cpu_map *mask, ··· 1203 1203 mask->long_size = sizeof(long); 1204 1204 1205 1205 for (i = 0; i < map->nr; i++) 1206 - set_bit(map->map[i], mask->mask); 1206 + set_bit(map->map[i].cpu, mask->mask); 1207 1207 } 1208 1208 1209 1209 static size_t cpus_size(struct perf_cpu_map *map) ··· 1219 1219 1220 1220 for (i = 0; i < map->nr; i++) { 1221 1221 /* bit position of the cpu is + 1 */ 1222 - int bit = map->map[i] + 1; 1222 + int bit = map->map[i].cpu + 1; 1223 1223 1224 1224 if (bit > *max) 1225 1225 *max = bit; ··· 1354 1354 } 1355 1355 1356 1356 int perf_event__synthesize_stat(struct perf_tool *tool, 1357 - u32 cpu, u32 thread, u64 id, 1357 + struct perf_cpu cpu, u32 thread, u64 id, 1358 1358 struct perf_counts_values *count, 1359 1359 perf_event__handler_t process, 1360 1360 struct machine *machine) ··· 1366 1366 event.header.misc = 0; 1367 1367 1368 1368 event.id = id; 1369 - event.cpu = cpu; 1369 + event.cpu = cpu.cpu; 1370 1370 event.thread = thread; 1371 1371 event.val = count->val; 1372 1372 event.ena = count->ena; ··· 1763 1763 } 1764 1764 1765 1765 e->idx = sid->idx; 1766 - e->cpu = sid->cpu; 1766 + e->cpu = sid->cpu.cpu; 1767 1767 e->tid = sid->tid; 1768 1768 } 1769 1769 }
+2 -1
tools/perf/util/synthetic-events.h
··· 6 6 #include <sys/types.h> // pid_t 7 7 #include <linux/compiler.h> 8 8 #include <linux/types.h> 9 + #include <perf/cpumap.h> 9 10 10 11 struct auxtrace_record; 11 12 struct dso; ··· 64 63 int perf_event__synthesize_stat_config(struct perf_tool *tool, struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine); 65 64 int perf_event__synthesize_stat_events(struct perf_stat_config *config, struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process, bool attrs); 66 65 int perf_event__synthesize_stat_round(struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine); 67 - int perf_event__synthesize_stat(struct perf_tool *tool, u32 cpu, u32 thread, u64 id, struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine); 66 + int perf_event__synthesize_stat(struct perf_tool *tool, struct perf_cpu cpu, u32 thread, u64 id, struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine); 68 67 int perf_event__synthesize_thread_map2(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine); 69 68 int perf_event__synthesize_thread_map(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine, bool needs_mmap, bool mmap_data); 70 69 int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool needs_mmap, bool mmap_data, unsigned int nr_threads_synthesize);
+4 -1
tools/perf/util/util.h
··· 11 11 #include <stddef.h> 12 12 #include <linux/compiler.h> 13 13 #include <sys/types.h> 14 + #ifndef __cplusplus 15 + #include <internal/cpumap.h> 16 + #endif 14 17 15 18 /* General helper functions */ 16 19 void usage(const char *err) __noreturn; ··· 69 66 void test_attr__ready(void); 70 67 void test_attr__init(void); 71 68 struct perf_event_attr; 72 - void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, 69 + void test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu, 73 70 int fd, int group_fd, unsigned long flags); 74 71 #endif /* GIT_COMPAT_UTIL_H */