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

perf tools: Remove hists from evsel

Now tools that deals want to have an hists per evsel need to call
hists__init() before creating any evsels, which can be as early as when
parsing the command line, so do it before calling parse_options().

The current tools using hists/hist_entries are report, top and annotate,
change them to request per evsel hists.

This is in preparation for making evsels usable by 3rd party tools, that
not necessarily live in perf's source code repository.

Acked-by: Borislav Petkov <bp@suse.de>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-usjx2la743f10ippj7p1b20x@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+65 -25
+4 -1
tools/perf/builtin-annotate.c
··· 326 326 "Show event group information together"), 327 327 OPT_END() 328 328 }; 329 - int ret; 329 + int ret = hists__init(); 330 + 331 + if (ret < 0) 332 + return ret; 330 333 331 334 argc = parse_options(argc, argv, options, annotate_usage, 0); 332 335
+4 -1
tools/perf/builtin-report.c
··· 568 568 struct stat st; 569 569 bool has_br_stack = false; 570 570 int branch_mode = -1; 571 - int ret = -1; 572 571 char callchain_default_opt[] = "fractal,0.5,callee"; 573 572 const char * const report_usage[] = { 574 573 "perf report [<options>]", ··· 694 695 struct perf_data_file file = { 695 696 .mode = PERF_DATA_MODE_READ, 696 697 }; 698 + int ret = hists__init(); 699 + 700 + if (ret < 0) 701 + return ret; 697 702 698 703 perf_config(report__config, &report); 699 704
+4 -1
tools/perf/builtin-top.c
··· 1047 1047 1048 1048 int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) 1049 1049 { 1050 - int status = -1; 1051 1050 char errbuf[BUFSIZ]; 1052 1051 struct perf_top top = { 1053 1052 .count_filter = 5, ··· 1164 1165 "perf top [<options>]", 1165 1166 NULL 1166 1167 }; 1168 + int status = hists__init(); 1169 + 1170 + if (status < 0) 1171 + return status; 1167 1172 1168 1173 top.evlist = perf_evlist__new(); 1169 1174 if (top.evlist == NULL)
+5
tools/perf/tests/builtin-test.c
··· 6 6 #include <unistd.h> 7 7 #include <string.h> 8 8 #include "builtin.h" 9 + #include "hist.h" 9 10 #include "intlist.h" 10 11 #include "tests.h" 11 12 #include "debug.h" ··· 303 302 OPT_END() 304 303 }; 305 304 struct intlist *skiplist = NULL; 305 + int ret = hists__init(); 306 + 307 + if (ret < 0) 308 + return ret; 306 309 307 310 argc = parse_options(argc, argv, test_options, test_usage, 0); 308 311 if (argc >= 1 && !strcmp(argv[0], "list"))
-11
tools/perf/util/evsel.c
··· 159 159 evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type); 160 160 } 161 161 162 - void hists__init(struct hists *hists) 163 - { 164 - memset(hists, 0, sizeof(*hists)); 165 - hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; 166 - hists->entries_in = &hists->entries_in_array[0]; 167 - hists->entries_collapsed = RB_ROOT; 168 - hists->entries = RB_ROOT; 169 - pthread_mutex_init(&hists->lock, NULL); 170 - } 171 - 172 162 void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, 173 163 enum perf_event_sample_format bit) 174 164 { ··· 201 211 evsel->unit = ""; 202 212 evsel->scale = 1.0; 203 213 INIT_LIST_HEAD(&evsel->node); 204 - hists__init(&evsel->hists); 205 214 perf_evsel__object.init(evsel); 206 215 evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); 207 216 perf_evsel__calc_id_pos(evsel);
-11
tools/perf/util/evsel.h
··· 8 8 #include <linux/types.h> 9 9 #include "xyarray.h" 10 10 #include "cgroup.h" 11 - #include "hist.h" 12 11 #include "symbol.h" 13 12 14 13 struct perf_counts_values { ··· 65 66 struct perf_counts *prev_raw_counts; 66 67 int idx; 67 68 u32 ids; 68 - struct hists hists; 69 69 char *name; 70 70 double scale; 71 71 const char *unit; ··· 97 99 u64 val64; 98 100 u32 val32[2]; 99 101 }; 100 - 101 - #define hists_to_evsel(h) container_of(h, struct perf_evsel, hists) 102 - 103 - static inline struct hists *evsel__hists(struct perf_evsel *evsel) 104 - { 105 - return &evsel->hists; 106 - } 107 102 108 103 struct cpu_map; 109 104 struct thread_map; ··· 280 289 { 281 290 return __perf_evsel__read(evsel, ncpus, nthreads, true); 282 291 } 283 - 284 - void hists__init(struct hists *hists); 285 292 286 293 int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, 287 294 struct perf_sample *sample);
+28
tools/perf/util/hist.c
··· 1447 1447 1448 1448 return 0; 1449 1449 } 1450 + 1451 + static int hists_evsel__init(struct perf_evsel *evsel) 1452 + { 1453 + struct hists *hists = evsel__hists(evsel); 1454 + 1455 + memset(hists, 0, sizeof(*hists)); 1456 + hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; 1457 + hists->entries_in = &hists->entries_in_array[0]; 1458 + hists->entries_collapsed = RB_ROOT; 1459 + hists->entries = RB_ROOT; 1460 + pthread_mutex_init(&hists->lock, NULL); 1461 + return 0; 1462 + } 1463 + 1464 + /* 1465 + * XXX We probably need a hists_evsel__exit() to free the hist_entries 1466 + * stored in the rbtree... 1467 + */ 1468 + 1469 + int hists__init(void) 1470 + { 1471 + int err = perf_evsel__object_config(sizeof(struct hists_evsel), 1472 + hists_evsel__init, NULL); 1473 + if (err) 1474 + fputs("FATAL ERROR: Couldn't setup hists class\n", stderr); 1475 + 1476 + return err; 1477 + }
+20
tools/perf/util/hist.h
··· 4 4 #include <linux/types.h> 5 5 #include <pthread.h> 6 6 #include "callchain.h" 7 + #include "evsel.h" 7 8 #include "header.h" 8 9 #include "color.h" 9 10 #include "ui/progress.h" ··· 158 157 159 158 void hists__match(struct hists *leader, struct hists *other); 160 159 int hists__link(struct hists *leader, struct hists *other); 160 + 161 + struct hists_evsel { 162 + struct perf_evsel evsel; 163 + struct hists hists; 164 + }; 165 + 166 + static inline struct perf_evsel *hists_to_evsel(struct hists *hists) 167 + { 168 + struct hists_evsel *hevsel = container_of(hists, struct hists_evsel, hists); 169 + return &hevsel->evsel; 170 + } 171 + 172 + static inline struct hists *evsel__hists(struct perf_evsel *evsel) 173 + { 174 + struct hists_evsel *hevsel = (struct hists_evsel *)evsel; 175 + return &hevsel->hists; 176 + } 177 + 178 + int hists__init(void); 161 179 162 180 struct perf_hpp { 163 181 char *buf;