Commit 43af5484 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo
Browse files

perf kvm: Wire up e_machine



Pass the e_machine to the kvm functions so that they aren't just wired
to EM_HOST.

In the case of a session move some setup until the session
is created.

As the session isn't fully running the default EM_HOST is returned as no
e_machine can be found in a running machine.

This is, however, some marginal progress to cross platform support.

Signed-off-by: default avatarIan Rogers <irogers@google.com>
Cc: Aditya Bodkhe <aditya.b1@linux.ibm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andrew Jones <ajones@ventanamicro.com>
Cc: Anubhav Shelat <ashelat@redhat.com>
Cc: Anup Patel <anup@brainfault.org>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Blake Jones <blakejones@google.com>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Quan Zhou <zhouquan@iscas.ac.cn>
Cc: Shimin Guo <shimin.guo@skydio.com>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yunseong Kim <ysk@kzalloc.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent ceea279f
Loading
Loading
Loading
Loading
+27 −18
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
#include "builtin.h"
#include "perf.h"

#include <dwarf-regs.h>
#include "util/build-id.h"
#include "util/evsel.h"
#include "util/evlist.h"
@@ -615,11 +616,11 @@ static const char *get_filename_for_perf_kvm(void)

#if defined(HAVE_LIBTRACEEVENT)

