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

perf annotate: Prefer passing evsel to evsel->core.idx

An evsel idx may not be stable due to sorting, evlist removal,
etc. Try to reduce it being part of APIs by explicitly passing the
evsel in annotate code. Internally the code just reads evsel->core.idx
so behavior is unchanged.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Chen Ni <nichen@iscas.ac.cn>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Link: https://lore.kernel.org/r/20250117181848.690474-1-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
035f0c27 ac22d753

+38 -36
+2 -2
tools/perf/builtin-top.c
··· 267 267 268 268 if (top->evlist->enabled) { 269 269 if (top->zero) 270 - symbol__annotate_zero_histogram(symbol, top->sym_evsel->core.idx); 270 + symbol__annotate_zero_histogram(symbol, top->sym_evsel); 271 271 else 272 - symbol__annotate_decay_histogram(symbol, top->sym_evsel->core.idx); 272 + symbol__annotate_decay_histogram(symbol, top->sym_evsel); 273 273 } 274 274 if (more != 0) 275 275 printf("%d lines not displayed, maybe increase display entries [e]\n", more);
+1 -1
tools/perf/ui/browsers/annotate.c
··· 754 754 hbt->timer(hbt->arg); 755 755 756 756 if (delay_secs != 0) { 757 - symbol__annotate_decay_histogram(sym, evsel->core.idx); 757 + symbol__annotate_decay_histogram(sym, evsel); 758 758 hists__scnprintf_title(hists, title, sizeof(title)); 759 759 annotate_browser__show(&browser->b, title, help); 760 760 }
+9 -7
tools/perf/ui/gtk/annotate.c
··· 3 3 #include "util/sort.h" 4 4 #include "util/debug.h" 5 5 #include "util/annotate.h" 6 + #include "util/evlist.h" 6 7 #include "util/evsel.h" 7 8 #include "util/map.h" 8 9 #include "util/dso.h" ··· 27 26 }; 28 27 29 28 static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym, 30 - struct disasm_line *dl, int evidx) 29 + struct disasm_line *dl, const struct evsel *evsel) 31 30 { 32 31 struct annotation *notes; 33 32 struct sym_hist *symhist; ··· 43 42 return 0; 44 43 45 44 notes = symbol__annotation(sym); 46 - symhist = annotation__histogram(notes, evidx); 47 - entry = annotated_source__hist_entry(notes->src, evidx, dl->al.offset); 45 + symhist = annotation__histogram(notes, evsel); 46 + entry = annotated_source__hist_entry(notes->src, evsel, dl->al.offset); 48 47 if (entry) 49 48 nr_samples = entry->nr_samples; 50 49 ··· 140 139 gtk_list_store_append(store, &iter); 141 140 142 141 if (evsel__is_group_event(evsel)) { 143 - for (i = 0; i < evsel->core.nr_members; i++) { 142 + struct evsel *cur_evsel; 143 + 144 + for_each_group_evsel(cur_evsel, evsel__leader(evsel)) { 144 145 ret += perf_gtk__get_percent(s + ret, 145 146 sizeof(s) - ret, 146 147 sym, pos, 147 - evsel->core.idx + i); 148 + cur_evsel); 148 149 ret += scnprintf(s + ret, sizeof(s) - ret, " "); 149 150 } 150 151 } else { 151 - ret = perf_gtk__get_percent(s, sizeof(s), sym, pos, 152 - evsel->core.idx); 152 + ret = perf_gtk__get_percent(s, sizeof(s), sym, pos, evsel); 153 153 } 154 154 155 155 if (ret)
+15 -17
tools/perf/util/annotate.c
··· 209 209 } 210 210 211 211 static int __symbol__inc_addr_samples(struct map_symbol *ms, 212 - struct annotated_source *src, int evidx, u64 addr, 212 + struct annotated_source *src, struct evsel *evsel, u64 addr, 213 213 struct perf_sample *sample) 214 214 { 215 215 struct symbol *sym = ms->sym; ··· 228 228 } 229 229 230 230 offset = addr - sym->start; 231 - h = annotated_source__histogram(src, evidx); 231 + h = annotated_source__histogram(src, evsel); 232 232 if (h == NULL) { 233 233 pr_debug("%s(%d): ENOMEM! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 ", func: %d\n", 234 234 __func__, __LINE__, sym->name, sym->start, addr, sym->end, sym->type == STT_FUNC); 235 235 return -ENOMEM; 236 236 } 237 237 238 - hash_key = offset << 16 | evidx; 238 + hash_key = offset << 16 | evsel->core.idx; 239 239 if (!hashmap__find(src->samples, hash_key, &entry)) { 240 240 entry = zalloc(sizeof(*entry)); 241 241 if (entry == NULL) ··· 252 252 253 253 pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 254 254 ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n", 255 - sym->start, sym->name, addr, addr - sym->start, evidx, 255 + sym->start, sym->name, addr, addr - sym->start, evsel->core.idx, 256 256 entry->nr_samples, entry->period); 257 257 return 0; 258 258 } ··· 323 323 if (sym == NULL) 324 324 return 0; 325 325 src = symbol__hists(sym, evsel->evlist->core.nr_entries); 326 - return src ? __symbol__inc_addr_samples(ms, src, evsel->core.idx, addr, sample) : 0; 326 + return src ? __symbol__inc_addr_samples(ms, src, evsel, addr, sample) : 0; 327 327 } 328 328 329 329 static int symbol__account_br_cntr(struct annotated_branch *branch, ··· 861 861 s64 offset, s64 end) 862 862 { 863 863 struct hists *hists = evsel__hists(evsel); 864 - int evidx = evsel->core.idx; 865 - struct sym_hist *sym_hist = annotation__histogram(notes, evidx); 864 + struct sym_hist *sym_hist = annotation__histogram(notes, evsel); 866 865 unsigned int hits = 0; 867 866 u64 period = 0; 868 867 869 868 while (offset < end) { 870 869 struct sym_hist_entry *entry; 871 870 872 - entry = annotated_source__hist_entry(notes->src, evidx, offset); 871 + entry = annotated_source__hist_entry(notes->src, evsel, offset); 873 872 if (entry) { 874 873 hits += entry->nr_samples; 875 874 period += entry->period; ··· 1139 1140 1140 1141 static void symbol__annotate_hits(struct symbol *sym, struct evsel *evsel) 1141 1142 { 1142 - int evidx = evsel->core.idx; 1143 1143 struct annotation *notes = symbol__annotation(sym); 1144 - struct sym_hist *h = annotation__histogram(notes, evidx); 1144 + struct sym_hist *h = annotation__histogram(notes, evsel); 1145 1145 u64 len = symbol__size(sym), offset; 1146 1146 1147 1147 for (offset = 0; offset < len; ++offset) { 1148 1148 struct sym_hist_entry *entry; 1149 1149 1150 - entry = annotated_source__hist_entry(notes->src, evidx, offset); 1150 + entry = annotated_source__hist_entry(notes->src, evsel, offset); 1151 1151 if (entry && entry->nr_samples != 0) 1152 1152 printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, 1153 1153 sym->start + offset, entry->nr_samples); ··· 1176 1178 const char *d_filename; 1177 1179 const char *evsel_name = evsel__name(evsel); 1178 1180 struct annotation *notes = symbol__annotation(sym); 1179 - struct sym_hist *h = annotation__histogram(notes, evsel->core.idx); 1181 + struct sym_hist *h = annotation__histogram(notes, evsel); 1180 1182 struct annotation_line *pos, *queue = NULL; 1181 1183 struct annotation_options *opts = &annotate_opts; 1182 1184 u64 start = map__rip_2objdump(map, sym->start); ··· 1362 1364 return err; 1363 1365 } 1364 1366 1365 - void symbol__annotate_zero_histogram(struct symbol *sym, int evidx) 1367 + void symbol__annotate_zero_histogram(struct symbol *sym, struct evsel *evsel) 1366 1368 { 1367 1369 struct annotation *notes = symbol__annotation(sym); 1368 - struct sym_hist *h = annotation__histogram(notes, evidx); 1370 + struct sym_hist *h = annotation__histogram(notes, evsel); 1369 1371 1370 1372 memset(h, 0, sizeof(*notes->src->histograms) * notes->src->nr_histograms); 1371 1373 } 1372 1374 1373 - void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) 1375 + void symbol__annotate_decay_histogram(struct symbol *sym, struct evsel *evsel) 1374 1376 { 1375 1377 struct annotation *notes = symbol__annotation(sym); 1376 - struct sym_hist *h = annotation__histogram(notes, evidx); 1378 + struct sym_hist *h = annotation__histogram(notes, evsel); 1377 1379 struct annotation_line *al; 1378 1380 1379 1381 h->nr_samples = 0; ··· 1383 1385 if (al->offset == -1) 1384 1386 continue; 1385 1387 1386 - entry = annotated_source__hist_entry(notes->src, evidx, al->offset); 1388 + entry = annotated_source__hist_entry(notes->src, evsel, al->offset); 1387 1389 if (entry == NULL) 1388 1390 continue; 1389 1391
+11 -9
tools/perf/util/annotate.h
··· 15 15 #include "hashmap.h" 16 16 #include "disasm.h" 17 17 #include "branch.h" 18 + #include "evsel.h" 18 19 19 20 struct hist_browser_timer; 20 21 struct hist_entry; ··· 24 23 struct addr_map_symbol; 25 24 struct option; 26 25 struct perf_sample; 27 - struct evsel; 28 26 struct symbol; 29 27 struct annotated_data_type; 30 28 ··· 373 373 void annotation__update_column_widths(struct annotation *notes); 374 374 void annotation__toggle_full_addr(struct annotation *notes, struct map_symbol *ms); 375 375 376 - static inline struct sym_hist *annotated_source__histogram(struct annotated_source *src, int idx) 376 + static inline struct sym_hist *annotated_source__histogram(struct annotated_source *src, 377 + const struct evsel *evsel) 377 378 { 378 - return &src->histograms[idx]; 379 + return &src->histograms[evsel->core.idx]; 379 380 } 380 381 381 - static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) 382 + static inline struct sym_hist *annotation__histogram(struct annotation *notes, 383 + const struct evsel *evsel) 382 384 { 383 - return annotated_source__histogram(notes->src, idx); 385 + return annotated_source__histogram(notes->src, evsel); 384 386 } 385 387 386 388 static inline struct sym_hist_entry * 387 - annotated_source__hist_entry(struct annotated_source *src, int idx, u64 offset) 389 + annotated_source__hist_entry(struct annotated_source *src, const struct evsel *evsel, u64 offset) 388 390 { 389 391 struct sym_hist_entry *entry; 390 - long key = offset << 16 | idx; 392 + long key = offset << 16 | evsel->core.idx; 391 393 392 394 if (!hashmap__find(src->samples, key, &entry)) 393 395 return NULL; ··· 451 449 int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, size_t buflen); 452 450 453 451 int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel); 454 - void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); 455 - void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); 452 + void symbol__annotate_zero_histogram(struct symbol *sym, struct evsel *evsel); 453 + void symbol__annotate_decay_histogram(struct symbol *sym, struct evsel *evsel); 456 454 void annotated_source__purge(struct annotated_source *as); 457 455 458 456 int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel);