Skip to content

Commit 25f69c6

Browse files
Changbin Duacmel
authored andcommitted
perf stat: Fix counting when initial delay configured
When creating counters with initial delay configured, the enable_on_exec field is not set. So we need to enable the counters later. The problem is, when a workload is specified the target__none() is true. So we also need to check stat_config.initial_delay. In this change, we add a new field 'initial_delay' for struct target which could be shared by other subcommands. And define target__enable_on_exec() which returns whether enable_on_exec should be set on normal cases. Before this fix the event is not counted: $ ./perf stat -e instructions -D 100 sleep 2 Events disabled Events enabled Performance counter stats for 'sleep 2': <not counted> instructions 1.901661124 seconds time elapsed 0.001602000 seconds user 0.000000000 seconds sys After fix it works: $ ./perf stat -e instructions -D 100 sleep 2 Events disabled Events enabled Performance counter stats for 'sleep 2': 404,214 instructions 1.901743475 seconds time elapsed 0.001617000 seconds user 0.000000000 seconds sys Fixes: c587e77 ("perf stat: Do not delay the workload with --delay") Signed-off-by: Changbin Du <[email protected]> Acked-by: Namhyung Kim <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Hui Wang <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent a98c071 commit 25f69c6

File tree

4 files changed

+18
-16
lines changed

4 files changed

+18
-16
lines changed

tools/perf/builtin-stat.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -539,12 +539,7 @@ static int enable_counters(void)
539539
return err;
540540
}
541541

542-
/*
543-
* We need to enable counters only if:
544-
* - we don't have tracee (attaching to task or cpu)
545-
* - we have initial delay configured
546-
*/
547-
if (!target__none(&target)) {
542+
if (!target__enable_on_exec(&target)) {
548543
if (!all_counters_use_bpf)
549544
evlist__enable(evsel_list);
550545
}
@@ -914,7 +909,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
914909
return err;
915910
}
916911

917-
if (stat_config.initial_delay) {
912+
if (target.initial_delay) {
918913
pr_info(EVLIST_DISABLED_MSG);
919914
} else {
920915
err = enable_counters();
@@ -926,8 +921,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
926921
if (forks)
927922
evlist__start_workload(evsel_list);
928923

929-
if (stat_config.initial_delay > 0) {
930-
usleep(stat_config.initial_delay * USEC_PER_MSEC);
924+
if (target.initial_delay > 0) {
925+
usleep(target.initial_delay * USEC_PER_MSEC);
931926
err = enable_counters();
932927
if (err)
933928
return -1;
@@ -1248,7 +1243,7 @@ static struct option stat_options[] = {
12481243
"aggregate counts per thread", AGGR_THREAD),
12491244
OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode,
12501245
"aggregate counts per numa node", AGGR_NODE),
1251-
OPT_INTEGER('D', "delay", &stat_config.initial_delay,
1246+
OPT_INTEGER('D', "delay", &target.initial_delay,
12521247
"ms to wait before starting measurement after program start (-1: start with events disabled)"),
12531248
OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
12541249
"Only print computed metrics. No raw values", enable_metric_only),

tools/perf/util/stat.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -842,11 +842,7 @@ int create_perf_stat_counter(struct evsel *evsel,
842842
if (evsel__is_group_leader(evsel)) {
843843
attr->disabled = 1;
844844

845-
/*
846-
* In case of initial_delay we enable tracee
847-
* events manually.
848-
*/
849-
if (target__none(target) && !config->initial_delay)
845+
if (target__enable_on_exec(target))
850846
attr->enable_on_exec = 1;
851847
}
852848

tools/perf/util/stat.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ struct perf_stat_config {
166166
FILE *output;
167167
unsigned int interval;
168168
unsigned int timeout;
169-
int initial_delay;
170169
unsigned int unit_width;
171170
unsigned int metric_only_len;
172171
int times;

tools/perf/util/target.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct target {
1818
bool per_thread;
1919
bool use_bpf;
2020
bool hybrid;
21+
int initial_delay;
2122
const char *attr_map;
2223
};
2324

@@ -72,6 +73,17 @@ static inline bool target__none(struct target *target)
7273
return !target__has_task(target) && !target__has_cpu(target);
7374
}
7475

76+
static inline bool target__enable_on_exec(struct target *target)
77+
{
78+
/*
79+
* Normally enable_on_exec should be set if:
80+
* 1) The tracee process is forked (not attaching to existed task or cpu).
81+
* 2) And initial_delay is not configured.
82+
* Otherwise, we enable tracee events manually.
83+
*/
84+
return target__none(target) && !target->initial_delay;
85+
}
86+
7587
static inline bool target__has_per_thread(struct target *target)
7688
{
7789
return target->system_wide && target->per_thread;

0 commit comments

Comments
 (0)