aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2015-07-21 08:31:27 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-06 15:08:16 -0400
commitf80010eb230b94e8d9cf5bf83373a097fb5b2dcc (patch)
treea122a4edc3bd68d173c274ad168651b8fa2856e8
parent5e5fe748bec771a810b1f44ec9c19e4b92685246 (diff)
perf stat: Move counter processing code into stat object
Moving counter processing code into stat object as perf_stat__process_counter. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1437481927-29538-8-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-stat.c141
-rw-r--r--tools/perf/util/stat.c139
-rw-r--r--tools/perf/util/stat.h3
3 files changed, 143 insertions, 140 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5a781718c09f..a054ddc0b2a0 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -179,145 +179,6 @@ static inline int nsec_counter(struct perf_evsel *evsel)
179 return 0; 179 return 0;
180} 180}
181 181
182static void zero_per_pkg(struct perf_evsel *counter)
183{
184 if (counter->per_pkg_mask)
185 memset(counter->per_pkg_mask, 0, MAX_NR_CPUS);
186}
187
188static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
189{
190 unsigned long *mask = counter->per_pkg_mask;
191 struct cpu_map *cpus = perf_evsel__cpus(counter);
192 int s;
193
194 *skip = false;
195
196 if (!counter->per_pkg)
197 return 0;
198
199 if (cpu_map__empty(cpus))
200 return 0;
201
202 if (!mask) {
203 mask = zalloc(MAX_NR_CPUS);
204 if (!mask)
205 return -ENOMEM;
206
207 counter->per_pkg_mask = mask;
208 }
209
210 s = cpu_map__get_socket(cpus, cpu);
211 if (s < 0)
212 return -1;
213
214 *skip = test_and_set_bit(s, mask) == 1;
215 return 0;
216}
217
218static int
219process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel,
220 int cpu, int thread,
221 struct perf_counts_values *count)
222{
223 struct perf_counts_values *aggr = &evsel->counts->aggr;
224 static struct perf_counts_values zero;
225 bool skip = false;
226
227 if (check_per_pkg(evsel, cpu, &skip)) {
228 pr_err("failed to read per-pkg counter\n");
229 return -1;
230 }
231
232 if (skip)
233 count = &zero;
234
235 switch (config->aggr_mode) {
236 case AGGR_THREAD:
237 case AGGR_CORE:
238 case AGGR_SOCKET:
239 case AGGR_NONE:
240 if (!evsel->snapshot)
241 perf_evsel__compute_deltas(evsel, cpu, thread, count);
242 perf_counts_values__scale(count, config->scale, NULL);
243 if (config->aggr_mode == AGGR_NONE)
244 perf_stat__update_shadow_stats(evsel, count->values, cpu);
245 break;
246 case AGGR_GLOBAL:
247 aggr->val += count->val;
248 if (config->scale) {
249 aggr->ena += count->ena;
250 aggr->run += count->run;
251 }
252 default:
253 break;
254 }
255
256 return 0;
257}
258
259static int process_counter_maps(struct perf_stat_config *config,
260 struct perf_evsel *counter)
261{
262 int nthreads = thread_map__nr(counter->threads);
263 int ncpus = perf_evsel__nr_cpus(counter);
264 int cpu, thread;
265
266 if (counter->system_wide)
267 nthreads = 1;
268
269 for (thread = 0; thread < nthreads; thread++) {
270 for (cpu = 0; cpu < ncpus; cpu++) {
271 if (process_counter_values(config, counter, cpu, thread,
272 perf_counts(counter->counts, cpu, thread)))
273 return -1;
274 }
275 }
276
277 return 0;
278}
279
280static int process_counter(struct perf_stat_config *config,
281 struct perf_evsel *counter)
282{
283 struct perf_counts_values *aggr = &counter->counts->aggr;
284 struct perf_stat *ps = counter->priv;
285 u64 *count = counter->counts->aggr.values;
286 int i, ret;
287
288 aggr->val = aggr->ena = aggr->run = 0;
289 init_stats(ps->res_stats);
290
291 if (counter->per_pkg)
292 zero_per_pkg(counter);
293
294 ret = process_counter_maps(&stat_config, counter);
295 if (ret)
296 return ret;
297
298 if (config->aggr_mode != AGGR_GLOBAL)
299 return 0;
300
301 if (!counter->snapshot)
302 perf_evsel__compute_deltas(counter, -1, -1, aggr);
303 perf_counts_values__scale(aggr, config->scale, &counter->counts->scaled);
304
305 for (i = 0; i < 3; i++)
306 update_stats(&ps->res_stats[i], count[i]);
307
308 if (verbose) {
309 fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
310 perf_evsel__name(counter), count[0], count[1], count[2]);
311 }
312
313 /*
314 * Save the full runtime - to allow normalization during printout:
315 */
316 perf_stat__update_shadow_stats(counter, count, 0);
317
318 return 0;
319}
320
321/* 182/*
322 * Read out the results of a single counter: 183 * Read out the results of a single counter:
323 * do not aggregate counts across CPUs in system-wide mode 184 * do not aggregate counts across CPUs in system-wide mode
@@ -355,7 +216,7 @@ static void read_counters(bool close_counters)
355 if (read_counter(counter)) 216 if (read_counter(counter))
356 pr_warning("failed to read counter %s\n", counter->name); 217 pr_warning("failed to read counter %s\n", counter->name);
357 218
358 if (process_counter(&stat_config, counter)) 219 if (perf_stat_process_counter(&stat_config, counter))
359 pr_warning("failed to process counter %s\n", counter->name); 220 pr_warning("failed to process counter %s\n", counter->name);
360 221
361 if (close_counters) { 222 if (close_counters) {
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index f2a0d1521e26..c5c709cdc3ce 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -238,3 +238,142 @@ void perf_evlist__reset_stats(struct perf_evlist *evlist)
238 perf_evsel__reset_counts(evsel); 238 perf_evsel__reset_counts(evsel);
239 } 239 }
240} 240}
241
242static void zero_per_pkg(struct perf_evsel *counter)
243{
244 if (counter->per_pkg_mask)
245 memset(counter->per_pkg_mask, 0, MAX_NR_CPUS);
246}
247
248static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
249{
250 unsigned long *mask = counter->per_pkg_mask;
251 struct cpu_map *cpus = perf_evsel__cpus(counter);
252 int s;
253
254 *skip = false;
255
256 if (!counter->per_pkg)
257 return 0;
258
259 if (cpu_map__empty(cpus))
260 return 0;
261
262 if (!mask) {
263 mask = zalloc(MAX_NR_CPUS);
264 if (!mask)
265 return -ENOMEM;
266
267 counter->per_pkg_mask = mask;
268 }
269
270 s = cpu_map__get_socket(cpus, cpu);
271 if (s < 0)
272 return -1;
273
274 *skip = test_and_set_bit(s, mask) == 1;
275 return 0;
276}
277
278static int
279process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel,
280 int cpu, int thread,
281 struct perf_counts_values *count)
282{
283 struct perf_counts_values *aggr = &evsel->counts->aggr;
284 static struct perf_counts_values zero;
285 bool skip = false;
286
287 if (check_per_pkg(evsel, cpu, &skip)) {
288 pr_err("failed to read per-pkg counter\n");
289 return -1;
290 }
291
292 if (skip)
293 count = &zero;
294
295 switch (config->aggr_mode) {
296 case AGGR_THREAD:
297 case AGGR_CORE:
298 case AGGR_SOCKET:
299 case AGGR_NONE:
300 if (!evsel->snapshot)
301 perf_evsel__compute_deltas(evsel, cpu, thread, count);
302 perf_counts_values__scale(count, config->scale, NULL);
303 if (config->aggr_mode == AGGR_NONE)
304 perf_stat__update_shadow_stats(evsel, count->values, cpu);
305 break;
306 case AGGR_GLOBAL:
307 aggr->val += count->val;
308 if (config->scale) {
309 aggr->ena += count->ena;
310 aggr->run += count->run;
311 }
312 default:
313 break;
314 }
315
316 return 0;
317}
318
319static int process_counter_maps(struct perf_stat_config *config,
320 struct perf_evsel *counter)
321{
322 int nthreads = thread_map__nr(counter->threads);
323 int ncpus = perf_evsel__nr_cpus(counter);
324 int cpu, thread;
325
326 if (counter->system_wide)
327 nthreads = 1;
328
329 for (thread = 0; thread < nthreads; thread++) {
330 for (cpu = 0; cpu < ncpus; cpu++) {
331 if (process_counter_values(config, counter, cpu, thread,
332 perf_counts(counter->counts, cpu, thread)))
333 return -1;
334 }
335 }
336
337 return 0;
338}
339
340int perf_stat_process_counter(struct perf_stat_config *config,
341 struct perf_evsel *counter)
342{
343 struct perf_counts_values *aggr = &counter->counts->aggr;
344 struct perf_stat *ps = counter->priv;
345 u64 *count = counter->counts->aggr.values;
346 int i, ret;
347
348 aggr->val = aggr->ena = aggr->run = 0;
349 init_stats(ps->res_stats);
350
351 if (counter->per_pkg)
352 zero_per_pkg(counter);
353
354 ret = process_counter_maps(config, counter);
355 if (ret)
356 return ret;
357
358 if (config->aggr_mode != AGGR_GLOBAL)
359 return 0;
360
361 if (!counter->snapshot)
362 perf_evsel__compute_deltas(counter, -1, -1, aggr);
363 perf_counts_values__scale(aggr, config->scale, &counter->counts->scaled);
364
365 for (i = 0; i < 3; i++)
366 update_stats(&ps->res_stats[i], count[i]);
367
368 if (verbose) {
369 fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
370 perf_evsel__name(counter), count[0], count[1], count[2]);
371 }
372
373 /*
374 * Save the full runtime - to allow normalization during printout:
375 */
376 perf_stat__update_shadow_stats(counter, count, 0);
377
378 return 0;
379}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 1da706d848fb..0b897b083682 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -116,4 +116,7 @@ int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw);
116int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw); 116int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
117void perf_evlist__free_stats(struct perf_evlist *evlist); 117void perf_evlist__free_stats(struct perf_evlist *evlist);
118void perf_evlist__reset_stats(struct perf_evlist *evlist); 118void perf_evlist__reset_stats(struct perf_evlist *evlist);
119
120int perf_stat_process_counter(struct perf_stat_config *config,
121 struct perf_evsel *counter);
119#endif 122#endif