]> git.baikalelectronics.ru Git - kernel.git/commitdiff
perf record: Support sample-read topdown metric group
authorKan Liang <kan.liang@linux.intel.com>
Fri, 11 Sep 2020 14:48:06 +0000 (07:48 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 17 Sep 2020 18:47:58 +0000 (15:47 -0300)
With the hardware TopDown metrics feature, sample-read feature should be
supported for a topdown group, e.g., sample a non-topdown event and read
a topdown metric group. But the current perf record code errors out.

For a topdown metric group, the slots event must be the leader of the
group, but the leader slots event doesn't support sampling.

To support sample-read the topdown metric group, use the 2nd event of
the group as the "leader" for the purposes of sampling.

Only the platform with Topdown metic feature supports sample-read the
topdown group. Add arch_topdown_sample_read() to indicate whether the
topdown group supports sample-read.

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20200911144808.27603-3-kan.liang@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/arch/x86/util/topdown.c
tools/perf/util/record.c
tools/perf/util/topdown.c
tools/perf/util/topdown.h

index 597e963fb3e7daec3e8de5b8d20a1f258c4ba5c2..2f3d96aa92a58af79d9933f378eb7317bf16d83f 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <stdio.h>
 #include "api/fs/fs.h"
+#include "util/pmu.h"
 #include "util/topdown.h"
 
 /*
@@ -26,3 +27,37 @@ void arch_topdown_group_warn(void)
                "nmi_watchdog enabled with topdown. May give wrong results.\n"
                "Disable with echo 0 > /proc/sys/kernel/nmi_watchdog\n");
 }
+
+#define TOPDOWN_SLOTS          0x0400
+
+static bool is_topdown_slots_event(struct evsel *counter)
+{
+       if (!counter->pmu_name)
+               return false;
+
+       if (strcmp(counter->pmu_name, "cpu"))
+               return false;
+
+       if (counter->core.attr.config == TOPDOWN_SLOTS)
+               return true;
+
+       return false;
+}
+
+/*
+ * Check whether a topdown group supports sample-read.
+ *
+ * Only Topdown metic supports sample-read. The slots
+ * event must be the leader of the topdown group.
+ */
+
+bool arch_topdown_sample_read(struct evsel *leader)
+{
+       if (!pmu_have_event("cpu", "slots"))
+               return false;
+
+       if (is_topdown_slots_event(leader))
+               return true;
+
+       return false;
+}
index ea9aa1d7cf50132088d98ba873043d8e63d5a8d5..07e4b96a6625a697023b2b4b37dcd42494cc7748 100644 (file)
@@ -14,6 +14,7 @@
 #include "util/perf_api_probe.h"
 #include "record.h"
 #include "../perf-sys.h"
+#include "topdown.h"
 
 /*
  * evsel__config_leader_sampling() uses special rules for leader sampling.
@@ -24,7 +25,7 @@ static struct evsel *evsel__read_sampler(struct evsel *evsel, struct evlist *evl
 {
        struct evsel *leader = evsel->leader;
 
-       if (evsel__is_aux_event(leader)) {
+       if (evsel__is_aux_event(leader) || arch_topdown_sample_read(leader)) {
                evlist__for_each_entry(evlist, evsel) {
                        if (evsel->leader == leader && evsel != evsel->leader)
                                return evsel;
index a085b3c77c27366058db7195e3f97b3389f6a5db..1081b20f9891dc9f8b655d57b20e55ec472e5bb7 100644 (file)
@@ -51,3 +51,8 @@ __weak bool arch_topdown_check_group(bool *warn)
 __weak void arch_topdown_group_warn(void)
 {
 }
+
+__weak bool arch_topdown_sample_read(struct evsel *leader __maybe_unused)
+{
+       return false;
+}
index e3d70e95f4f161d28e06bf92ffb1e3fc77a182a7..2f0d0b8876393507b3efef039c57a035cc3bf857 100644 (file)
@@ -1,9 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef TOPDOWN_H
 #define TOPDOWN_H 1
+#include "evsel.h"
 
 bool arch_topdown_check_group(bool *warn);
 void arch_topdown_group_warn(void);
+bool arch_topdown_sample_read(struct evsel *leader);
 
 int topdown_filter_events(const char **attr, char **str, bool use_group);