[RFC PATCH] perf/stat: Add --disable-hwdt

From: Borislav Petkov
Date: Mon Feb 06 2017 - 07:15:16 EST


Hi guys,

so I've been tracing recently on an AMD F15h which has those funky counter
constraints and am seeing this:

# ./perf stat sleep 1

Performance counter stats for 'sleep 1':

0.749208 task-clock (msec) # 0.001 CPUs utilized
1 context-switches # 0.001 M/sec
0 cpu-migrations # 0.000 K/sec
54 page-faults # 0.072 M/sec
1,122,815 cycles # 1.499 GHz
286,740 stalled-cycles-frontend # 25.54% frontend cycles idle
<not counted> stalled-cycles-backend (0.00%)
^^^^^^^^^^^^
<not counted> instructions (0.00%)
^^^^^^^^^^^^
<not counted> branches (0.00%)
<not counted> branch-misses (0.00%)

1.001550070 seconds time elapsed


The problem is that the HW watchdog thing is already taking up a
counter so when perf stat uses the default counters and when we reach
stalled-cycles-backend, we run out of counters for the remaining events.

So how about something like this:

# ./perf stat --disable-hwdt sleep 1

Performance counter stats for 'sleep 1':

0.782552 task-clock (msec) # 0.001 CPUs utilized
1 context-switches # 0.001 M/sec
0 cpu-migrations # 0.000 K/sec
55 page-faults # 0.070 M/sec
1,163,246 cycles # 1.486 GHz
293,598 stalled-cycles-frontend # 25.24% frontend cycles idle
400,017 stalled-cycles-backend # 34.39% backend cycles idle
676,505 instructions # 0.58 insn per cycle
# 0.59 stalled cycles per insn
133,822 branches # 171.007 M/sec
7,319 branch-misses # 5.47% of all branches

1.001660058 seconds time elapsed

We did explore other opportunities on IRC like sharing counters or
making the HW WDT thing a 'soft' counter but all those are nasty and
probably not really worth the trouble of touching perf core just so that
this works.

Besides, future generations don't have those constraints anymore so it
is only F15h.

Below is a silly patch as a syntactic sugar helper for perf stat. This
is just an RFC anyway, I'll do it properly with fopen() if you're ok
with the approach.

---
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a02f2e965628..7b466dde8012 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -146,6 +146,7 @@ static aggr_get_id_t aggr_get_id;
static bool append_file;
static const char *output_name;
static int output_fd;
+static bool disable_hwdt;

struct perf_stat {
bool record;
@@ -1575,6 +1576,10 @@ static void sig_atexit(void)

sigprocmask(SIG_SETMASK, &oset, NULL);

+ if (disable_hwdt)
+ if (system("echo 1 > /proc/sys/kernel/nmi_watchdog"))
+ return;
+
if (signr == -1)
return;

@@ -1659,6 +1664,8 @@ static const struct option stat_options[] = {
"Only print computed metrics. No raw values", enable_metric_only),
OPT_BOOLEAN(0, "topdown", &topdown_run,
"measure topdown level 1 statistics"),
+ OPT_BOOLEAN(0, "disable-hwdt", &disable_hwdt,
+ "Disable HW watchdog to free-up a counter"),
OPT_END()
};

@@ -2523,6 +2530,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
if (perf_stat_init_aggr_mode())
goto out;

+ if (disable_hwdt) {
+ if (system("echo 0 > /proc/sys/kernel/nmi_watchdog"))
+ goto out;
+ }
+
/*
* We dont want to block the signals - that would cause
* child tasks to inherit that and Ctrl-C would not work.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.