|
@@ -68,6 +68,7 @@ struct report {
|
|
bool header;
|
|
bool header;
|
|
bool header_only;
|
|
bool header_only;
|
|
bool nonany_branch_mode;
|
|
bool nonany_branch_mode;
|
|
|
|
+ bool group_set;
|
|
int max_stack;
|
|
int max_stack;
|
|
struct perf_read_values show_threads_values;
|
|
struct perf_read_values show_threads_values;
|
|
const char *pretty_printing_style;
|
|
const char *pretty_printing_style;
|
|
@@ -193,6 +194,45 @@ out:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Events in data file are not collect in groups, but we still want
|
|
|
|
+ * the group display. Set the artificial group and set the leader's
|
|
|
|
+ * forced_leader flag to notify the display code.
|
|
|
|
+ */
|
|
|
|
+static void setup_forced_leader(struct report *report,
|
|
|
|
+ struct perf_evlist *evlist)
|
|
|
|
+{
|
|
|
|
+ if (report->group_set && !evlist->nr_groups) {
|
|
|
|
+ struct perf_evsel *leader = perf_evlist__first(evlist);
|
|
|
|
+
|
|
|
|
+ perf_evlist__set_leader(evlist);
|
|
|
|
+ leader->forced_leader = true;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int process_feature_event(struct perf_tool *tool,
|
|
|
|
+ union perf_event *event,
|
|
|
|
+ struct perf_session *session __maybe_unused)
|
|
|
|
+{
|
|
|
|
+ struct report *rep = container_of(tool, struct report, tool);
|
|
|
|
+
|
|
|
|
+ if (event->feat.feat_id < HEADER_LAST_FEATURE)
|
|
|
|
+ return perf_event__process_feature(tool, event, session);
|
|
|
|
+
|
|
|
|
+ if (event->feat.feat_id != HEADER_LAST_FEATURE) {
|
|
|
|
+ pr_err("failed: wrong feature ID: %" PRIu64 "\n",
|
|
|
|
+ event->feat.feat_id);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * All features are received, we can force the
|
|
|
|
+ * group if needed.
|
|
|
|
+ */
|
|
|
|
+ setup_forced_leader(rep, session->evlist);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int process_sample_event(struct perf_tool *tool,
|
|
static int process_sample_event(struct perf_tool *tool,
|
|
union perf_event *event,
|
|
union perf_event *event,
|
|
struct perf_sample *sample,
|
|
struct perf_sample *sample,
|
|
@@ -940,7 +980,6 @@ int cmd_report(int argc, const char **argv)
|
|
"perf report [<options>]",
|
|
"perf report [<options>]",
|
|
NULL
|
|
NULL
|
|
};
|
|
};
|
|
- bool group_set = false;
|
|
|
|
struct report report = {
|
|
struct report report = {
|
|
.tool = {
|
|
.tool = {
|
|
.sample = process_sample_event,
|
|
.sample = process_sample_event,
|
|
@@ -958,7 +997,7 @@ int cmd_report(int argc, const char **argv)
|
|
.id_index = perf_event__process_id_index,
|
|
.id_index = perf_event__process_id_index,
|
|
.auxtrace_info = perf_event__process_auxtrace_info,
|
|
.auxtrace_info = perf_event__process_auxtrace_info,
|
|
.auxtrace = perf_event__process_auxtrace,
|
|
.auxtrace = perf_event__process_auxtrace,
|
|
- .feature = perf_event__process_feature,
|
|
|
|
|
|
+ .feature = process_feature_event,
|
|
.ordered_events = true,
|
|
.ordered_events = true,
|
|
.ordering_requires_timestamps = true,
|
|
.ordering_requires_timestamps = true,
|
|
},
|
|
},
|
|
@@ -1060,7 +1099,7 @@ int cmd_report(int argc, const char **argv)
|
|
"Specify disassembler style (e.g. -M intel for intel syntax)"),
|
|
"Specify disassembler style (e.g. -M intel for intel syntax)"),
|
|
OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
|
|
OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
|
|
"Show a column with the sum of periods"),
|
|
"Show a column with the sum of periods"),
|
|
- OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &group_set,
|
|
|
|
|
|
+ OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &report.group_set,
|
|
"Show event group information together"),
|
|
"Show event group information together"),
|
|
OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
|
|
OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
|
|
"use branch records for per branch histogram filling",
|
|
"use branch records for per branch histogram filling",
|
|
@@ -1177,17 +1216,7 @@ repeat:
|
|
has_br_stack = perf_header__has_feat(&session->header,
|
|
has_br_stack = perf_header__has_feat(&session->header,
|
|
HEADER_BRANCH_STACK);
|
|
HEADER_BRANCH_STACK);
|
|
|
|
|
|
- /*
|
|
|
|
- * Events in data file are not collect in groups, but we still want
|
|
|
|
- * the group display. Set the artificial group and set the leader's
|
|
|
|
- * forced_leader flag to notify the display code.
|
|
|
|
- */
|
|
|
|
- if (group_set && !session->evlist->nr_groups) {
|
|
|
|
- struct perf_evsel *leader = perf_evlist__first(session->evlist);
|
|
|
|
-
|
|
|
|
- perf_evlist__set_leader(session->evlist);
|
|
|
|
- leader->forced_leader = true;
|
|
|
|
- }
|
|
|
|
|
|
+ setup_forced_leader(&report, session->evlist);
|
|
|
|
|
|
if (itrace_synth_opts.last_branch)
|
|
if (itrace_synth_opts.last_branch)
|
|
has_br_stack = true;
|
|
has_br_stack = true;
|