Add the powerpc-htm.c decode stub and wire the dispatch in
perf_event__process_auxtrace_info() to call
powerpc_htm_process_auxtrace_info().

Signed-off-by: Athira Rajeev <[email protected]>
---
Changes in V4:
- Add #include <linux/zalloc.h> to the powerpc-htm.c stub.  V3 omitted
it from the stub; without it the zalloc() call added in patch 6 would
require the include to be introduced there instead of alongside the
struct definition it serves.  Moving it here keeps the allocation
header co-located with the powerpc_htm struct that patch 6 expands.

Changes in V3:
- Change powerpc_htm_dump_event() parameter from size_t to u64 and
use %" PRIu64 ", matching the type of buffer->size and avoiding
truncation on 32-bit platforms.
- Add #include <inttypes.h> for PRIu64.
- Remove the htm->auxtrace_type = auxtrace_info->type assignment
that was added here in V2; this field is now set from
priv[POWERPC_HTM_PMU_TYPE] in patch 6 where the full processing
logic lives.
- Do not re-add PERF_AUXTRACE_POWERPC_HTM to auxtrace.h or the
stub case in auxtrace.c; those are now in patch 2. This patch only
adds the powerpc-htm.c decode stub and wires the dispatch to call
powerpc_htm_process_auxtrace_info().

Changes in V2:
- Scope narrowed: this patch now only adds the PERF_AUXTRACE_POWERPC_HTM
  enum constant to auxtrace.h and wires the dispatch in
  perf_event__process_auxtrace_info() to call
  powerpc_htm_process_auxtrace_info().  It also amends htm_info_fill()
  (from patch 2) to set auxtrace_info->type now that the constant is
  defined.
- All file-writing and decoding logic is moved to patch 6.
- Patch is now 5/6 instead of 5/9.

 tools/perf/util/Build         |   1 +
 tools/perf/util/auxtrace.c    |   2 +
 tools/perf/util/powerpc-htm.c | 118 ++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 tools/perf/util/powerpc-htm.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 330311cac550..7fa354853d2a 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -141,6 +141,7 @@ perf-util-y += hisi-ptt.o
 perf-util-y += hisi-ptt-decoder/
 perf-util-y += s390-cpumsf.o
 perf-util-y += powerpc-vpadtl.o
+perf-util-y += powerpc-htm.o
 
 ifdef CONFIG_LIBOPENCSD
 perf-util-y += cs-etm.o
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 31c0db933f61..9f32f54fad43 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -1429,6 +1429,8 @@ int perf_event__process_auxtrace_info(const struct 
perf_tool *tool __maybe_unuse
                err = powerpc_vpadtl_process_auxtrace_info(event, session);
                break;
        case PERF_AUXTRACE_POWERPC_HTM:
+               err = powerpc_htm_process_auxtrace_info(event, session);
+               break;
        case PERF_AUXTRACE_UNKNOWN:
        default:
                return -EINVAL;
diff --git a/tools/perf/util/powerpc-htm.c b/tools/perf/util/powerpc-htm.c
new file mode 100644
index 000000000000..0ef7ecd18c6f
--- /dev/null
+++ b/tools/perf/util/powerpc-htm.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <endian.h>
+#include <linux/zalloc.h>
+#include "util/evsel.h"
+#include "util/evlist.h"
+#include "util/session.h"
+#include "auxtrace.h"
+#include "color.h"
+#include "powerpc-htm.h"
+#include "debug.h"
+#include "sample.h"
+
+struct powerpc_htm {
+       struct auxtrace         auxtrace;
+       struct auxtrace_queues  queues;
+       struct auxtrace_heap    heap;
+       u32                     auxtrace_type;
+       struct perf_session     *session;
+       struct machine          *machine;
+};
+
+static void powerpc_htm_dump_event(u64 len)
+{
+       const char *color = PERF_COLOR_BLUE;
+
+       if (dump_trace) {
+               color_fprintf(stdout, color,
+                       ". ... HTM PMU data: size %" PRIu64 " bytes\n", len);
+       }
+}
+
+static int powerpc_htm_process_event(struct perf_session *session 
__maybe_unused,
+                                    union perf_event *event __maybe_unused,
+                                    struct perf_sample *sample __maybe_unused,
+                                    const struct perf_tool *tool 
__maybe_unused)
+{
+       return 0;
+}
+
+static int powerpc_htm_process_auxtrace_event(struct perf_session *session 
__maybe_unused,
+                                             union perf_event *event,
+                                             const struct perf_tool *tool 
__maybe_unused)
+{
+       if (dump_trace)
+               powerpc_htm_dump_event(event->auxtrace.size);
+
+       return 0;
+}
+
+static int powerpc_htm_flush(struct perf_session *session __maybe_unused,
+                            const struct perf_tool *tool __maybe_unused)
+{
+       return 0;
+}
+
+static void powerpc_htm_free_events(struct perf_session *session)
+{
+       struct powerpc_htm *htm;
+
+       if (!session || !session->auxtrace)
+               return;
+
+       htm = container_of(session->auxtrace, struct powerpc_htm, auxtrace);
+       auxtrace_queues__free(&htm->queues);
+}
+
+static void powerpc_htm_free(struct perf_session *session)
+{
+       struct powerpc_htm *htm;
+
+       if (!session || !session->auxtrace)
+               return;
+
+       htm = container_of(session->auxtrace, struct powerpc_htm, auxtrace);
+       powerpc_htm_free_events(session);
+       session->auxtrace = NULL;
+       free(htm);
+}
+
+int powerpc_htm_process_auxtrace_info(union perf_event *event,
+                                     struct perf_session *session)
+{
+       struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
+       struct powerpc_htm *htm;
+       int err;
+
+       if (auxtrace_info->header.size < sizeof(struct 
perf_record_auxtrace_info) +
+                                        HTM_AUXTRACE_PRIV_FIXED)
+               return -EINVAL;
+
+       htm = zalloc(sizeof(struct powerpc_htm));
+       if (!htm)
+               return -ENOMEM;
+
+       err = auxtrace_queues__init(&htm->queues);
+       if (err) {
+               free(htm);
+               return err;
+       }
+
+       htm->session = session;
+       htm->machine = &session->machines.host;
+       htm->auxtrace.process_event = powerpc_htm_process_event;
+       htm->auxtrace.process_auxtrace_event = 
powerpc_htm_process_auxtrace_event;
+       htm->auxtrace.flush_events = powerpc_htm_flush;
+       htm->auxtrace.free_events = powerpc_htm_free_events;
+       htm->auxtrace.free = powerpc_htm_free;
+       session->auxtrace = &htm->auxtrace;
+
+       return 0;
+}
-- 
2.43.0


Reply via email to