static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
static bool register_kvm_events_ops(struct perf_kvm_stat *kvm, uint16_t e_machine)
{
	const struct kvm_reg_events_ops *events_ops;

	for (events_ops = kvm_reg_events_ops(); events_ops->name; events_ops++) {
	for (events_ops = kvm_reg_events_ops(e_machine); events_ops->name; events_ops++) {
		if (!strcmp(events_ops->name, kvm->report_event)) {
			kvm->events_ops = events_ops->ops;
			return true;
@@ -841,11 +842,11 @@ static bool handle_child_event(struct perf_kvm_stat *kvm,
	return true;
}

static bool skip_event(const char *event)
static bool skip_event(uint16_t e_machine, const char *event)
{
	const char * const *skip_events;

	for (skip_events = kvm_skip_events(); *skip_events; skip_events++)
	for (skip_events = kvm_skip_events(e_machine); *skip_events; skip_events++)
		if (!strcmp(event, *skip_events))
			return true;

@@ -901,9 +902,10 @@ static bool handle_end_event(struct perf_kvm_stat *kvm,

	if (kvm->duration && time_diff > kvm->duration) {
		char decode[KVM_EVENT_NAME_LEN];
		uint16_t e_machine = perf_session__e_machine(kvm->session);

		kvm->events_ops->decode_key(kvm, &event->key, decode);
		if (!skip_event(decode)) {
		if (!skip_event(e_machine, decode)) {
			pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n",
				 sample->time, sample->pid, vcpu_record->vcpu_id,
				 decode, time_diff / NSEC_PER_USEC);
@@ -921,6 +923,8 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
	/* Only kvm_entry records vcpu id. */
	if (!thread__priv(thread) && kvm_entry_event(evsel)) {
		struct vcpu_event_record *vcpu_record;
		struct machine *machine = maps__machine(thread__maps(thread));
		uint16_t e_machine = thread__e_machine(thread, machine, /*e_flags=*/NULL);

		vcpu_record = zalloc(sizeof(*vcpu_record));
		if (!vcpu_record) {
@@ -928,7 +932,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
			return NULL;
		}

		vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str());
		vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str(e_machine));
		thread__set_priv(thread, vcpu_record);
	}

@@ -1163,6 +1167,7 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
{
	char buf[128], *cpuid;
	int err;
	uint16_t e_machine;

	if (kvm->live) {
		struct perf_cpu cpu = {-1};
@@ -1182,7 +1187,8 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
		return -EINVAL;
	}

	err = cpu_isa_init(kvm, cpuid);
	e_machine = perf_session__e_machine(kvm->session);
	err = cpu_isa_init(kvm, e_machine, cpuid);
	if (err == -ENOTSUP)
		pr_err("CPU %s is not supported.\n", cpuid);

@@ -1413,7 +1419,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)

	if (!verify_vcpu(kvm->trace_vcpu) ||
	    !is_valid_key(kvm) ||
	    !register_kvm_events_ops(kvm)) {
		!register_kvm_events_ops(kvm, EM_HOST)) {
		goto out;
	}

@@ -1568,6 +1574,11 @@ static int read_events(struct perf_kvm_stat *kvm)
		goto out_delete;
	}

	if (!register_kvm_events_ops(kvm, perf_session__e_machine(kvm->session))) {
		ret = -EINVAL;
		goto out_delete;
	}

	/*
	 * Do not use 'isa' recorded in kvm_exit tracepoint since it is not
	 * traced in the old kernel.
@@ -1610,9 +1621,6 @@ static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
	if (!is_valid_key(kvm))
		goto exit;

	if (!register_kvm_events_ops(kvm))
		goto exit;

	if (kvm->use_stdio) {
		use_browser = 0;
		setup_pager();
@@ -1653,15 +1661,16 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
	};
	const char * const *events_tp;
	int ret;
	uint16_t e_machine = EM_HOST;

	events_tp_size = 0;
	ret = setup_kvm_events_tp(kvm);
	ret = setup_kvm_events_tp(kvm, e_machine);
	if (ret < 0) {
		pr_err("Unable to setup the kvm tracepoints\n");
		return ret;
	}

	for (events_tp = kvm_events_tp(); *events_tp; events_tp++)
	for (events_tp = kvm_events_tp(e_machine); *events_tp; events_tp++)
		events_tp_size++;

	rec_argc = ARRAY_SIZE(record_args) + argc + 2 +
@@ -1676,7 +1685,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)

	for (j = 0; j < events_tp_size; j++) {
		rec_argv[i++] = STRDUP_FAIL_EXIT("-e");
		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp()[j]);
		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp(e_machine)[j]);
	}

	rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
@@ -1770,7 +1779,7 @@ static struct evlist *kvm_live_event_list(void)
	if (evlist == NULL)
		return NULL;

	for (events_tp = kvm_events_tp(); *events_tp; events_tp++) {
	for (events_tp = kvm_events_tp(EM_HOST); *events_tp; events_tp++) {

		tp = strdup(*events_tp);
		if (tp == NULL)
@@ -1895,7 +1904,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
	/*
	 * generate the event list
	 */
	err = setup_kvm_events_tp(kvm);
	err = setup_kvm_events_tp(kvm, EM_HOST);
	if (err < 0) {
		pr_err("Unable to setup the kvm tracepoints\n");
		return err;
@@ -2005,7 +2014,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv)

	BUG_ON(i + 2 != rec_argc);

	ret = kvm_add_default_arch_event(&i, rec_argv);
	ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv);
	if (ret)
		goto EXIT;

@@ -2092,7 +2101,7 @@ static int __cmd_top(int argc, const char **argv)

	BUG_ON(i != argc);

	ret = kvm_add_default_arch_event(&i, rec_argv);
	ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv);
	if (ret)
		goto EXIT;

+1 −1
Original line number Diff line number Diff line
@@ -1008,7 +1008,7 @@ int evsel__group_desc(struct evsel *evsel, char *buf, size_t size)
	return ret;
}

static uint16_t evsel__e_machine(struct evsel *evsel)
uint16_t evsel__e_machine(struct evsel *evsel)
{
	struct perf_session *session = evsel__session(evsel);

+1 −0
Original line number Diff line number Diff line
@@ -546,6 +546,7 @@ static inline bool evsel__is_dummy_event(struct evsel *evsel)

struct perf_session *evsel__session(struct evsel *evsel);
struct perf_env *evsel__env(struct evsel *evsel);
uint16_t evsel__e_machine(struct evsel *evsel);

int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);

+3 −3
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ static void event_get_key(struct evsel *evsel,
			  struct event_key *key)
{
	key->info = 0;
	key->key = evsel__intval(evsel, sample, kvm_exit_reason());
	key->key = evsel__intval(evsel, sample, kvm_exit_reason(EM_AARCH64));
	key->exit_reasons = arm64_exit_reasons;

	/*
@@ -40,14 +40,14 @@ static bool event_begin(struct evsel *evsel,
			struct perf_sample *sample __maybe_unused,
			struct event_key *key __maybe_unused)
{
	return evsel__name_is(evsel, kvm_entry_trace());
	return evsel__name_is(evsel, kvm_entry_trace(EM_AARCH64));
}

static bool event_end(struct evsel *evsel,
		      struct perf_sample *sample,
		      struct event_key *key)
{
	if (evsel__name_is(evsel, kvm_exit_trace())) {
	if (evsel__name_is(evsel, kvm_exit_trace(EM_AARCH64))) {
		event_get_key(evsel, sample, key);
		return true;
	}
+2 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <memory.h>
#include <dwarf-regs.h>
#include "../kvm-stat.h"
#include "../parse-events.h"
#include "../debug.h"
@@ -70,7 +71,7 @@ static bool event_end(struct evsel *evsel,
	 *   kvm:kvm_enter   means returning to vmm and then to guest
	 *   kvm:kvm_reenter means returning to guest immediately
	 */
	return evsel__name_is(evsel, kvm_entry_trace()) ||
	return evsel__name_is(evsel, kvm_entry_trace(EM_LOONGARCH)) ||
	       evsel__name_is(evsel, kvm_reenter_trace);
}

Loading