|
@@ -213,10 +213,20 @@ static void perf_stat__reset_stats(void)
|
|
static int create_perf_stat_counter(struct perf_evsel *evsel)
|
|
static int create_perf_stat_counter(struct perf_evsel *evsel)
|
|
{
|
|
{
|
|
struct perf_event_attr *attr = &evsel->attr;
|
|
struct perf_event_attr *attr = &evsel->attr;
|
|
|
|
+ struct perf_evsel *leader = evsel->leader;
|
|
|
|
|
|
- if (stat_config.scale)
|
|
|
|
|
|
+ if (stat_config.scale) {
|
|
attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
|
|
attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
|
|
PERF_FORMAT_TOTAL_TIME_RUNNING;
|
|
PERF_FORMAT_TOTAL_TIME_RUNNING;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The event is part of non trivial group, let's enable
|
|
|
|
+ * the group read (for leader) and ID retrieval for all
|
|
|
|
+ * members.
|
|
|
|
+ */
|
|
|
|
+ if (leader->nr_members > 1)
|
|
|
|
+ attr->read_format |= PERF_FORMAT_ID|PERF_FORMAT_GROUP;
|
|
|
|
|
|
attr->inherit = !no_inherit;
|
|
attr->inherit = !no_inherit;
|
|
|
|
|
|
@@ -333,13 +343,21 @@ static int read_counter(struct perf_evsel *counter)
|
|
struct perf_counts_values *count;
|
|
struct perf_counts_values *count;
|
|
|
|
|
|
count = perf_counts(counter->counts, cpu, thread);
|
|
count = perf_counts(counter->counts, cpu, thread);
|
|
- if (perf_evsel__read(counter, cpu, thread, count)) {
|
|
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The leader's group read loads data into its group members
|
|
|
|
+ * (via perf_evsel__read_counter) and sets threir count->loaded.
|
|
|
|
+ */
|
|
|
|
+ if (!count->loaded &&
|
|
|
|
+ perf_evsel__read_counter(counter, cpu, thread)) {
|
|
counter->counts->scaled = -1;
|
|
counter->counts->scaled = -1;
|
|
perf_counts(counter->counts, cpu, thread)->ena = 0;
|
|
perf_counts(counter->counts, cpu, thread)->ena = 0;
|
|
perf_counts(counter->counts, cpu, thread)->run = 0;
|
|
perf_counts(counter->counts, cpu, thread)->run = 0;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ count->loaded = false;
|
|
|
|
+
|
|
if (STAT_RECORD) {
|
|
if (STAT_RECORD) {
|
|
if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
|
|
if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
|
|
pr_err("failed to write stat event\n");
|
|
pr_err("failed to write stat event\n");
|
|
@@ -559,6 +577,11 @@ static int store_counter_ids(struct perf_evsel *counter)
|
|
return __store_counter_ids(counter, cpus, threads);
|
|
return __store_counter_ids(counter, cpus, threads);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool perf_evsel__should_store_id(struct perf_evsel *counter)
|
|
|
|
+{
|
|
|
|
+ return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID;
|
|
|
|
+}
|
|
|
|
+
|
|
static int __run_perf_stat(int argc, const char **argv)
|
|
static int __run_perf_stat(int argc, const char **argv)
|
|
{
|
|
{
|
|
int interval = stat_config.interval;
|
|
int interval = stat_config.interval;
|
|
@@ -631,7 +654,8 @@ try_again:
|
|
if (l > unit_width)
|
|
if (l > unit_width)
|
|
unit_width = l;
|
|
unit_width = l;
|
|
|
|
|
|
- if (STAT_RECORD && store_counter_ids(counter))
|
|
|
|
|
|
+ if (perf_evsel__should_store_id(counter) &&
|
|
|
|
+ store_counter_ids(counter))
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|