perf stat: Introduce stats for the user and system rusage times
authorFlorian Fischer <florian.fischer@muhq.space>
Wed, 20 Apr 2022 10:23:52 +0000 (12:23 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 20 Apr 2022 16:38:41 +0000 (13:38 -0300)
This is preparation for exporting rusage values as tool events.

Add new global stats tracking the values obtained via rusage.

For now only ru_utime and ru_stime are part of the tracked stats.

Both are stored as nanoseconds to be consistent with 'duration_time',
although the finest resolution the struct timeval data in rusage
provides are microseconds.

Signed-off-by: Florian Fischer <florian.fischer@muhq.space>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Link: https://lore.kernel.org/r/20220420102354.468173-2-florian.fischer@muhq.space
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-stat.c
tools/perf/util/stat-shadow.c
tools/perf/util/stat.h

index a96f106..61faffb 100644 (file)
@@ -216,6 +216,7 @@ static struct perf_stat_config stat_config = {
        .run_count              = 1,
        .metric_only_len        = METRIC_ONLY_LEN,
        .walltime_nsecs_stats   = &walltime_nsecs_stats,
+       .ru_stats               = &ru_stats,
        .big_num                = true,
        .ctl_fd                 = -1,
        .ctl_fd_ack             = -1,
@@ -1010,8 +1011,10 @@ try_again_reset:
                evlist__reset_prev_raw_counts(evsel_list);
                runtime_stat_reset(&stat_config);
                perf_stat__reset_shadow_per_stat(&rt_stat);
-       } else
+       } else {
                update_stats(&walltime_nsecs_stats, t1 - t0);
+               update_rusage_stats(&ru_stats, &stat_config.ru_data);
+       }
 
        /*
         * Closing a group leader splits the group, and as we only disable
index 10af780..ea4c35e 100644 (file)
@@ -26,6 +26,7 @@
 
 struct runtime_stat rt_stat;
 struct stats walltime_nsecs_stats;
+struct rusage_stats ru_stats;
 
 struct saved_value {
        struct rb_node rb_node;
@@ -199,6 +200,7 @@ void perf_stat__reset_shadow_stats(void)
 {
        reset_stat(&rt_stat);
        memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
+       memset(&ru_stats, 0, sizeof(ru_stats));
 }
 
 void perf_stat__reset_shadow_per_stat(struct runtime_stat *st)
index 335d19c..e31c94d 100644 (file)
@@ -108,6 +108,11 @@ struct runtime_stat {
        struct rblist value_list;
 };
 
+struct rusage_stats {
+       struct stats ru_utime_usec_stat;
+       struct stats ru_stime_usec_stat;
+};
+
 typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *config, struct perf_cpu cpu);
 
 struct perf_stat_config {
@@ -148,6 +153,7 @@ struct perf_stat_config {
        const char              *csv_sep;
        struct stats            *walltime_nsecs_stats;
        struct rusage            ru_data;
+       struct rusage_stats              *ru_stats;
        struct cpu_aggr_map     *aggr_map;
        aggr_get_id_t            aggr_get_id;
        struct cpu_aggr_map     *cpus_aggr_map;
@@ -177,6 +183,20 @@ static inline void init_stats(struct stats *stats)
        stats->max  = 0;
 }
 
+static inline void init_rusage_stats(struct rusage_stats *ru_stats) {
+       init_stats(&ru_stats->ru_utime_usec_stat);
+       init_stats(&ru_stats->ru_stime_usec_stat);
+}
+
+static inline void update_rusage_stats(struct rusage_stats *ru_stats, struct rusage* rusage) {
+       const u64 us_to_ns = 1000;
+       const u64 s_to_ns = 1000000000;
+       update_stats(&ru_stats->ru_utime_usec_stat,
+                    (rusage->ru_utime.tv_usec * us_to_ns + rusage->ru_utime.tv_sec * s_to_ns));
+       update_stats(&ru_stats->ru_stime_usec_stat,
+                    (rusage->ru_stime.tv_usec * us_to_ns + rusage->ru_stime.tv_sec * s_to_ns));
+}
+
 struct evsel;
 struct evlist;
 
@@ -196,6 +216,7 @@ bool __perf_stat_evsel__is(struct evsel *evsel, enum perf_stat_evsel_id id);
 
 extern struct runtime_stat rt_stat;
 extern struct stats walltime_nsecs_stats;
+extern struct rusage_stats ru_stats;
 
 typedef void (*print_metric_t)(struct perf_stat_config *config,
                               void *ctx, const char *color, const char *unit,