From e636c8d336489bf3eed5878299e6cc045bbad077 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:17:29 +0000
Subject: [PATCH] debug lk
---
kernel/tools/perf/arch/powerpc/util/kvm-stat.c | 65 ++++++++++++++++++++++++++++----
1 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/kernel/tools/perf/arch/powerpc/util/kvm-stat.c b/kernel/tools/perf/arch/powerpc/util/kvm-stat.c
index 596ad6a..eed9e5a 100644
--- a/kernel/tools/perf/arch/powerpc/util/kvm-stat.c
+++ b/kernel/tools/perf/arch/powerpc/util/kvm-stat.c
@@ -3,9 +3,13 @@
#include "util/kvm-stat.h"
#include "util/parse-events.h"
#include "util/debug.h"
+#include "util/evsel.h"
+#include "util/evlist.h"
+#include "util/pmu.h"
#include "book3s_hv_exits.h"
#include "book3s_hcalls.h"
+#include <subcmd/parse-options.h>
#define NR_TPS 4
@@ -30,12 +34,12 @@
const char *kvm_events_tp[NR_TPS + 1];
const char *kvm_exit_reason;
-static void hcall_event_get_key(struct perf_evsel *evsel,
+static void hcall_event_get_key(struct evsel *evsel,
struct perf_sample *sample,
struct event_key *key)
{
key->info = 0;
- key->key = perf_evsel__intval(evsel, sample, "req");
+ key->key = evsel__intval(evsel, sample, "req");
}
static const char *get_hcall_exit_reason(u64 exit_code)
@@ -53,14 +57,14 @@
return "UNKNOWN";
}
-static bool hcall_event_end(struct perf_evsel *evsel,
+static bool hcall_event_end(struct evsel *evsel,
struct perf_sample *sample __maybe_unused,
struct event_key *key __maybe_unused)
{
return (!strcmp(evsel->name, kvm_events_tp[3]));
}
-static bool hcall_event_begin(struct perf_evsel *evsel,
+static bool hcall_event_begin(struct evsel *evsel,
struct perf_sample *sample, struct event_key *key)
{
if (!strcmp(evsel->name, kvm_events_tp[2])) {
@@ -104,20 +108,20 @@
};
-static int is_tracepoint_available(const char *str, struct perf_evlist *evlist)
+static int is_tracepoint_available(const char *str, struct evlist *evlist)
{
struct parse_events_error err;
int ret;
- err.str = NULL;
+ bzero(&err, sizeof(err));
ret = parse_events(evlist, str, &err);
if (err.str)
- pr_err("%s : %s\n", str, err.str);
+ parse_events_print_error(&err, "tracepoint");
return ret;
}
static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm,
- struct perf_evlist *evlist)
+ struct evlist *evlist)
{
const char **events_ptr;
int i, nr_tp = 0, err = -1;
@@ -144,7 +148,7 @@
/* Wrapper to setup kvm tracepoints */
static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm)
{
- struct perf_evlist *evlist = perf_evlist__new();
+ struct evlist *evlist = evlist__new();
if (evlist == NULL)
return -ENOMEM;
@@ -170,3 +174,46 @@
return ret;
}
+
+/*
+ * Incase of powerpc architecture, pmu registers are programmable
+ * by guest kernel. So monitoring guest via host may not provide
+ * valid samples with default 'cycles' event. It is better to use
+ * 'trace_imc/trace_cycles' event for guest profiling, since it
+ * can track the guest instruction pointer in the trace-record.
+ *
+ * Function to parse the arguments and return appropriate values.
+ */
+int kvm_add_default_arch_event(int *argc, const char **argv)
+{
+ const char **tmp;
+ bool event = false;
+ int i, j = *argc;
+
+ const struct option event_options[] = {
+ OPT_BOOLEAN('e', "event", &event, NULL),
+ OPT_END()
+ };
+
+ tmp = calloc(j + 1, sizeof(char *));
+ if (!tmp)
+ return -EINVAL;
+
+ for (i = 0; i < j; i++)
+ tmp[i] = argv[i];
+
+ parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
+ if (!event) {
+ if (pmu_have_event("trace_imc", "trace_cycles")) {
+ argv[j++] = strdup("-e");
+ argv[j++] = strdup("trace_imc/trace_cycles/");
+ *argc += 2;
+ } else {
+ free(tmp);
+ return -EINVAL;
+ }
+ }
+
+ free(tmp);
+ return 0;
+}
--
Gitblit v1.6.2