summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-kvm.c109
-rw-r--r--tools/perf/util/kvm-stat.h1
2 files changed, 108 insertions, 2 deletions
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 9bfde8b7ac65..4c205df5106f 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -23,6 +23,8 @@
#include "util/data.h"
#include "util/ordered-events.h"
#include "util/kvm-stat.h"
+#include "ui/browsers/hists.h"
+#include "ui/progress.h"
#include "ui/ui.h"
#include "util/string2.h"
@@ -496,6 +498,7 @@ out:
static int kvm_hists__init(void)
{
+ kvm_hists.list.nr_header_lines = 1;
__hists__init(&kvm_hists.hists, &kvm_hists.list);
perf_hpp_list__init(&kvm_hists.list);
return kvm_hpp_list__parse(&kvm_hists.list, NULL, "ev_name");
@@ -506,6 +509,93 @@ static int kvm_hists__reinit(const char *output, const char *sort)
perf_hpp__reset_output_field(&kvm_hists.list);
return kvm_hpp_list__parse(&kvm_hists.list, output, sort);
}
+static void print_result(struct perf_kvm_stat *kvm);
+
+#ifdef HAVE_SLANG_SUPPORT
+static void kvm_browser__update_nr_entries(struct hist_browser *hb)
+{
+ struct rb_node *nd = rb_first_cached(&hb->hists->entries);
+ u64 nr_entries = 0;
+
+ for (; nd; nd = rb_next(nd)) {
+ struct hist_entry *he = rb_entry(nd, struct hist_entry,
+ rb_node);
+
+ if (!he->filtered)
+ nr_entries++;
+ }
+
+ hb->nr_non_filtered_entries = nr_entries;
+}
+
+static int kvm_browser__title(struct hist_browser *browser,
+ char *buf, size_t size)
+{
+ scnprintf(buf, size, "KVM event statistics (%lu entries)",
+ browser->nr_non_filtered_entries);
+ return 0;
+}
+
+static struct hist_browser*
+perf_kvm_browser__new(struct hists *hists)
+{
+ struct hist_browser *browser = hist_browser__new(hists);
+
+ if (browser)
+ browser->title = kvm_browser__title;
+
+ return browser;
+}
+
+static int kvm__hists_browse(struct hists *hists)
+{
+ struct hist_browser *browser;
+ int key = -1;
+
+ browser = perf_kvm_browser__new(hists);
+ if (browser == NULL)
+ return -1;
+
+ /* reset abort key so that it can get Ctrl-C as a key */
+ SLang_reset_tty();
+ SLang_init_tty(0, 0, 0);
+
+ kvm_browser__update_nr_entries(browser);
+
+ while (1) {
+ key = hist_browser__run(browser, "? - help", true, 0);
+
+ switch (key) {
+ case 'q':
+ goto out;
+ default:
+ break;
+ }
+ }
+
+out:
+ hist_browser__delete(browser);
+ return 0;
+}
+
+static void kvm_display(struct perf_kvm_stat *kvm)
+{
+ if (!use_browser)
+ print_result(kvm);
+ else
+ kvm__hists_browse(&kvm_hists.hists);
+}
+
+#else
+
+static void kvm_display(struct perf_kvm_stat *kvm)
+{
+ use_browser = 0;
+ print_result(kvm);
+}
+
+#endif /* HAVE_SLANG_SUPPORT */
+
#endif // defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
static const char *get_filename_for_perf_kvm(void)
@@ -972,12 +1062,15 @@ static int filter_cb(struct hist_entry *he, void *arg __maybe_unused)
static void sort_result(struct perf_kvm_stat *kvm)
{
+ struct ui_progress prog;
const char *output_columns = "ev_name,sample,percent_sample,"
"time,percent_time,max_t,min_t,mean_t";
kvm_hists__reinit(output_columns, kvm->sort_key);
+ ui_progress__init(&prog, kvm_hists.hists.nr_entries, "Sorting...");
hists__collapse_resort(&kvm_hists.hists, NULL);
hists__output_resort_cb(&kvm_hists.hists, NULL, filter_cb);
+ ui_progress__finish();
}
static void print_vcpu_info(struct perf_kvm_stat *kvm)
@@ -1579,7 +1672,14 @@ static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
if (!register_kvm_events_ops(kvm))
goto exit;
- setup_pager();
+ if (kvm->use_stdio) {
+ use_browser = 0;
+ setup_pager();
+ } else {
+ use_browser = 1;
+ }
+
+ setup_browser(false);
kvm_hists__init();
@@ -1588,7 +1688,7 @@ static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
goto exit;
sort_result(kvm);
- print_result(kvm);
+ kvm_display(kvm);
exit:
return ret;
@@ -1695,6 +1795,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
"analyze events only for given process id(s)"),
OPT_BOOLEAN('f', "force", &kvm->force, "don't complain, do it"),
+ OPT_BOOLEAN(0, "stdio", &kvm->use_stdio, "use the stdio interface"),
OPT_END()
};
@@ -1712,6 +1813,10 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
kvm_events_report_options);
}
+#ifndef HAVE_SLANG_SUPPORT
+ kvm->use_stdio = true;
+#endif
+
if (!kvm->opts.target.pid)
kvm->opts.target.system_wide = true;
diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h
index 35d03894fac3..bc6c8e38ef50 100644
--- a/tools/perf/util/kvm-stat.h
+++ b/tools/perf/util/kvm-stat.h
@@ -103,6 +103,7 @@ struct perf_kvm_stat {
unsigned int display_time;
bool live;
bool force;
+ bool use_stdio;
};
struct kvm_reg_events_ops {