mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
perf parse-events: Architecture specific leader override
Currently topdown events must appear after a slots event: $ perf stat -e '{slots,topdown-fe-bound}' /bin/true Performance counter stats for '/bin/true': 3,183,090 slots 986,133 topdown-fe-bound Reversing the events yields: $ perf stat -e '{topdown-fe-bound,slots}' /bin/true Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (topdown-fe-bound). For metrics the order of events is determined by iterating over a hashmap, and so slots isn't guaranteed to be first which can yield this error. Change the set_leader in parse-events, called when a group is closed, so that rather than always making the first event the leader, if the slots event exists then it is made the leader. It is then moved to the head of the evlist otherwise it won't be opened in the correct order. The result is: $ perf stat -e '{topdown-fe-bound,slots}' /bin/true Performance counter stats for '/bin/true': 3,274,795 slots 1,001,702 topdown-fe-bound A problem with this approach is the slots event is identified by name, names can be overwritten like 'cpu/slots,name=foo/' and this causes the leader change to fail. The change also modifies and fixes mixed groups like, with the change: $ perf stat -e '{instructions,slots,topdown-fe-bound}' -a -- sleep 2 Performance counter stats for 'system wide': 5574985410 slots 971981616 instructions 1348461887 topdown-fe-bound 2.001263120 seconds time elapsed Without the change: $ perf stat -e '{instructions,slots,topdown-fe-bound}' -a -- sleep 2 Performance counter stats for 'system wide': <not counted> instructions <not counted> slots <not supported> topdown-fe-bound 2.006247990 seconds time elapsed Something that may be undesirable here is that the events are reordered in the output. Reviewed-by: Kajol Jain <kjain@linux.ibm.com> Signed-off-by: Ian Rogers <irogers@google.com> Acked-by: Jiri Olsa <jolsa@redhat.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: John Garry <john.garry@huawei.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Clarke <pc@us.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Riccardo Mancini <rickyman7@gmail.com> Cc: Stephane Eranian <eranian@google.com> Cc: Vineet Singh <vineet.singh@intel.com> Link: http://lore.kernel.org/lkml/20211130174945.247604-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
ecdcf630d7
commit
94dbfd6781
@ -17,3 +17,20 @@ int arch_evlist__add_default_attrs(struct evlist *evlist)
|
|||||||
else
|
else
|
||||||
return parse_events(evlist, TOPDOWN_L1_EVENTS, NULL);
|
return parse_events(evlist, TOPDOWN_L1_EVENTS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct evsel *arch_evlist__leader(struct list_head *list)
|
||||||
|
{
|
||||||
|
struct evsel *evsel, *first;
|
||||||
|
|
||||||
|
first = list_first_entry(list, struct evsel, core.node);
|
||||||
|
|
||||||
|
if (!pmu_have_event("cpu", "slots"))
|
||||||
|
return first;
|
||||||
|
|
||||||
|
__evlist__for_each_entry(list, evsel) {
|
||||||
|
if (evsel->pmu_name && !strcmp(evsel->pmu_name, "cpu") &&
|
||||||
|
evsel->name && strstr(evsel->name, "slots"))
|
||||||
|
return evsel;
|
||||||
|
}
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
@ -110,6 +110,7 @@ int __evlist__add_default_attrs(struct evlist *evlist,
|
|||||||
__evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array))
|
__evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array))
|
||||||
|
|
||||||
int arch_evlist__add_default_attrs(struct evlist *evlist);
|
int arch_evlist__add_default_attrs(struct evlist *evlist);
|
||||||
|
struct evsel *arch_evlist__leader(struct list_head *list);
|
||||||
|
|
||||||
int evlist__add_dummy(struct evlist *evlist);
|
int evlist__add_dummy(struct evlist *evlist);
|
||||||
|
|
||||||
|
@ -1824,6 +1824,11 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__weak struct evsel *arch_evlist__leader(struct list_head *list)
|
||||||
|
{
|
||||||
|
return list_first_entry(list, struct evsel, core.node);
|
||||||
|
}
|
||||||
|
|
||||||
void parse_events__set_leader(char *name, struct list_head *list,
|
void parse_events__set_leader(char *name, struct list_head *list,
|
||||||
struct parse_events_state *parse_state)
|
struct parse_events_state *parse_state)
|
||||||
{
|
{
|
||||||
@ -1837,9 +1842,10 @@ void parse_events__set_leader(char *name, struct list_head *list,
|
|||||||
if (parse_events__set_leader_for_uncore_aliase(name, list, parse_state))
|
if (parse_events__set_leader_for_uncore_aliase(name, list, parse_state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
leader = list_first_entry(list, struct evsel, core.node);
|
leader = arch_evlist__leader(list);
|
||||||
__perf_evlist__set_leader(list, &leader->core);
|
__perf_evlist__set_leader(list, &leader->core);
|
||||||
leader->group_name = name ? strdup(name) : NULL;
|
leader->group_name = name ? strdup(name) : NULL;
|
||||||
|
list_move(&leader->core.node, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* list_event is assumed to point to malloc'ed memory */
|
/* list_event is assumed to point to malloc'ed memory */
|
||||||
|
Loading…
Reference in New Issue
Block a user