The powerpc PMU collecting Hardware Trace Macro (HTM) entries makes use of
AUX support in perf infrastructure. The PMU driver has the functionality
to collect trace entries in the aux buffer. On the tools side, this data
is made available as PERF_RECORD_AUXTRACE records. This record is
generated by "perf record" command. To enable the creation of
PERF_RECORD_AUXTRACE, add functions to initialize auxtrace records ie
"htm_recording_init()". Fill in fields for other callbacks like
info_priv_size, info_fill, free, recording options etc. Add header file
to define htm pmu specific details.

Signed-off-by: Athira Rajeev <[email protected]>
---
 tools/perf/arch/powerpc/util/Build      |   1 +
 tools/perf/arch/powerpc/util/auxtrace.c |  10 ++-
 tools/perf/arch/powerpc/util/htm.c      | 113 ++++++++++++++++++++++++
 tools/perf/util/powerpc-htm.h           |  23 +++++
 4 files changed, 146 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/arch/powerpc/util/htm.c
 create mode 100644 tools/perf/util/powerpc-htm.h

diff --git a/tools/perf/arch/powerpc/util/Build 
b/tools/perf/arch/powerpc/util/Build
index 7819c8f5af2d..297152591046 100644
--- a/tools/perf/arch/powerpc/util/Build
+++ b/tools/perf/arch/powerpc/util/Build
@@ -8,3 +8,4 @@ perf-util-$(CONFIG_LIBDW) += skip-callchain-idx.o
 
 perf-util-y += auxtrace.o
 perf-util-y += vpa-dtl.o
+perf-util-y += htm.o
diff --git a/tools/perf/arch/powerpc/util/auxtrace.c 
b/tools/perf/arch/powerpc/util/auxtrace.c
index 0053526329e0..ec84f8876a4a 100644
--- a/tools/perf/arch/powerpc/util/auxtrace.c
+++ b/tools/perf/arch/powerpc/util/auxtrace.c
@@ -12,6 +12,7 @@
 #include "../../util/debug.h"
 #include "../../util/auxtrace.h"
 #include "../../util/powerpc-vpadtl.h"
+#include "../../util/powerpc-htm.h"
 #include "../../util/record.h"
 
 struct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
@@ -19,6 +20,7 @@ struct auxtrace_record *auxtrace_record__init(struct evlist 
*evlist,
 {
        struct evsel *pos;
        int found_vpa_dtl = 0;
+       int found_htm = 0;
 
        /*
         * Set err value to zero here. Any fail later
@@ -31,13 +33,19 @@ struct auxtrace_record *auxtrace_record__init(struct evlist 
*evlist,
                        found_vpa_dtl = 1;
                        pos->needs_auxtrace_mmap = true;
                        break;
+               } else if (strstarts(pos->name, "htm")) {
+                       found_htm = 1;
+                       pos->needs_auxtrace_mmap = true;
+                       break;
                }
        }
 
        if (found_vpa_dtl)
                return vpa_dtl_recording_init(pos);
+       else if (found_htm)
+               return htm_recording_init(pos);
        else {
-               *err = -EINVAL;
+               *err = 0;
                return NULL;
        }
 }
diff --git a/tools/perf/arch/powerpc/util/htm.c 
b/tools/perf/arch/powerpc/util/htm.c
new file mode 100644
index 000000000000..cc733f45ac9b
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/htm.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HTM support
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/log2.h>
+#include <linux/string.h>
+#include <time.h>
+
+#include "../../util/cpumap.h"
+#include "../../util/evsel.h"
+#include "../../util/evlist.h"
+#include "../../util/session.h"
+#include "../../util/util.h"
+#include "../../util/pmu.h"
+#include "../../util/debug.h"
+#include "../../util/auxtrace.h"
+#include "../../util/powerpc-htm.h"
+#include "../../util/record.h"
+#include <internal/lib.h> // page_size
+#include <errno.h>
+
+#define KiB(x) ((x) * 1024)
+
+static int
+htm_recording_options(struct auxtrace_record *ar __maybe_unused,
+                       struct evlist *evlist __maybe_unused,
+                       struct record_opts *opts)
+{
+       struct evsel *pos;
+
+       opts->full_auxtrace = true;
+
+       if (opts->target.system_wide) {
+               pr_info("System wide monitoring not supported, specify -C 
<cpu>\n");
+               return -EINVAL;
+       } else if (!opts->target.cpu_list) {
+               pr_info("-C option not provided, specify -C <cpu> to use HTM 
event\n");
+               return -EINVAL;
+       }
+
+       /*
+        * Set auxtrace_mmap_pages to minimum
+        * two pages
+        */
+       if (!opts->auxtrace_mmap_pages) {
+               opts->auxtrace_mmap_pages = KiB(128) / page_size;
+               if (opts->mmap_pages == UINT_MAX)
+                       opts->mmap_pages = KiB(256) / page_size;
+       }
+
+       evlist__for_each_entry(evlist, pos) {
+               if (strstarts(pos->name, "htm")) {
+                       pos->needs_auxtrace_mmap = true;
+                       pos->core.attr.aux_watermark = 
opts->auxtrace_mmap_pages * (size_t)page_size;
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static size_t htm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
+                                       struct evlist *evlist __maybe_unused)
+{
+       return HTM_AUXTRACE_PRIV_SIZE;
+}
+
+static int
+htm_info_fill(struct auxtrace_record *itr __maybe_unused,
+               struct perf_session *session __maybe_unused,
+               struct perf_record_auxtrace_info *auxtrace_info __maybe_unused,
+               size_t priv_size __maybe_unused)
+{
+       return 0;
+}
+
+static u64 htm_reference(struct auxtrace_record *itr __maybe_unused)
+{
+       return 0;
+}
+
+static void htm_free(struct auxtrace_record *itr)
+{
+       free(itr);
+}
+
+struct auxtrace_record *htm_recording_init(struct evsel *pos)
+{
+       struct auxtrace_record *aux;
+
+       /*
+        * To obtain the auxtrace buffer file descriptor, the auxtrace event
+        * must come first.
+        */
+       evlist__to_front(pos->evlist, pos);
+
+       aux = zalloc(sizeof(*aux));
+       if (aux == NULL) {
+               pr_debug("aux record is NULL\n");
+               return NULL;
+       }
+
+       aux->recording_options = htm_recording_options;
+       aux->info_priv_size = htm_info_priv_size;
+       aux->info_fill = htm_info_fill;
+       aux->free = htm_free;
+       aux->reference = htm_reference;
+       return aux;
+}
diff --git a/tools/perf/util/powerpc-htm.h b/tools/perf/util/powerpc-htm.h
new file mode 100644
index 000000000000..be7f8c03e161
--- /dev/null
+++ b/tools/perf/util/powerpc-htm.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * HTM PMU Support
+ */
+
+#ifndef INCLUDE__PERF_POWERPC_HTM_H__
+#define INCLUDE__PERF_POWERPC_HTM_H__
+
+#define POWERPC_HTM_NAME "powerpc_htm_"
+
+enum {
+       POWERPC_HTM_TYPE,
+       HTM_AUXTRACE_PRIV_MAX,
+};
+
+#define HTM_AUXTRACE_PRIV_SIZE (HTM_AUXTRACE_PRIV_MAX * sizeof(u64))
+
+union perf_event;
+struct perf_session;
+struct perf_pmu;
+
+struct auxtrace_record *htm_recording_init(struct evsel *pos);
+#endif
-- 
2.52.0


Reply via email to