1 // SPDX-License-Identifier: GPL-2.0 2 #include <stdio.h> 3 #include "util/pmu.h" 4 #include "util/evlist.h" 5 #include "util/parse-events.h" 6 #include "topdown.h" 7 8 #define TOPDOWN_L1_EVENTS "{slots,topdown-retiring,topdown-bad-spec,topdown-fe-bound,topdown-be-bound}" 9 #define TOPDOWN_L2_EVENTS "{slots,topdown-retiring,topdown-bad-spec,topdown-fe-bound,topdown-be-bound,topdown-heavy-ops,topdown-br-mispredict,topdown-fetch-lat,topdown-mem-bound}" 10 11 int arch_evlist__add_default_attrs(struct evlist *evlist) 12 { 13 if (!pmu_have_event("cpu", "slots")) 14 return 0; 15 16 if (pmu_have_event("cpu", "topdown-heavy-ops")) 17 return parse_events(evlist, TOPDOWN_L2_EVENTS, NULL); 18 else 19 return parse_events(evlist, TOPDOWN_L1_EVENTS, NULL); 20 } 21 22 struct evsel *arch_evlist__leader(struct list_head *list) 23 { 24 struct evsel *evsel, *first, *slots = NULL; 25 bool has_topdown = false; 26 27 first = list_first_entry(list, struct evsel, core.node); 28 29 if (!topdown_sys_has_perf_metrics()) 30 return first; 31 32 /* If there is a slots event and a topdown event then the slots event comes first. */ 33 __evlist__for_each_entry(list, evsel) { 34 if (evsel->pmu_name && !strncmp(evsel->pmu_name, "cpu", 3) && evsel->name) { 35 if (strcasestr(evsel->name, "slots")) { 36 slots = evsel; 37 if (slots == first) 38 return first; 39 } 40 if (strcasestr(evsel->name, "topdown")) 41 has_topdown = true; 42 if (slots && has_topdown) 43 return slots; 44 } 45 } 46 return first; 47 } 48