From: Jiri Olsa <jolsa@kernel.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: lkml <linux-kernel@vger.kernel.org>,
Ingo Molnar <mingo@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
David Ahern <dsahern@gmail.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Stephane Eranian <eranian@google.com>,
Milian Wolff <milian.wolff@kdab.com>,
Andi Kleen <andi@firstfloor.org>,
Frederic Weisbecker <frederic@kernel.org>
Subject: [PATCH 10/10] perf stat: Add cputime metric support
Date: Thu, 7 Jun 2018 00:15:13 +0200 [thread overview]
Message-ID: <20180606221513.11302-11-jolsa@kernel.org> (raw)
In-Reply-To: <20180606221513.11302-1-jolsa@kernel.org>
Adding --top/--top-full options to provide metrics based
on the cputime PMU events. Simply all the metrics are simple
ratios of events to STAT_NSECS time to get their % value.
The --top option provides basic subset of cputime metrics:
# perf stat --top -I 1000
# time Idle System User Irq Softirq IO wait
1.001692690 100.0% 0.0% 0.0% 0.7% 0.2% 0.0%
2.002994039 98.9% 0.0% 0.0% 0.9% 0.2% 0.0%
3.004164038 98.5% 0.2% 0.2% 0.9% 0.2% 0.0%
4.005312773 98.9% 0.0% 0.0% 0.9% 0.2% 0.0%
The --top-full option provides all cputime metrics:
# perf stat --top-full -I 1000
# time Idle System User Irq Softirq IO wait Guest Guest nice Nice Steal
1.001750803 100.0% 0.0% 0.0% 0.7% 0.2% 0.0% 0.0% 0.0% 0.0% 0.0%
2.003159490 99.0% 0.0% 0.0% 0.9% 0.2% 0.0% 0.0% 0.0% 0.0% 0.0%
3.004358366 99.0% 0.0% 0.0% 0.9% 0.2% 0.0% 0.0% 0.0% 0.0% 0.0%
4.005592436 98.9% 0.0% 0.0% 0.9% 0.2% 0.0% 0.0% 0.0% 0.0% 0.0%
Link: http://lkml.kernel.org/n/tip-zue4s78pxc1cybb954t52ks4@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/perf/Documentation/perf-stat.txt | 65 +++++++++++++++++++++++++++++++
tools/perf/builtin-stat.c | 47 +++++++++++++++++++++++
tools/perf/util/stat-shadow.c | 70 ++++++++++++++++++++++++++++++++++
tools/perf/util/stat.c | 10 +++++
tools/perf/util/stat.h | 10 +++++
5 files changed, 202 insertions(+)
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index b10a90b6a718..9330765b7225 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -310,6 +310,71 @@ The output is SMI cycles%, equals to (aperf - unhalted core cycles) / aperf
Users who wants to get the actual value can apply --no-metric-only.
+--top::
+--top-full:
+Measure cputime PMU events and display percentage of CPU utilization rates.
+
+The --top option displays rates for following events:
+ idle system user irq softirq iowait
+
+The --top-full option displays additional rates:
+ guest guest_nice nice steal
+
+Examples:
+ # perf stat --top
+ ^C
+ Performance counter stats for 'system wide':
+
+ Idle System User Irq Softirq IO wait
+ 1.3% 89.5% 7.4% 1.8% 0.1% 0.0%
+
+ 7.282332605 seconds time elapsed
+
+ # perf stat --top-full
+ ^C
+ Performance counter stats for 'system wide':
+
+ Idle System User Irq Softirq IO wait Guest Guest nice Nice Steal
+ 5.4% 85.4% 8.6% 0.5% 0.1% 0.0% 0.0% 0.0% 0.0% 0.0%
+
+ 7.618359683 seconds time elapsed
+
+ # perf stat --top -I 1000
+ # time Idle System User Irq Softirq IO wait
+ 1.000525839 5.4% 85.3% 8.8% 0.4% 0.1% 0.0%
+ 2.001032632 5.1% 85.7% 8.7% 0.4% 0.1% 0.0%
+ 3.001388414 5.2% 85.7% 8.6% 0.4% 0.1% 0.0%
+ 4.001758697 5.7% 85.2% 8.6% 0.5% 0.1% 0.0%
+
+ # perf stat --top -I 1000 -A
+ # time CPU Idle System User Irq Softirq IO wait
+ 1.000485174 CPU0 6.9% 84.0% 8.6% 0.5% 0.1% 0.0%
+ 1.000485174 CPU1 5.5% 84.8% 9.1% 0.5% 0.1% 0.0%
+ 1.000485174 CPU2 5.5% 86.6% 7.4% 0.5% 0.1% 0.0%
+ ...
+
+ # perf stat --top -I 1000 --per-core
+ # time core cpus Idle System User Irq Softirq IO wait
+ 1.000450719 S0-C0 2 4.6% 87.0% 7.9% 0.4% 0.1% 0.0%
+ 1.000450719 S0-C1 2 4.8% 86.3% 8.3% 0.4% 0.1% 0.0%
+ 1.000450719 S0-C2 2 5.3% 86.3% 7.8% 0.4% 0.1% 0.0%
+ 1.000450719 S0-C3 2 5.2% 85.5% 8.7% 0.4% 0.1% 0.0%
+ 1.000450719 S0-C4 2 4.5% 86.7% 8.3% 0.4% 0.1% 0.0%
+
+ # perf stat --top ./perf bench sched messaging -l 10000
+ ...
+ Total time: 7.089 [sec]
+
+ Performance counter stats for './perf bench sched messaging -l 10000':
+
+ Idle System User Irq Softirq IO wait
+ 0.0% 90.1% 8.9% 0.5% 0.1% 0.0%
+
+ 7.186366800 seconds time elapsed
+
+ 14.527066000 seconds user
+ 146.254278000 seconds sys
+
EXAMPLES
--------
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index cc3dd85d5a60..dfe5a0d926c0 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -135,6 +135,34 @@ static const char *smi_cost_attrs = {
"}"
};
+static const char *top_attrs = {
+ "{"
+ "cpu-clock,"
+ "cputime/idle/,"
+ "cputime/system/,"
+ "cputime/user/,"
+ "cputime/irq/,"
+ "cputime/softirq/,"
+ "cputime/iowait/"
+ "}"
+};
+
+static const char *top_full_attrs = {
+ "{"
+ "cpu-clock,"
+ "cputime/idle/,"
+ "cputime/system/,"
+ "cputime/user/,"
+ "cputime/irq/,"
+ "cputime/softirq/,"
+ "cputime/iowait/,"
+ "cputime/guest/,"
+ "cputime/guest_nice/,"
+ "cputime/nice/,"
+ "cputime/steal/"
+ "}"
+};
+
static struct perf_evlist *evsel_list;
static struct rblist metric_events;
@@ -154,6 +182,8 @@ static bool null_run = false;
static int detailed_run = 0;
static bool transaction_run;
static bool topdown_run = false;
+static bool top_run = false;
+static bool top_run_full = false;
static bool smi_cost = false;
static bool smi_reset = false;
static bool big_num = true;
@@ -2088,6 +2118,8 @@ static const struct option stat_options[] = {
"measure topdown level 1 statistics"),
OPT_BOOLEAN(0, "smi-cost", &smi_cost,
"measure SMI cost"),
+ OPT_BOOLEAN(0, "top", &top_run, "show CPU utilization"),
+ OPT_BOOLEAN(0, "top-full", &top_run_full, "show extended CPU utilization"),
OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
"monitor specified metrics or metric groups (separated by ,)",
parse_metric_groups),
@@ -2474,6 +2506,21 @@ static int add_default_attributes(void)
return 0;
}
+ if (top_run || top_run_full) {
+ const char *attrs = top_run ? top_attrs : top_full_attrs;
+
+ err = parse_events(evsel_list, attrs, &errinfo);
+ if (err) {
+ fprintf(stderr, "Cannot set up cputime events\n");
+ parse_events_print_error(&errinfo, attrs);
+ return -1;
+ }
+ if (!force_metric_only)
+ metric_only = true;
+ metric_only_len = 10;
+ return 0;
+ }
+
if (smi_cost) {
int smi;
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 594d14a02b67..06365dba1753 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -750,6 +750,46 @@ static void generic_metric(const char *metric_expr,
print_metric(ctxp, NULL, NULL, "", 0);
}
+static void cputime_color_name(struct perf_evsel *evsel,
+ const char **color, const char **name,
+ double ratio)
+{
+ if (perf_stat_evsel__is(evsel, CPUTIME_IDLE)) {
+ if (ratio < 0.8)
+ *color = PERF_COLOR_GREEN;
+ if (ratio < 0.5)
+ *color = PERF_COLOR_RED;
+ *name = "Idle";
+ return;
+ }
+
+ if (ratio > (MIN_GREEN / 100))
+ *color = PERF_COLOR_GREEN;
+ if (ratio > (MIN_RED / 100))
+ *color = PERF_COLOR_RED;
+
+ if (perf_stat_evsel__is(evsel, CPUTIME_GUEST))
+ *name = "Guest";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_GUEST_NICE))
+ *name = "Guest nice";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_IOWAIT))
+ *name = "IO wait";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_IRQ))
+ *name = "Irq";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_NICE))
+ *name = "Nice";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_SOFTIRQ))
+ *name = "Softirq";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_STEAL))
+ *name = "Steal";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_SYSTEM))
+ *name = "System";
+ else if (perf_stat_evsel__is(evsel, CPUTIME_USER))
+ *name = "User";
+ else
+ *name = "unknown";
+}
+
void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
double avg, int cpu,
struct perf_stat_output_ctx *out,
@@ -960,6 +1000,36 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
be_bound * 100.);
else
print_metric(ctxp, NULL, NULL, name, 0);
+ } else if (perf_stat_evsel__is(evsel, CPUTIME_GUEST) ||
+ perf_stat_evsel__is(evsel, CPUTIME_GUEST_NICE) ||
+ perf_stat_evsel__is(evsel, CPUTIME_IDLE) ||
+ perf_stat_evsel__is(evsel, CPUTIME_IOWAIT) ||
+ perf_stat_evsel__is(evsel, CPUTIME_IRQ) ||
+ perf_stat_evsel__is(evsel, CPUTIME_NICE) ||
+ perf_stat_evsel__is(evsel, CPUTIME_SOFTIRQ) ||
+ perf_stat_evsel__is(evsel, CPUTIME_STEAL) ||
+ perf_stat_evsel__is(evsel, CPUTIME_SYSTEM) ||
+ perf_stat_evsel__is(evsel, CPUTIME_USER)) {
+
+ const char *name = NULL;
+
+ total = runtime_stat_avg(st, STAT_NSECS, ctx, cpu);
+
+ if (total)
+ ratio = avg / total;
+
+ cputime_color_name(evsel, &color, &name, ratio);
+
+ /*
+ * The cputime meassures are tricky, we can easily get some noise
+ * over 100% ... so let's be proactive and don't confuse users ;-)
+ */
+ ratio = min(1., ratio);
+
+ if (total)
+ print_metric(ctxp, color, "%8.1f%%", name, ratio * 100.);
+ else
+ print_metric(ctxp, NULL, NULL, name, 0);
} else if (evsel->metric_expr) {
generic_metric(evsel->metric_expr, evsel->metric_events, evsel->name,
evsel->metric_name, avg, cpu, out, st);
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index a0061e0b0fad..aa78a7188029 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -89,6 +89,16 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
ID(TOPDOWN_RECOVERY_BUBBLES, topdown-recovery-bubbles),
ID(SMI_NUM, msr/smi/),
ID(APERF, msr/aperf/),
+ ID(CPUTIME_GUEST, cputime/guest/),
+ ID(CPUTIME_GUEST_NICE, cputime/guest_nice/),
+ ID(CPUTIME_IDLE, cputime/idle/),
+ ID(CPUTIME_IOWAIT, cputime/iowait/),
+ ID(CPUTIME_IRQ, cputime/irq/),
+ ID(CPUTIME_NICE, cputime/nice/),
+ ID(CPUTIME_SOFTIRQ, cputime/softirq/),
+ ID(CPUTIME_STEAL, cputime/steal/),
+ ID(CPUTIME_SYSTEM, cputime/system/),
+ ID(CPUTIME_USER, cputime/user/),
};
#undef ID
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 36efb986f7fc..24373873fc76 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -25,6 +25,16 @@ enum perf_stat_evsel_id {
PERF_STAT_EVSEL_ID__TOPDOWN_RECOVERY_BUBBLES,
PERF_STAT_EVSEL_ID__SMI_NUM,
PERF_STAT_EVSEL_ID__APERF,
+ PERF_STAT_EVSEL_ID__CPUTIME_GUEST,
+ PERF_STAT_EVSEL_ID__CPUTIME_GUEST_NICE,
+ PERF_STAT_EVSEL_ID__CPUTIME_IDLE,
+ PERF_STAT_EVSEL_ID__CPUTIME_IOWAIT,
+ PERF_STAT_EVSEL_ID__CPUTIME_IRQ,
+ PERF_STAT_EVSEL_ID__CPUTIME_NICE,
+ PERF_STAT_EVSEL_ID__CPUTIME_SOFTIRQ,
+ PERF_STAT_EVSEL_ID__CPUTIME_STEAL,
+ PERF_STAT_EVSEL_ID__CPUTIME_SYSTEM,
+ PERF_STAT_EVSEL_ID__CPUTIME_USER,
PERF_STAT_EVSEL_ID__MAX,
};
--
2.13.6
next prev parent reply other threads:[~2018-06-06 22:15 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-06 22:15 [RFC 00/10] perf: Add cputime events/metrics Jiri Olsa
2018-06-06 22:15 ` [PATCH 01/10] perf tools: Uniquify the event name if there's no other matched event Jiri Olsa
2018-06-06 23:19 ` Andi Kleen
2018-06-07 6:22 ` Jiri Olsa
2018-06-07 16:09 ` Stephane Eranian
2018-06-08 0:06 ` Jiri Olsa
2018-06-06 22:15 ` [PATCH 02/10] perf tools: Fix error index for pmu event parser Jiri Olsa
2018-06-07 18:53 ` Arnaldo Carvalho de Melo
2018-06-14 6:21 ` [tip:perf/urgent] " tip-bot for Jiri Olsa
2018-06-06 22:15 ` [PATCH 03/10] perf stat: Add --interval-clear option Jiri Olsa
2018-06-07 18:57 ` Arnaldo Carvalho de Melo
2018-06-14 6:21 ` [tip:perf/urgent] " tip-bot for Jiri Olsa
2018-06-06 22:15 ` [PATCH 04/10] perf stat: Use only color_fprintf call in print_metric_only Jiri Olsa
2018-06-07 19:00 ` Arnaldo Carvalho de Melo
2018-06-14 6:22 ` [tip:perf/urgent] " tip-bot for Jiri Olsa
2018-06-06 22:15 ` [PATCH 05/10] perf stat: Fix metric column display Jiri Olsa
2018-06-07 19:00 ` Arnaldo Carvalho de Melo
2018-06-14 6:22 ` [tip:perf/urgent] perf stat: Fix metric column header display alignment tip-bot for Jiri Olsa
2018-06-06 22:15 ` [PATCH 06/10] perf stat: Allow to specify specific metric column len Jiri Olsa
2018-06-14 6:23 ` [tip:perf/urgent] " tip-bot for Jiri Olsa
2018-06-06 22:15 ` [PATCH 07/10] perf stat: Add event parsing error handling to add_default_attributes Jiri Olsa
2018-06-07 19:04 ` Arnaldo Carvalho de Melo
2018-06-07 19:05 ` Arnaldo Carvalho de Melo
2018-06-14 6:23 ` [tip:perf/urgent] " tip-bot for Jiri Olsa
2018-06-06 22:15 ` [PATCH 08/10] perf/cputime: Add cputime pmu Jiri Olsa
2018-06-06 22:15 ` [PATCH 09/10] perf/cputime: Don't stop idle tick if there's live cputime event Jiri Olsa
2018-06-07 15:45 ` Andi Kleen
2018-06-07 16:01 ` Stephane Eranian
2018-06-08 0:12 ` Jiri Olsa
2018-06-06 22:15 ` Jiri Olsa [this message]
2018-06-06 23:10 ` [RFC 00/10] perf: Add cputime events/metrics Andi Kleen
2018-09-26 14:44 ` Milian Wolff
2018-09-26 21:48 ` Jiri Olsa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180606221513.11302-11-jolsa@kernel.org \
--to=jolsa@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=andi@firstfloor.org \
--cc=dsahern@gmail.com \
--cc=eranian@google.com \
--cc=frederic@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=milian.wolff@kdab.com \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.