Commit c735b0a5 authored by Florian Fischer's avatar Florian Fischer Committed by Arnaldo Carvalho de Melo
Browse files

perf stat: Introduce stats for the user and system rusage times



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: default avatarFlorian 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent c60664de
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
		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
+2 −0
Original line number Diff line number Diff line
@@ -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)
+21 −0
Original line number Diff line number Diff line
@@ -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,