diff options
author | Jiri Olsa <jolsa@kernel.org> | 2019-07-21 07:24:30 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-07-29 17:34:45 -0400 |
commit | 9c3516d1b850ea938b074df33e4c86d721c77720 (patch) | |
tree | cb937368ee6d8048f465bcbe27d62709f871212c | |
parent | 1fc632cef4ea137bc45fd0fc4cb902e374064163 (diff) |
libperf: Add perf_cpu_map__new()/perf_cpu_map__read() functions
Moving the following functions from tools/perf:
cpu_map__new()
cpu_map__read()
to libperf with the following names:
perf_cpu_map__new()
perf_cpu_map__read()
Committer notes:
Fixed up this one:
tools/perf/arch/arm/util/cs-etm.c
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20190721112506.12306-44-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
37 files changed, 265 insertions, 227 deletions
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index f5aafdec7f50..c25bc1528b96 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c | |||
@@ -156,7 +156,7 @@ static int cs_etm_set_option(struct auxtrace_record *itr, | |||
156 | { | 156 | { |
157 | int i, err = -EINVAL; | 157 | int i, err = -EINVAL; |
158 | struct perf_cpu_map *event_cpus = evsel->evlist->cpus; | 158 | struct perf_cpu_map *event_cpus = evsel->evlist->cpus; |
159 | struct perf_cpu_map *online_cpus = cpu_map__new(NULL); | 159 | struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); |
160 | 160 | ||
161 | /* Set option of each CPU we have */ | 161 | /* Set option of each CPU we have */ |
162 | for (i = 0; i < cpu__max_cpu(); i++) { | 162 | for (i = 0; i < cpu__max_cpu(); i++) { |
@@ -490,7 +490,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, | |||
490 | int i; | 490 | int i; |
491 | int etmv3 = 0, etmv4 = 0; | 491 | int etmv3 = 0, etmv4 = 0; |
492 | struct perf_cpu_map *event_cpus = evlist->cpus; | 492 | struct perf_cpu_map *event_cpus = evlist->cpus; |
493 | struct perf_cpu_map *online_cpus = cpu_map__new(NULL); | 493 | struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); |
494 | 494 | ||
495 | /* cpu map is not empty, we have specific CPUs to work with */ | 495 | /* cpu map is not empty, we have specific CPUs to work with */ |
496 | if (!cpu_map__empty(event_cpus)) { | 496 | if (!cpu_map__empty(event_cpus)) { |
@@ -637,7 +637,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, | |||
637 | u64 nr_cpu, type; | 637 | u64 nr_cpu, type; |
638 | struct perf_cpu_map *cpu_map; | 638 | struct perf_cpu_map *cpu_map; |
639 | struct perf_cpu_map *event_cpus = session->evlist->cpus; | 639 | struct perf_cpu_map *event_cpus = session->evlist->cpus; |
640 | struct perf_cpu_map *online_cpus = cpu_map__new(NULL); | 640 | struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); |
641 | struct cs_etm_recording *ptr = | 641 | struct cs_etm_recording *ptr = |
642 | container_of(itr, struct cs_etm_recording, itr); | 642 | container_of(itr, struct cs_etm_recording, itr); |
643 | struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; | 643 | struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; |
diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 07129e007eb0..261bdd680651 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <unistd.h> | 5 | #include <unistd.h> |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <sys/prctl.h> | 7 | #include <sys/prctl.h> |
8 | #include <perf/cpumap.h> | ||
8 | 9 | ||
9 | #include "parse-events.h" | 10 | #include "parse-events.h" |
10 | #include "evlist.h" | 11 | #include "evlist.h" |
@@ -65,7 +66,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe | |||
65 | threads = thread_map__new(-1, getpid(), UINT_MAX); | 66 | threads = thread_map__new(-1, getpid(), UINT_MAX); |
66 | CHECK_NOT_NULL__(threads); | 67 | CHECK_NOT_NULL__(threads); |
67 | 68 | ||
68 | cpus = cpu_map__new(NULL); | 69 | cpus = perf_cpu_map__new(NULL); |
69 | CHECK_NOT_NULL__(cpus); | 70 | CHECK_NOT_NULL__(cpus); |
70 | 71 | ||
71 | evlist = evlist__new(); | 72 | evlist = evlist__new(); |
diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c index 1fd724f1d48b..84658d45f349 100644 --- a/tools/perf/bench/epoll-ctl.c +++ b/tools/perf/bench/epoll-ctl.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <sys/resource.h> | 20 | #include <sys/resource.h> |
21 | #include <sys/epoll.h> | 21 | #include <sys/epoll.h> |
22 | #include <sys/eventfd.h> | 22 | #include <sys/eventfd.h> |
23 | #include <perf/cpumap.h> | ||
23 | 24 | ||
24 | #include "../util/stat.h" | 25 | #include "../util/stat.h" |
25 | #include <subcmd/parse-options.h> | 26 | #include <subcmd/parse-options.h> |
@@ -315,7 +316,7 @@ int bench_epoll_ctl(int argc, const char **argv) | |||
315 | act.sa_sigaction = toggle_done; | 316 | act.sa_sigaction = toggle_done; |
316 | sigaction(SIGINT, &act, NULL); | 317 | sigaction(SIGINT, &act, NULL); |
317 | 318 | ||
318 | cpu = cpu_map__new(NULL); | 319 | cpu = perf_cpu_map__new(NULL); |
319 | if (!cpu) | 320 | if (!cpu) |
320 | goto errmem; | 321 | goto errmem; |
321 | 322 | ||
diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index 79a254fff2d1..c27a65639cfb 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c | |||
@@ -75,6 +75,7 @@ | |||
75 | #include <sys/epoll.h> | 75 | #include <sys/epoll.h> |
76 | #include <sys/eventfd.h> | 76 | #include <sys/eventfd.h> |
77 | #include <sys/types.h> | 77 | #include <sys/types.h> |
78 | #include <perf/cpumap.h> | ||
78 | 79 | ||
79 | #include "../util/stat.h" | 80 | #include "../util/stat.h" |
80 | #include <subcmd/parse-options.h> | 81 | #include <subcmd/parse-options.h> |
@@ -429,7 +430,7 @@ int bench_epoll_wait(int argc, const char **argv) | |||
429 | act.sa_sigaction = toggle_done; | 430 | act.sa_sigaction = toggle_done; |
430 | sigaction(SIGINT, &act, NULL); | 431 | sigaction(SIGINT, &act, NULL); |
431 | 432 | ||
432 | cpu = cpu_map__new(NULL); | 433 | cpu = perf_cpu_map__new(NULL); |
433 | if (!cpu) | 434 | if (!cpu) |
434 | goto errmem; | 435 | goto errmem; |
435 | 436 | ||
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index b4fea8e3a368..80e138904c66 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/zalloc.h> | 21 | #include <linux/zalloc.h> |
22 | #include <sys/time.h> | 22 | #include <sys/time.h> |
23 | #include <perf/cpumap.h> | ||
23 | 24 | ||
24 | #include "../util/stat.h" | 25 | #include "../util/stat.h" |
25 | #include <subcmd/parse-options.h> | 26 | #include <subcmd/parse-options.h> |
@@ -132,7 +133,7 @@ int bench_futex_hash(int argc, const char **argv) | |||
132 | exit(EXIT_FAILURE); | 133 | exit(EXIT_FAILURE); |
133 | } | 134 | } |
134 | 135 | ||
135 | cpu = cpu_map__new(NULL); | 136 | cpu = perf_cpu_map__new(NULL); |
136 | if (!cpu) | 137 | if (!cpu) |
137 | goto errmem; | 138 | goto errmem; |
138 | 139 | ||
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 596769924709..c5d6d0abbaa9 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/zalloc.h> | 15 | #include <linux/zalloc.h> |
16 | #include <errno.h> | 16 | #include <errno.h> |
17 | #include <perf/cpumap.h> | ||
17 | #include "bench.h" | 18 | #include "bench.h" |
18 | #include "futex.h" | 19 | #include "futex.h" |
19 | #include "cpumap.h" | 20 | #include "cpumap.h" |
@@ -156,7 +157,7 @@ int bench_futex_lock_pi(int argc, const char **argv) | |||
156 | if (argc) | 157 | if (argc) |
157 | goto err; | 158 | goto err; |
158 | 159 | ||
159 | cpu = cpu_map__new(NULL); | 160 | cpu = perf_cpu_map__new(NULL); |
160 | if (!cpu) | 161 | if (!cpu) |
161 | err(EXIT_FAILURE, "calloc"); | 162 | err(EXIT_FAILURE, "calloc"); |
162 | 163 | ||
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 1fd32a4f9c14..75d3418c1a88 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/time64.h> | 21 | #include <linux/time64.h> |
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | #include <perf/cpumap.h> | ||
23 | #include "bench.h" | 24 | #include "bench.h" |
24 | #include "futex.h" | 25 | #include "futex.h" |
25 | #include "cpumap.h" | 26 | #include "cpumap.h" |
@@ -123,7 +124,7 @@ int bench_futex_requeue(int argc, const char **argv) | |||
123 | if (argc) | 124 | if (argc) |
124 | goto err; | 125 | goto err; |
125 | 126 | ||
126 | cpu = cpu_map__new(NULL); | 127 | cpu = perf_cpu_map__new(NULL); |
127 | if (!cpu) | 128 | if (!cpu) |
128 | err(EXIT_FAILURE, "cpu_map__new"); | 129 | err(EXIT_FAILURE, "cpu_map__new"); |
129 | 130 | ||
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 884c73e5bd1b..163fe16c275a 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c | |||
@@ -237,7 +237,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) | |||
237 | act.sa_sigaction = toggle_done; | 237 | act.sa_sigaction = toggle_done; |
238 | sigaction(SIGINT, &act, NULL); | 238 | sigaction(SIGINT, &act, NULL); |
239 | 239 | ||
240 | cpu = cpu_map__new(NULL); | 240 | cpu = perf_cpu_map__new(NULL); |
241 | if (!cpu) | 241 | if (!cpu) |
242 | err(EXIT_FAILURE, "calloc"); | 242 | err(EXIT_FAILURE, "calloc"); |
243 | 243 | ||
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 2288fa8412ff..77dcdc13618a 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/time64.h> | 21 | #include <linux/time64.h> |
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | #include <perf/cpumap.h> | ||
23 | #include "bench.h" | 24 | #include "bench.h" |
24 | #include "futex.h" | 25 | #include "futex.h" |
25 | #include "cpumap.h" | 26 | #include "cpumap.h" |
@@ -131,7 +132,7 @@ int bench_futex_wake(int argc, const char **argv) | |||
131 | exit(EXIT_FAILURE); | 132 | exit(EXIT_FAILURE); |
132 | } | 133 | } |
133 | 134 | ||
134 | cpu = cpu_map__new(NULL); | 135 | cpu = perf_cpu_map__new(NULL); |
135 | if (!cpu) | 136 | if (!cpu) |
136 | err(EXIT_FAILURE, "calloc"); | 137 | err(EXIT_FAILURE, "calloc"); |
137 | 138 | ||
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 6943352b8d94..77989254fdd8 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c | |||
@@ -202,7 +202,7 @@ static int set_tracing_cpu(struct perf_ftrace *ftrace) | |||
202 | 202 | ||
203 | static int reset_tracing_cpu(void) | 203 | static int reset_tracing_cpu(void) |
204 | { | 204 | { |
205 | struct perf_cpu_map *cpumap = cpu_map__new(NULL); | 205 | struct perf_cpu_map *cpumap = perf_cpu_map__new(NULL); |
206 | int ret; | 206 | int ret; |
207 | 207 | ||
208 | ret = set_tracing_cpumask(cpumap); | 208 | ret = set_tracing_cpumask(cpumap); |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 897d11c8ca2e..0d6b4c3b1a51 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -3183,7 +3183,7 @@ static int setup_map_cpus(struct perf_sched *sched) | |||
3183 | if (!sched->map.cpus_str) | 3183 | if (!sched->map.cpus_str) |
3184 | return 0; | 3184 | return 0; |
3185 | 3185 | ||
3186 | map = cpu_map__new(sched->map.cpus_str); | 3186 | map = perf_cpu_map__new(sched->map.cpus_str); |
3187 | if (!map) { | 3187 | if (!map) { |
3188 | pr_err("failed to get cpus map from %s\n", sched->map.cpus_str); | 3188 | pr_err("failed to get cpus map from %s\n", sched->map.cpus_str); |
3189 | return -1; | 3189 | return -1; |
@@ -3217,7 +3217,7 @@ static int setup_color_cpus(struct perf_sched *sched) | |||
3217 | if (!sched->map.color_cpus_str) | 3217 | if (!sched->map.color_cpus_str) |
3218 | return 0; | 3218 | return 0; |
3219 | 3219 | ||
3220 | map = cpu_map__new(sched->map.color_cpus_str); | 3220 | map = perf_cpu_map__new(sched->map.color_cpus_str); |
3221 | if (!map) { | 3221 | if (!map) { |
3222 | pr_err("failed to get thread map from %s\n", sched->map.color_cpus_str); | 3222 | pr_err("failed to get thread map from %s\n", sched->map.color_cpus_str); |
3223 | return -1; | 3223 | return -1; |
diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index f3cfb4c71106..a5d4f7ff7174 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c | |||
@@ -5,6 +5,10 @@ | |||
5 | #include <internal/cpumap.h> | 5 | #include <internal/cpumap.h> |
6 | #include <asm/bug.h> | 6 | #include <asm/bug.h> |
7 | #include <stdio.h> | 7 | #include <stdio.h> |
8 | #include <string.h> | ||
9 | #include <unistd.h> | ||
10 | #include <ctype.h> | ||
11 | #include <limits.h> | ||
8 | 12 | ||
9 | struct perf_cpu_map *perf_cpu_map__dummy_new(void) | 13 | struct perf_cpu_map *perf_cpu_map__dummy_new(void) |
10 | { | 14 | { |
@@ -40,3 +44,183 @@ void perf_cpu_map__put(struct perf_cpu_map *map) | |||
40 | if (map && refcount_dec_and_test(&map->refcnt)) | 44 | if (map && refcount_dec_and_test(&map->refcnt)) |
41 | cpu_map__delete(map); | 45 | cpu_map__delete(map); |
42 | } | 46 | } |
47 | |||
48 | static struct perf_cpu_map *cpu_map__default_new(void) | ||
49 | { | ||
50 | struct perf_cpu_map *cpus; | ||
51 | int nr_cpus; | ||
52 | |||
53 | nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); | ||
54 | if (nr_cpus < 0) | ||
55 | return NULL; | ||
56 | |||
57 | cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int)); | ||
58 | if (cpus != NULL) { | ||
59 | int i; | ||
60 | |||
61 | for (i = 0; i < nr_cpus; ++i) | ||
62 | cpus->map[i] = i; | ||
63 | |||
64 | cpus->nr = nr_cpus; | ||
65 | refcount_set(&cpus->refcnt, 1); | ||
66 | } | ||
67 | |||
68 | return cpus; | ||
69 | } | ||
70 | |||
71 | static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) | ||
72 | { | ||
73 | size_t payload_size = nr_cpus * sizeof(int); | ||
74 | struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); | ||
75 | |||
76 | if (cpus != NULL) { | ||
77 | cpus->nr = nr_cpus; | ||
78 | memcpy(cpus->map, tmp_cpus, payload_size); | ||
79 | refcount_set(&cpus->refcnt, 1); | ||
80 | } | ||
81 | |||
82 | return cpus; | ||
83 | } | ||
84 | |||
85 | struct perf_cpu_map *perf_cpu_map__read(FILE *file) | ||
86 | { | ||
87 | struct perf_cpu_map *cpus = NULL; | ||
88 | int nr_cpus = 0; | ||
89 | int *tmp_cpus = NULL, *tmp; | ||
90 | int max_entries = 0; | ||
91 | int n, cpu, prev; | ||
92 | char sep; | ||
93 | |||
94 | sep = 0; | ||
95 | prev = -1; | ||
96 | for (;;) { | ||
97 | n = fscanf(file, "%u%c", &cpu, &sep); | ||
98 | if (n <= 0) | ||
99 | break; | ||
100 | if (prev >= 0) { | ||
101 | int new_max = nr_cpus + cpu - prev - 1; | ||
102 | |||
103 | if (new_max >= max_entries) { | ||
104 | max_entries = new_max + MAX_NR_CPUS / 2; | ||
105 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
106 | if (tmp == NULL) | ||
107 | goto out_free_tmp; | ||
108 | tmp_cpus = tmp; | ||
109 | } | ||
110 | |||
111 | while (++prev < cpu) | ||
112 | tmp_cpus[nr_cpus++] = prev; | ||
113 | } | ||
114 | if (nr_cpus == max_entries) { | ||
115 | max_entries += MAX_NR_CPUS; | ||
116 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
117 | if (tmp == NULL) | ||
118 | goto out_free_tmp; | ||
119 | tmp_cpus = tmp; | ||
120 | } | ||
121 | |||
122 | tmp_cpus[nr_cpus++] = cpu; | ||
123 | if (n == 2 && sep == '-') | ||
124 | prev = cpu; | ||
125 | else | ||
126 | prev = -1; | ||
127 | if (n == 1 || sep == '\n') | ||
128 | break; | ||
129 | } | ||
130 | |||
131 | if (nr_cpus > 0) | ||
132 | cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); | ||
133 | else | ||
134 | cpus = cpu_map__default_new(); | ||
135 | out_free_tmp: | ||
136 | free(tmp_cpus); | ||
137 | return cpus; | ||
138 | } | ||
139 | |||
140 | static struct perf_cpu_map *cpu_map__read_all_cpu_map(void) | ||
141 | { | ||
142 | struct perf_cpu_map *cpus = NULL; | ||
143 | FILE *onlnf; | ||
144 | |||
145 | onlnf = fopen("/sys/devices/system/cpu/online", "r"); | ||
146 | if (!onlnf) | ||
147 | return cpu_map__default_new(); | ||
148 | |||
149 | cpus = perf_cpu_map__read(onlnf); | ||
150 | fclose(onlnf); | ||
151 | return cpus; | ||
152 | } | ||
153 | |||
154 | struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) | ||
155 | { | ||
156 | struct perf_cpu_map *cpus = NULL; | ||
157 | unsigned long start_cpu, end_cpu = 0; | ||
158 | char *p = NULL; | ||
159 | int i, nr_cpus = 0; | ||
160 | int *tmp_cpus = NULL, *tmp; | ||
161 | int max_entries = 0; | ||
162 | |||
163 | if (!cpu_list) | ||
164 | return cpu_map__read_all_cpu_map(); | ||
165 | |||
166 | /* | ||
167 | * must handle the case of empty cpumap to cover | ||
168 | * TOPOLOGY header for NUMA nodes with no CPU | ||
169 | * ( e.g., because of CPU hotplug) | ||
170 | */ | ||
171 | if (!isdigit(*cpu_list) && *cpu_list != '\0') | ||
172 | goto out; | ||
173 | |||
174 | while (isdigit(*cpu_list)) { | ||
175 | p = NULL; | ||
176 | start_cpu = strtoul(cpu_list, &p, 0); | ||
177 | if (start_cpu >= INT_MAX | ||
178 | || (*p != '\0' && *p != ',' && *p != '-')) | ||
179 | goto invalid; | ||
180 | |||
181 | if (*p == '-') { | ||
182 | cpu_list = ++p; | ||
183 | p = NULL; | ||
184 | end_cpu = strtoul(cpu_list, &p, 0); | ||
185 | |||
186 | if (end_cpu >= INT_MAX || (*p != '\0' && *p != ',')) | ||
187 | goto invalid; | ||
188 | |||
189 | if (end_cpu < start_cpu) | ||
190 | goto invalid; | ||
191 | } else { | ||
192 | end_cpu = start_cpu; | ||
193 | } | ||
194 | |||
195 | for (; start_cpu <= end_cpu; start_cpu++) { | ||
196 | /* check for duplicates */ | ||
197 | for (i = 0; i < nr_cpus; i++) | ||
198 | if (tmp_cpus[i] == (int)start_cpu) | ||
199 | goto invalid; | ||
200 | |||
201 | if (nr_cpus == max_entries) { | ||
202 | max_entries += MAX_NR_CPUS; | ||
203 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
204 | if (tmp == NULL) | ||
205 | goto invalid; | ||
206 | tmp_cpus = tmp; | ||
207 | } | ||
208 | tmp_cpus[nr_cpus++] = (int)start_cpu; | ||
209 | } | ||
210 | if (*p) | ||
211 | ++p; | ||
212 | |||
213 | cpu_list = p; | ||
214 | } | ||
215 | |||
216 | if (nr_cpus > 0) | ||
217 | cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); | ||
218 | else if (*cpu_list != '\0') | ||
219 | cpus = cpu_map__default_new(); | ||
220 | else | ||
221 | cpus = perf_cpu_map__dummy_new(); | ||
222 | invalid: | ||
223 | free(tmp_cpus); | ||
224 | out: | ||
225 | return cpus; | ||
226 | } | ||
diff --git a/tools/perf/lib/include/internal/cpumap.h b/tools/perf/lib/include/internal/cpumap.h index 53ce95374b05..3306319f7df8 100644 --- a/tools/perf/lib/include/internal/cpumap.h +++ b/tools/perf/lib/include/internal/cpumap.h | |||
@@ -10,4 +10,8 @@ struct perf_cpu_map { | |||
10 | int map[]; | 10 | int map[]; |
11 | }; | 11 | }; |
12 | 12 | ||
13 | #ifndef MAX_NR_CPUS | ||
14 | #define MAX_NR_CPUS 2048 | ||
15 | #endif | ||
16 | |||
13 | #endif /* __LIBPERF_INTERNAL_CPUMAP_H */ | 17 | #endif /* __LIBPERF_INTERNAL_CPUMAP_H */ |
diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h index e16c2515a499..b4a9283a5dfa 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/perf/lib/include/perf/cpumap.h | |||
@@ -3,10 +3,13 @@ | |||
3 | #define __LIBPERF_CPUMAP_H | 3 | #define __LIBPERF_CPUMAP_H |
4 | 4 | ||
5 | #include <perf/core.h> | 5 | #include <perf/core.h> |
6 | #include <stdio.h> | ||
6 | 7 | ||
7 | struct perf_cpu_map; | 8 | struct perf_cpu_map; |
8 | 9 | ||
9 | LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); | 10 | LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); |
11 | LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); | ||
12 | LIBPERF_API struct perf_cpu_map *perf_cpu_map__read(FILE *file); | ||
10 | LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); | 13 | LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); |
11 | LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); | 14 | LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); |
12 | 15 | ||
diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 168339f89a2e..e38473a8f32f 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map | |||
@@ -4,6 +4,8 @@ LIBPERF_0.0.1 { | |||
4 | perf_cpu_map__dummy_new; | 4 | perf_cpu_map__dummy_new; |
5 | perf_cpu_map__get; | 5 | perf_cpu_map__get; |
6 | perf_cpu_map__put; | 6 | perf_cpu_map__put; |
7 | perf_cpu_map__new; | ||
8 | perf_cpu_map__read; | ||
7 | perf_thread_map__new_dummy; | 9 | perf_thread_map__new_dummy; |
8 | perf_thread_map__set_pid; | 10 | perf_thread_map__set_pid; |
9 | perf_thread_map__comm; | 11 | perf_thread_map__comm; |
diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 95304d29092e..db2aadff3708 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c | |||
@@ -1,6 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | #include <linux/bitmap.h> | 3 | #include <linux/bitmap.h> |
4 | #include <perf/cpumap.h> | ||
4 | #include "tests.h" | 5 | #include "tests.h" |
5 | #include "cpumap.h" | 6 | #include "cpumap.h" |
6 | #include "debug.h" | 7 | #include "debug.h" |
@@ -9,7 +10,7 @@ | |||
9 | 10 | ||
10 | static unsigned long *get_bitmap(const char *str, int nbits) | 11 | static unsigned long *get_bitmap(const char *str, int nbits) |
11 | { | 12 | { |
12 | struct perf_cpu_map *map = cpu_map__new(str); | 13 | struct perf_cpu_map *map = perf_cpu_map__new(str); |
13 | unsigned long *bm = NULL; | 14 | unsigned long *bm = NULL; |
14 | int i; | 15 | int i; |
15 | 16 | ||
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 131bbeec62d2..bfaf22c2023c 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | #include <sys/param.h> | 10 | #include <sys/param.h> |
11 | #include <perf/cpumap.h> | ||
11 | 12 | ||
12 | #include "parse-events.h" | 13 | #include "parse-events.h" |
13 | #include "evlist.h" | 14 | #include "evlist.h" |
@@ -613,9 +614,9 @@ static int do_test_code_reading(bool try_kcore) | |||
613 | goto out_put; | 614 | goto out_put; |
614 | } | 615 | } |
615 | 616 | ||
616 | cpus = cpu_map__new(NULL); | 617 | cpus = perf_cpu_map__new(NULL); |
617 | if (!cpus) { | 618 | if (!cpus) { |
618 | pr_debug("cpu_map__new failed\n"); | 619 | pr_debug("perf_cpu_map__new failed\n"); |
619 | goto out_put; | 620 | goto out_put; |
620 | } | 621 | } |
621 | 622 | ||
diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 6c921087b0fe..b71fe09a8087 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include "event.h" | 5 | #include "event.h" |
6 | #include <string.h> | 6 | #include <string.h> |
7 | #include <linux/bitops.h> | 7 | #include <linux/bitops.h> |
8 | #include <perf/cpumap.h> | ||
8 | #include "debug.h" | 9 | #include "debug.h" |
9 | 10 | ||
10 | struct machine; | 11 | struct machine; |
@@ -78,7 +79,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may | |||
78 | struct perf_cpu_map *cpus; | 79 | struct perf_cpu_map *cpus; |
79 | 80 | ||
80 | /* This one is better stores in mask. */ | 81 | /* This one is better stores in mask. */ |
81 | cpus = cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19"); | 82 | cpus = perf_cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19"); |
82 | 83 | ||
83 | TEST_ASSERT_VAL("failed to synthesize map", | 84 | TEST_ASSERT_VAL("failed to synthesize map", |
84 | !perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL)); | 85 | !perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL)); |
@@ -86,7 +87,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may | |||
86 | perf_cpu_map__put(cpus); | 87 | perf_cpu_map__put(cpus); |
87 | 88 | ||
88 | /* This one is better stores in cpu values. */ | 89 | /* This one is better stores in cpu values. */ |
89 | cpus = cpu_map__new("1,256"); | 90 | cpus = perf_cpu_map__new("1,256"); |
90 | 91 | ||
91 | TEST_ASSERT_VAL("failed to synthesize map", | 92 | TEST_ASSERT_VAL("failed to synthesize map", |
92 | !perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL)); | 93 | !perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL)); |
@@ -97,7 +98,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may | |||
97 | 98 | ||
98 | static int cpu_map_print(const char *str) | 99 | static int cpu_map_print(const char *str) |
99 | { | 100 | { |
100 | struct perf_cpu_map *map = cpu_map__new(str); | 101 | struct perf_cpu_map *map = perf_cpu_map__new(str); |
101 | char buf[100]; | 102 | char buf[100]; |
102 | 103 | ||
103 | if (!map) | 104 | if (!map) |
diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 165534f62036..00adba86403b 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <inttypes.h> | 4 | #include <inttypes.h> |
5 | #include <string.h> | 5 | #include <string.h> |
6 | #include <sys/wait.h> | 6 | #include <sys/wait.h> |
7 | #include <perf/cpumap.h> | ||
7 | #include "tests.h" | 8 | #include "tests.h" |
8 | #include "evlist.h" | 9 | #include "evlist.h" |
9 | #include "evsel.h" | 10 | #include "evsel.h" |
@@ -115,9 +116,9 @@ static int attach__cpu_disabled(struct evlist *evlist) | |||
115 | 116 | ||
116 | pr_debug("attaching to CPU 0 as enabled\n"); | 117 | pr_debug("attaching to CPU 0 as enabled\n"); |
117 | 118 | ||
118 | cpus = cpu_map__new("0"); | 119 | cpus = perf_cpu_map__new("0"); |
119 | if (cpus == NULL) { | 120 | if (cpus == NULL) { |
120 | pr_debug("failed to call cpu_map__new\n"); | 121 | pr_debug("failed to call perf_cpu_map__new\n"); |
121 | return -1; | 122 | return -1; |
122 | } | 123 | } |
123 | 124 | ||
@@ -144,9 +145,9 @@ static int attach__cpu_enabled(struct evlist *evlist) | |||
144 | 145 | ||
145 | pr_debug("attaching to CPU 0 as enabled\n"); | 146 | pr_debug("attaching to CPU 0 as enabled\n"); |
146 | 147 | ||
147 | cpus = cpu_map__new("0"); | 148 | cpus = perf_cpu_map__new("0"); |
148 | if (cpus == NULL) { | 149 | if (cpus == NULL) { |
149 | pr_debug("failed to call cpu_map__new\n"); | 150 | pr_debug("failed to call perf_cpu_map__new\n"); |
150 | return -1; | 151 | return -1; |
151 | } | 152 | } |
152 | 153 | ||
diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 415d12e96834..2bc5145284c0 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c | |||
@@ -1,5 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | #include <perf/cpumap.h> | ||
3 | #include "evlist.h" | 4 | #include "evlist.h" |
4 | #include "evsel.h" | 5 | #include "evsel.h" |
5 | #include "machine.h" | 6 | #include "machine.h" |
@@ -108,7 +109,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu | |||
108 | TEST_ASSERT_VAL("failed to synthesize attr update name", | 109 | TEST_ASSERT_VAL("failed to synthesize attr update name", |
109 | !perf_event__synthesize_event_update_name(&tmp.tool, evsel, process_event_name)); | 110 | !perf_event__synthesize_event_update_name(&tmp.tool, evsel, process_event_name)); |
110 | 111 | ||
111 | evsel->own_cpus = cpu_map__new("1,2,3"); | 112 | evsel->own_cpus = perf_cpu_map__new("1,2,3"); |
112 | 113 | ||
113 | TEST_ASSERT_VAL("failed to synthesize attr update cpus", | 114 | TEST_ASSERT_VAL("failed to synthesize attr update cpus", |
114 | !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus)); | 115 | !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus)); |
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 4fc7b3b4e153..46478ba1ed16 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/types.h> | 2 | #include <linux/types.h> |
3 | #include <unistd.h> | 3 | #include <unistd.h> |
4 | #include <sys/prctl.h> | 4 | #include <sys/prctl.h> |
5 | #include <perf/cpumap.h> | ||
5 | 6 | ||
6 | #include "parse-events.h" | 7 | #include "parse-events.h" |
7 | #include "evlist.h" | 8 | #include "evlist.h" |
@@ -75,7 +76,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un | |||
75 | threads = thread_map__new(-1, getpid(), UINT_MAX); | 76 | threads = thread_map__new(-1, getpid(), UINT_MAX); |
76 | CHECK_NOT_NULL__(threads); | 77 | CHECK_NOT_NULL__(threads); |
77 | 78 | ||
78 | cpus = cpu_map__new(NULL); | 79 | cpus = perf_cpu_map__new(NULL); |
79 | CHECK_NOT_NULL__(cpus); | 80 | CHECK_NOT_NULL__(cpus); |
80 | 81 | ||
81 | evlist = evlist__new(); | 82 | evlist = evlist__new(); |
diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 6fe2c1e7918b..5ec193f7968d 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | #include <linux/bitmap.h> | 3 | #include <linux/bitmap.h> |
4 | #include <linux/zalloc.h> | 4 | #include <linux/zalloc.h> |
5 | #include <perf/cpumap.h> | ||
5 | #include "cpumap.h" | 6 | #include "cpumap.h" |
6 | #include "mem2node.h" | 7 | #include "mem2node.h" |
7 | #include "tests.h" | 8 | #include "tests.h" |
@@ -19,7 +20,7 @@ static struct node { | |||
19 | 20 | ||
20 | static unsigned long *get_bitmap(const char *str, int nbits) | 21 | static unsigned long *get_bitmap(const char *str, int nbits) |
21 | { | 22 | { |
22 | struct perf_cpu_map *map = cpu_map__new(str); | 23 | struct perf_cpu_map *map = perf_cpu_map__new(str); |
23 | unsigned long *bm = NULL; | 24 | unsigned long *bm = NULL; |
24 | int i; | 25 | int i; |
25 | 26 | ||
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 9d8eb43b12cb..aa792aebd7f0 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <inttypes.h> | 3 | #include <inttypes.h> |
4 | /* For the CLR_() macros */ | 4 | /* For the CLR_() macros */ |
5 | #include <pthread.h> | 5 | #include <pthread.h> |
6 | #include <perf/cpumap.h> | ||
6 | 7 | ||
7 | #include "evlist.h" | 8 | #include "evlist.h" |
8 | #include "evsel.h" | 9 | #include "evsel.h" |
@@ -46,7 +47,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse | |||
46 | return -1; | 47 | return -1; |
47 | } | 48 | } |
48 | 49 | ||
49 | cpus = cpu_map__new(NULL); | 50 | cpus = perf_cpu_map__new(NULL); |
50 | if (cpus == NULL) { | 51 | if (cpus == NULL) { |
51 | pr_debug("cpu_map__new\n"); | 52 | pr_debug("cpu_map__new\n"); |
52 | goto out_free_threads; | 53 | goto out_free_threads; |
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 674b0fa035ec..d161b1a78703 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c | |||
@@ -33,7 +33,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int | |||
33 | return -1; | 33 | return -1; |
34 | } | 34 | } |
35 | 35 | ||
36 | cpus = cpu_map__new(NULL); | 36 | cpus = perf_cpu_map__new(NULL); |
37 | if (cpus == NULL) { | 37 | if (cpus == NULL) { |
38 | pr_debug("cpu_map__new\n"); | 38 | pr_debug("cpu_map__new\n"); |
39 | goto out_thread_map_delete; | 39 | goto out_thread_map_delete; |
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index dd07acced4af..9e0bbea15005 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <time.h> | 5 | #include <time.h> |
6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
7 | #include <linux/zalloc.h> | 7 | #include <linux/zalloc.h> |
8 | #include <perf/cpumap.h> | ||
8 | 9 | ||
9 | #include "parse-events.h" | 10 | #include "parse-events.h" |
10 | #include "evlist.h" | 11 | #include "evlist.h" |
@@ -341,9 +342,9 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ | |||
341 | goto out_err; | 342 | goto out_err; |
342 | } | 343 | } |
343 | 344 | ||
344 | cpus = cpu_map__new(NULL); | 345 | cpus = perf_cpu_map__new(NULL); |
345 | if (!cpus) { | 346 | if (!cpus) { |
346 | pr_debug("cpu_map__new failed!\n"); | 347 | pr_debug("perf_cpu_map__new failed!\n"); |
347 | goto out_err; | 348 | goto out_err; |
348 | } | 349 | } |
349 | 350 | ||
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 1b57ded58d59..a4f9f5182b47 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <string.h> | 2 | #include <string.h> |
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <perf/cpumap.h> | ||
5 | #include "tests.h" | 6 | #include "tests.h" |
6 | #include "util.h" | 7 | #include "util.h" |
7 | #include "session.h" | 8 | #include "session.h" |
@@ -126,7 +127,7 @@ int test__session_topology(struct test *test __maybe_unused, int subtest __maybe | |||
126 | if (session_write_header(path)) | 127 | if (session_write_header(path)) |
127 | goto free_path; | 128 | goto free_path; |
128 | 129 | ||
129 | map = cpu_map__new(NULL); | 130 | map = perf_cpu_map__new(NULL); |
130 | if (map == NULL) { | 131 | if (map == NULL) { |
131 | pr_debug("failed to get system cpumap\n"); | 132 | pr_debug("failed to get system cpumap\n"); |
132 | goto free_path; | 133 | goto free_path; |
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 44082e5eabde..71d4d7b35a57 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c | |||
@@ -17,185 +17,6 @@ static int max_present_cpu_num; | |||
17 | static int max_node_num; | 17 | static int max_node_num; |
18 | static int *cpunode_map; | 18 | static int *cpunode_map; |
19 | 19 | ||
20 | static struct perf_cpu_map *cpu_map__default_new(void) | ||
21 | { | ||
22 | struct perf_cpu_map *cpus; | ||
23 | int nr_cpus; | ||
24 | |||
25 | nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); | ||
26 | if (nr_cpus < 0) | ||
27 | return NULL; | ||
28 | |||
29 | cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int)); | ||
30 | if (cpus != NULL) { | ||
31 | int i; | ||
32 | for (i = 0; i < nr_cpus; ++i) | ||
33 | cpus->map[i] = i; | ||
34 | |||
35 | cpus->nr = nr_cpus; | ||
36 | refcount_set(&cpus->refcnt, 1); | ||
37 | } | ||
38 | |||
39 | return cpus; | ||
40 | } | ||
41 | |||
42 | static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) | ||
43 | { | ||
44 | size_t payload_size = nr_cpus * sizeof(int); | ||
45 | struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); | ||
46 | |||
47 | if (cpus != NULL) { | ||
48 | cpus->nr = nr_cpus; | ||
49 | memcpy(cpus->map, tmp_cpus, payload_size); | ||
50 | refcount_set(&cpus->refcnt, 1); | ||
51 | } | ||
52 | |||
53 | return cpus; | ||
54 | } | ||
55 | |||
56 | struct perf_cpu_map *cpu_map__read(FILE *file) | ||
57 | { | ||
58 | struct perf_cpu_map *cpus = NULL; | ||
59 | int nr_cpus = 0; | ||
60 | int *tmp_cpus = NULL, *tmp; | ||
61 | int max_entries = 0; | ||
62 | int n, cpu, prev; | ||
63 | char sep; | ||
64 | |||
65 | sep = 0; | ||
66 | prev = -1; | ||
67 | for (;;) { | ||
68 | n = fscanf(file, "%u%c", &cpu, &sep); | ||
69 | if (n <= 0) | ||
70 | break; | ||
71 | if (prev >= 0) { | ||
72 | int new_max = nr_cpus + cpu - prev - 1; | ||
73 | |||
74 | if (new_max >= max_entries) { | ||
75 | max_entries = new_max + MAX_NR_CPUS / 2; | ||
76 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
77 | if (tmp == NULL) | ||
78 | goto out_free_tmp; | ||
79 | tmp_cpus = tmp; | ||
80 | } | ||
81 | |||
82 | while (++prev < cpu) | ||
83 | tmp_cpus[nr_cpus++] = prev; | ||
84 | } | ||
85 | if (nr_cpus == max_entries) { | ||
86 | max_entries += MAX_NR_CPUS; | ||
87 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
88 | if (tmp == NULL) | ||
89 | goto out_free_tmp; | ||
90 | tmp_cpus = tmp; | ||
91 | } | ||
92 | |||
93 | tmp_cpus[nr_cpus++] = cpu; | ||
94 | if (n == 2 && sep == '-') | ||
95 | prev = cpu; | ||
96 | else | ||
97 | prev = -1; | ||
98 | if (n == 1 || sep == '\n') | ||
99 | break; | ||
100 | } | ||
101 | |||
102 | if (nr_cpus > 0) | ||
103 | cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); | ||
104 | else | ||
105 | cpus = cpu_map__default_new(); | ||
106 | out_free_tmp: | ||
107 | free(tmp_cpus); | ||
108 | return cpus; | ||
109 | } | ||
110 | |||
111 | static struct perf_cpu_map *cpu_map__read_all_cpu_map(void) | ||
112 | { | ||
113 | struct perf_cpu_map *cpus = NULL; | ||
114 | FILE *onlnf; | ||
115 | |||
116 | onlnf = fopen("/sys/devices/system/cpu/online", "r"); | ||
117 | if (!onlnf) | ||
118 | return cpu_map__default_new(); | ||
119 | |||
120 | cpus = cpu_map__read(onlnf); | ||
121 | fclose(onlnf); | ||
122 | return cpus; | ||
123 | } | ||
124 | |||
125 | struct perf_cpu_map *cpu_map__new(const char *cpu_list) | ||
126 | { | ||
127 | struct perf_cpu_map *cpus = NULL; | ||
128 | unsigned long start_cpu, end_cpu = 0; | ||
129 | char *p = NULL; | ||
130 | int i, nr_cpus = 0; | ||
131 | int *tmp_cpus = NULL, *tmp; | ||
132 | int max_entries = 0; | ||
133 | |||
134 | if (!cpu_list) | ||
135 | return cpu_map__read_all_cpu_map(); | ||
136 | |||
137 | /* | ||
138 | * must handle the case of empty cpumap to cover | ||
139 | * TOPOLOGY header for NUMA nodes with no CPU | ||
140 | * ( e.g., because of CPU hotplug) | ||
141 | */ | ||
142 | if (!isdigit(*cpu_list) && *cpu_list != '\0') | ||
143 | goto out; | ||
144 | |||
145 | while (isdigit(*cpu_list)) { | ||
146 | p = NULL; | ||
147 | start_cpu = strtoul(cpu_list, &p, 0); | ||
148 | if (start_cpu >= INT_MAX | ||
149 | || (*p != '\0' && *p != ',' && *p != '-')) | ||
150 | goto invalid; | ||
151 | |||
152 | if (*p == '-') { | ||
153 | cpu_list = ++p; | ||
154 | p = NULL; | ||
155 | end_cpu = strtoul(cpu_list, &p, 0); | ||
156 | |||
157 | if (end_cpu >= INT_MAX || (*p != '\0' && *p != ',')) | ||
158 | goto invalid; | ||
159 | |||
160 | if (end_cpu < start_cpu) | ||
161 | goto invalid; | ||
162 | } else { | ||
163 | end_cpu = start_cpu; | ||
164 | } | ||
165 | |||
166 | for (; start_cpu <= end_cpu; start_cpu++) { | ||
167 | /* check for duplicates */ | ||
168 | for (i = 0; i < nr_cpus; i++) | ||
169 | if (tmp_cpus[i] == (int)start_cpu) | ||
170 | goto invalid; | ||
171 | |||
172 | if (nr_cpus == max_entries) { | ||
173 | max_entries += MAX_NR_CPUS; | ||
174 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
175 | if (tmp == NULL) | ||
176 | goto invalid; | ||
177 | tmp_cpus = tmp; | ||
178 | } | ||
179 | tmp_cpus[nr_cpus++] = (int)start_cpu; | ||
180 | } | ||
181 | if (*p) | ||
182 | ++p; | ||
183 | |||
184 | cpu_list = p; | ||
185 | } | ||
186 | |||
187 | if (nr_cpus > 0) | ||
188 | cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); | ||
189 | else if (*cpu_list != '\0') | ||
190 | cpus = cpu_map__default_new(); | ||
191 | else | ||
192 | cpus = perf_cpu_map__dummy_new(); | ||
193 | invalid: | ||
194 | free(tmp_cpus); | ||
195 | out: | ||
196 | return cpus; | ||
197 | } | ||
198 | |||
199 | static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) | 20 | static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) |
200 | { | 21 | { |
201 | struct perf_cpu_map *map; | 22 | struct perf_cpu_map *map; |
@@ -751,7 +572,7 @@ const struct perf_cpu_map *cpu_map__online(void) /* thread unsafe */ | |||
751 | static const struct perf_cpu_map *online = NULL; | 572 | static const struct perf_cpu_map *online = NULL; |
752 | 573 | ||
753 | if (!online) | 574 | if (!online) |
754 | online = cpu_map__new(NULL); /* from /sys/devices/system/cpu/online */ | 575 | online = perf_cpu_map__new(NULL); /* from /sys/devices/system/cpu/online */ |
755 | 576 | ||
756 | return online; | 577 | return online; |
757 | } | 578 | } |
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index b7af2cb68c19..a3d27f4131be 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h | |||
@@ -11,10 +11,8 @@ | |||
11 | #include "perf.h" | 11 | #include "perf.h" |
12 | #include "util/debug.h" | 12 | #include "util/debug.h" |
13 | 13 | ||
14 | struct perf_cpu_map *cpu_map__new(const char *cpu_list); | ||
15 | struct perf_cpu_map *cpu_map__empty_new(int nr); | 14 | struct perf_cpu_map *cpu_map__empty_new(int nr); |
16 | struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); | 15 | struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); |
17 | struct perf_cpu_map *cpu_map__read(FILE *file); | ||
18 | size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); | 16 | size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); |
19 | size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size); | 17 | size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size); |
20 | size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp); | 18 | size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp); |
diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 0cd99c460cd4..4f70155eaf83 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | #include <api/fs/fs.h> | 6 | #include <api/fs/fs.h> |
7 | #include <linux/zalloc.h> | 7 | #include <linux/zalloc.h> |
8 | #include <perf/cpumap.h> | ||
8 | 9 | ||
9 | #include "cputopo.h" | 10 | #include "cputopo.h" |
10 | #include "cpumap.h" | 11 | #include "cpumap.h" |
@@ -182,7 +183,7 @@ struct cpu_topology *cpu_topology__new(void) | |||
182 | ncpus = cpu__max_present_cpu(); | 183 | ncpus = cpu__max_present_cpu(); |
183 | 184 | ||
184 | /* build online CPU map */ | 185 | /* build online CPU map */ |
185 | map = cpu_map__new(NULL); | 186 | map = perf_cpu_map__new(NULL); |
186 | if (map == NULL) { | 187 | if (map == NULL) { |
187 | pr_debug("failed to get system cpumap\n"); | 188 | pr_debug("failed to get system cpumap\n"); |
188 | return NULL; | 189 | return NULL; |
@@ -312,7 +313,7 @@ struct numa_topology *numa_topology__new(void) | |||
312 | if (c) | 313 | if (c) |
313 | *c = '\0'; | 314 | *c = '\0'; |
314 | 315 | ||
315 | node_map = cpu_map__new(buf); | 316 | node_map = perf_cpu_map__new(buf); |
316 | if (!node_map) | 317 | if (!node_map) |
317 | goto out; | 318 | goto out; |
318 | 319 | ||
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ae75777a0ba4..67c67e9a38cd 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/err.h> | 34 | #include <linux/err.h> |
35 | #include <linux/zalloc.h> | 35 | #include <linux/zalloc.h> |
36 | #include <perf/evlist.h> | 36 | #include <perf/evlist.h> |
37 | #include <perf/cpumap.h> | ||
37 | 38 | ||
38 | #ifdef LACKS_SIGQUEUE_PROTOTYPE | 39 | #ifdef LACKS_SIGQUEUE_PROTOTYPE |
39 | int sigqueue(pid_t pid, int sig, const union sigval value); | 40 | int sigqueue(pid_t pid, int sig, const union sigval value); |
@@ -1089,7 +1090,7 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target) | |||
1089 | if (target__uses_dummy_map(target)) | 1090 | if (target__uses_dummy_map(target)) |
1090 | cpus = perf_cpu_map__dummy_new(); | 1091 | cpus = perf_cpu_map__dummy_new(); |
1091 | else | 1092 | else |
1092 | cpus = cpu_map__new(target->cpu_list); | 1093 | cpus = perf_cpu_map__new(target->cpu_list); |
1093 | 1094 | ||
1094 | if (!cpus) | 1095 | if (!cpus) |
1095 | goto out_delete_threads; | 1096 | goto out_delete_threads; |
@@ -1372,7 +1373,7 @@ static int perf_evlist__create_syswide_maps(struct evlist *evlist) | |||
1372 | * error, and we may not want to do that fallback to a | 1373 | * error, and we may not want to do that fallback to a |
1373 | * default cpu identity map :-\ | 1374 | * default cpu identity map :-\ |
1374 | */ | 1375 | */ |
1375 | cpus = cpu_map__new(NULL); | 1376 | cpus = perf_cpu_map__new(NULL); |
1376 | if (!cpus) | 1377 | if (!cpus) |
1377 | goto out; | 1378 | goto out; |
1378 | 1379 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d81afe56392c..fa914ba8cd56 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/time64.h> | 20 | #include <linux/time64.h> |
21 | #include <dirent.h> | 21 | #include <dirent.h> |
22 | #include <bpf/libbpf.h> | 22 | #include <bpf/libbpf.h> |
23 | #include <perf/cpumap.h> | ||
23 | 24 | ||
24 | #include "evlist.h" | 25 | #include "evlist.h" |
25 | #include "evsel.h" | 26 | #include "evsel.h" |
@@ -2348,7 +2349,7 @@ static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused) | |||
2348 | if (!str) | 2349 | if (!str) |
2349 | goto error; | 2350 | goto error; |
2350 | 2351 | ||
2351 | n->map = cpu_map__new(str); | 2352 | n->map = perf_cpu_map__new(str); |
2352 | if (!n->map) | 2353 | if (!n->map) |
2353 | goto error; | 2354 | goto error; |
2354 | 2355 | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index ec7ce18b999a..db2460d6b625 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "bpf-loader.h" | 24 | #include "bpf-loader.h" |
25 | #include "debug.h" | 25 | #include "debug.h" |
26 | #include <api/fs/tracing_path.h> | 26 | #include <api/fs/tracing_path.h> |
27 | #include <perf/cpumap.h> | ||
27 | #include "parse-events-bison.h" | 28 | #include "parse-events-bison.h" |
28 | #define YY_EXTRA_TYPE int | 29 | #define YY_EXTRA_TYPE int |
29 | #include "parse-events-flex.h" | 30 | #include "parse-events-flex.h" |
@@ -323,7 +324,7 @@ __add_event(struct list_head *list, int *idx, | |||
323 | { | 324 | { |
324 | struct evsel *evsel; | 325 | struct evsel *evsel; |
325 | struct perf_cpu_map *cpus = pmu ? pmu->cpus : | 326 | struct perf_cpu_map *cpus = pmu ? pmu->cpus : |
326 | cpu_list ? cpu_map__new(cpu_list) : NULL; | 327 | cpu_list ? perf_cpu_map__new(cpu_list) : NULL; |
327 | 328 | ||
328 | event_attr_init(attr); | 329 | event_attr_init(attr); |
329 | 330 | ||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d355f9506a1c..b7da21a7d627 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <api/fs/fs.h> | 15 | #include <api/fs/fs.h> |
16 | #include <locale.h> | 16 | #include <locale.h> |
17 | #include <regex.h> | 17 | #include <regex.h> |
18 | #include <perf/cpumap.h> | ||
18 | #include "pmu.h" | 19 | #include "pmu.h" |
19 | #include "parse-events.h" | 20 | #include "parse-events.h" |
20 | #include "cpumap.h" | 21 | #include "cpumap.h" |
@@ -581,7 +582,7 @@ static struct perf_cpu_map *__pmu_cpumask(const char *path) | |||
581 | if (!file) | 582 | if (!file) |
582 | return NULL; | 583 | return NULL; |
583 | 584 | ||
584 | cpus = cpu_map__read(file); | 585 | cpus = perf_cpu_map__read(file); |
585 | fclose(file); | 586 | fclose(file); |
586 | return cpus; | 587 | return cpus; |
587 | } | 588 | } |
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 23a4fa13b92d..75ecc32a4427 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <inttypes.h> | 4 | #include <inttypes.h> |
5 | #include <poll.h> | 5 | #include <poll.h> |
6 | #include <linux/err.h> | 6 | #include <linux/err.h> |
7 | #include <perf/cpumap.h> | ||
7 | #include "evlist.h" | 8 | #include "evlist.h" |
8 | #include "callchain.h" | 9 | #include "callchain.h" |
9 | #include "evsel.h" | 10 | #include "evsel.h" |
@@ -549,7 +550,7 @@ static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, | |||
549 | kwlist, &cpustr)) | 550 | kwlist, &cpustr)) |
550 | return -1; | 551 | return -1; |
551 | 552 | ||
552 | pcpus->cpus = cpu_map__new(cpustr); | 553 | pcpus->cpus = perf_cpu_map__new(cpustr); |
553 | if (pcpus->cpus == NULL) | 554 | if (pcpus->cpus == NULL) |
554 | return -1; | 555 | return -1; |
555 | return 0; | 556 | return 0; |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 445788819969..03dcdb3f33a7 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <errno.h> | 6 | #include <errno.h> |
7 | #include <api/fs/fs.h> | 7 | #include <api/fs/fs.h> |
8 | #include <subcmd/parse-options.h> | 8 | #include <subcmd/parse-options.h> |
9 | #include <perf/cpumap.h> | ||
9 | #include "util.h" | 10 | #include "util.h" |
10 | #include "cloexec.h" | 11 | #include "cloexec.h" |
11 | 12 | ||
@@ -63,7 +64,7 @@ static bool perf_probe_api(setup_probe_fn_t fn) | |||
63 | struct perf_cpu_map *cpus; | 64 | struct perf_cpu_map *cpus; |
64 | int cpu, ret, i = 0; | 65 | int cpu, ret, i = 0; |
65 | 66 | ||
66 | cpus = cpu_map__new(NULL); | 67 | cpus = perf_cpu_map__new(NULL); |
67 | if (!cpus) | 68 | if (!cpus) |
68 | return false; | 69 | return false; |
69 | cpu = cpus->map[0]; | 70 | cpu = cpus->map[0]; |
@@ -118,7 +119,7 @@ bool perf_can_record_cpu_wide(void) | |||
118 | struct perf_cpu_map *cpus; | 119 | struct perf_cpu_map *cpus; |
119 | int cpu, fd; | 120 | int cpu, fd; |
120 | 121 | ||
121 | cpus = cpu_map__new(NULL); | 122 | cpus = perf_cpu_map__new(NULL); |
122 | if (!cpus) | 123 | if (!cpus) |
123 | return false; | 124 | return false; |
124 | cpu = cpus->map[0]; | 125 | cpu = cpus->map[0]; |
@@ -275,7 +276,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) | |||
275 | evsel = perf_evlist__last(temp_evlist); | 276 | evsel = perf_evlist__last(temp_evlist); |
276 | 277 | ||
277 | if (!evlist || cpu_map__empty(evlist->cpus)) { | 278 | if (!evlist || cpu_map__empty(evlist->cpus)) { |
278 | struct perf_cpu_map *cpus = cpu_map__new(NULL); | 279 | struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); |
279 | 280 | ||
280 | cpu = cpus ? cpus->map[0] : 0; | 281 | cpu = cpus ? cpus->map[0] : 0; |
281 | perf_cpu_map__put(cpus); | 282 | perf_cpu_map__put(cpus); |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1f3dc7a8cee6..11e6093c941b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <unistd.h> | 10 | #include <unistd.h> |
11 | #include <sys/types.h> | 11 | #include <sys/types.h> |
12 | #include <sys/mman.h> | 12 | #include <sys/mman.h> |
13 | #include <perf/cpumap.h> | ||
13 | 14 | ||
14 | #include "evlist.h" | 15 | #include "evlist.h" |
15 | #include "evsel.h" | 16 | #include "evsel.h" |
@@ -2289,7 +2290,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, | |||
2289 | } | 2290 | } |
2290 | } | 2291 | } |
2291 | 2292 | ||
2292 | map = cpu_map__new(cpu_list); | 2293 | map = perf_cpu_map__new(cpu_list); |
2293 | if (map == NULL) { | 2294 | if (map == NULL) { |
2294 | pr_err("Invalid cpu_list\n"); | 2295 | pr_err("Invalid cpu_list\n"); |
2295 | return -1; | 2296 | return -1; |
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index a9ca5c4fffee..ae6a534a7a80 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/bitmap.h> | 16 | #include <linux/bitmap.h> |
17 | #include <linux/time64.h> | 17 | #include <linux/time64.h> |
18 | #include <linux/zalloc.h> | 18 | #include <linux/zalloc.h> |
19 | #include <perf/cpumap.h> | ||
19 | 20 | ||
20 | #include "perf.h" | 21 | #include "perf.h" |
21 | #include "svghelper.h" | 22 | #include "svghelper.h" |
@@ -731,7 +732,7 @@ static int str_to_bitmap(char *s, cpumask_t *b) | |||
731 | struct perf_cpu_map *m; | 732 | struct perf_cpu_map *m; |
732 | int c; | 733 | int c; |
733 | 734 | ||
734 | m = cpu_map__new(s); | 735 | m = perf_cpu_map__new(s); |
735 | if (!m) | 736 | if (!m) |
736 | return -1; | 737 | return -1; |
737 | 738 | ||