mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
perf kvm: Factor out kvm_need_default_arch_event()
The kvm_add_default_arch_event() has a similar logic in each arch to check if there's an existing command line option for events. Let's check it in the generic code and remove the duplication. Tested-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
#include <termios.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <perf/mmap.h>
|
||||
|
||||
@@ -2014,9 +2015,11 @@ 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(EM_HOST, &i, rec_argv);
|
||||
if (ret)
|
||||
goto EXIT;
|
||||
if (kvm_need_default_arch_event(EM_HOST, argc, argv)) {
|
||||
ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv);
|
||||
if (ret)
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = cmd_record(i, rec_argv);
|
||||
|
||||
@@ -2101,9 +2104,11 @@ static int __cmd_top(int argc, const char **argv)
|
||||
|
||||
BUG_ON(i != argc);
|
||||
|
||||
ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv);
|
||||
if (ret)
|
||||
goto EXIT;
|
||||
if (kvm_need_default_arch_event(EM_HOST, argc, argv)) {
|
||||
ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv);
|
||||
if (ret)
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = cmd_top(i, rec_argv);
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "book3s_hv_exits.h"
|
||||
#include "book3s_hcalls.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
|
||||
#define NR_TPS 4
|
||||
|
||||
@@ -177,35 +176,15 @@ int __cpu_isa_init_powerpc(struct perf_kvm_stat *kvm)
|
||||
*/
|
||||
int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv)
|
||||
{
|
||||
const char **tmp;
|
||||
bool event = false;
|
||||
int i, j = *argc;
|
||||
int j = *argc;
|
||||
|
||||
const struct option event_options[] = {
|
||||
OPT_BOOLEAN('e', "event", &event, NULL),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
tmp = calloc(j + 1, sizeof(char *));
|
||||
if (!tmp)
|
||||
if (!perf_pmus__have_event("trace_imc", "trace_cycles"))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < j; i++)
|
||||
tmp[i] = argv[i];
|
||||
argv[j++] = strdup("-e");
|
||||
argv[j++] = strdup("trace_imc/trace_cycles/");
|
||||
*argc += 2;
|
||||
|
||||
parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
|
||||
if (!event) {
|
||||
if (perf_pmus__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;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "../../../arch/x86/include/uapi/asm/svm.h"
|
||||
#include "../../../arch/x86/include/uapi/asm/vmx.h"
|
||||
#include "../../../arch/x86/include/uapi/asm/kvm.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
|
||||
define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS);
|
||||
define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);
|
||||
@@ -211,38 +210,15 @@ int __cpu_isa_init_x86(struct perf_kvm_stat *kvm, const char *cpuid)
|
||||
*/
|
||||
int __kvm_add_default_arch_event_x86(int *argc, const char **argv)
|
||||
{
|
||||
const char **tmp;
|
||||
bool event = false;
|
||||
int ret = 0, i, j = *argc;
|
||||
int ret = 0, j = *argc;
|
||||
|
||||
const struct option event_options[] = {
|
||||
OPT_BOOLEAN('e', "event", &event, NULL),
|
||||
OPT_BOOLEAN(0, "pfm-events", &event, NULL),
|
||||
OPT_END()
|
||||
};
|
||||
argv[j++] = STRDUP_FAIL_EXIT("-e");
|
||||
argv[j++] = STRDUP_FAIL_EXIT("cycles");
|
||||
*argc += 2;
|
||||
|
||||
if (!x86__is_intel_cpu())
|
||||
return 0;
|
||||
|
||||
tmp = calloc(j + 1, sizeof(char *));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < j; i++)
|
||||
tmp[i] = argv[i];
|
||||
|
||||
parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
|
||||
if (!event) {
|
||||
argv[j++] = STRDUP_FAIL_EXIT("-e");
|
||||
argv[j++] = STRDUP_FAIL_EXIT("cycles");
|
||||
*argc += 2;
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
return 0;
|
||||
|
||||
EXIT:
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "debug.h"
|
||||
#include "env.h"
|
||||
#include "evsel.h"
|
||||
#include "kvm-stat.h"
|
||||
#include <dwarf-regs.h>
|
||||
#include <subcmd/parse-options.h>
|
||||
|
||||
bool kvm_exit_event(struct evsel *evsel)
|
||||
{
|
||||
@@ -268,3 +270,42 @@ int kvm_add_default_arch_event(uint16_t e_machine, int *argc, const char **argv)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool kvm_need_default_arch_event(uint16_t e_machine, int argc, const char **argv)
|
||||
{
|
||||
const char **tmp_argv;
|
||||
bool event = false;
|
||||
int i;
|
||||
|
||||
const struct option event_options[] = {
|
||||
OPT_BOOLEAN('e', "event", &event, NULL),
|
||||
OPT_BOOLEAN(0, "pfm-events", &event, NULL),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
switch (e_machine) {
|
||||
case EM_PPC:
|
||||
case EM_PPC64:
|
||||
break;
|
||||
case EM_X86_64:
|
||||
case EM_386:
|
||||
if (!x86__is_intel_cpu())
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/* parse_options() may change the argv, let's make a copy */
|
||||
tmp_argv = calloc(argc + 1, sizeof(char *));
|
||||
if (!tmp_argv)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
tmp_argv[i] = argv[i];
|
||||
|
||||
parse_options(argc, tmp_argv, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
|
||||
free(tmp_argv);
|
||||
|
||||
return !event;
|
||||
}
|
||||
|
||||
@@ -174,12 +174,20 @@ const char * const *__kvm_skip_events_riscv(void);
|
||||
const char * const *__kvm_skip_events_s390(void);
|
||||
const char * const *__kvm_skip_events_x86(void);
|
||||
|
||||
bool kvm_need_default_arch_event(uint16_t e_machine, int argc, const char **argv);
|
||||
int kvm_add_default_arch_event(uint16_t e_machine, int *argc, const char **argv);
|
||||
int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv);
|
||||
int __kvm_add_default_arch_event_x86(int *argc, const char **argv);
|
||||
|
||||
#else /* !HAVE_LIBTRACEEVENT */
|
||||
|
||||
static inline bool kvm_need_default_arch_event(uint16_t e_machine __maybe_unused,
|
||||
int argc __maybe_unused,
|
||||
const char **argv __maybe_unused)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int kvm_add_default_arch_event(uint16_t e_machine __maybe_unused,
|
||||
int *argc __maybe_unused,
|
||||
const char **argv __maybe_unused)
|
||||
|
||||
Reference in New Issue
Block a user