Release 4.10 tools/perf/builtin-kvm.c
#include "builtin.h"
#include "perf.h"
#include "util/evsel.h"
#include "util/evlist.h"
#include "util/util.h"
#include "util/cache.h"
#include "util/symbol.h"
#include "util/thread.h"
#include "util/header.h"
#include "util/session.h"
#include "util/intlist.h"
#include <subcmd/parse-options.h>
#include "util/trace-event.h"
#include "util/debug.h"
#include "util/tool.h"
#include "util/stat.h"
#include "util/top.h"
#include "util/data.h"
#include "util/ordered-events.h"
#include <sys/prctl.h>
#ifdef HAVE_TIMERFD_SUPPORT
#include <sys/timerfd.h>
#endif
#include <linux/time64.h>
#include <termios.h>
#include <semaphore.h>
#include <pthread.h>
#include <math.h>
#ifdef HAVE_KVM_STAT_SUPPORT
#include "util/kvm-stat.h"
void exit_event_get_key(struct perf_evsel *evsel,
struct perf_sample *sample,
struct event_key *key)
{
key->info = 0;
key->key = perf_evsel__intval(evsel, sample, kvm_exit_reason);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 22 | 56.41% | 1 | 25.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 8 | 20.51% | 1 | 25.00% |
alexander yarygin | alexander yarygin | 8 | 20.51% | 1 | 25.00% |
hemant kumar | hemant kumar | 1 | 2.56% | 1 | 25.00% |
| Total | 39 | 100.00% | 4 | 100.00% |
bool kvm_exit_event(struct perf_evsel *evsel)
{
return !strcmp(evsel->name, kvm_exit_trace);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
alexander yarygin | alexander yarygin | 15 | 71.43% | 1 | 25.00% |
xiao guangrong | xiao guangrong | 4 | 19.05% | 1 | 25.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 1 | 4.76% | 1 | 25.00% |
hemant kumar | hemant kumar | 1 | 4.76% | 1 | 25.00% |
| Total | 21 | 100.00% | 4 | 100.00% |
bool exit_event_begin(struct perf_evsel *evsel,
struct perf_sample *sample, struct event_key *key)
{
if (kvm_exit_event(evsel)) {
exit_event_get_key(evsel, sample, key);
return true;
}
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 33 | 75.00% | 1 | 33.33% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 8 | 18.18% | 1 | 33.33% |
alexander yarygin | alexander yarygin | 3 | 6.82% | 1 | 33.33% |
| Total | 44 | 100.00% | 3 | 100.00% |
bool kvm_entry_event(struct perf_evsel *evsel)
{
return !strcmp(evsel->name, kvm_entry_trace);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
alexander yarygin | alexander yarygin | 20 | 95.24% | 1 | 50.00% |
hemant kumar | hemant kumar | 1 | 4.76% | 1 | 50.00% |
| Total | 21 | 100.00% | 2 | 100.00% |
bool exit_event_end(struct perf_evsel *evsel,
struct perf_sample *sample __maybe_unused,
struct event_key *key __maybe_unused)
{
return kvm_entry_event(evsel);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 20 | 71.43% | 1 | 33.33% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 7 | 25.00% | 1 | 33.33% |
alexander yarygin | alexander yarygin | 1 | 3.57% | 1 | 33.33% |
| Total | 28 | 100.00% | 3 | 100.00% |
static const char *get_exit_reason(struct perf_kvm_stat *kvm,
struct exit_reasons_table *tbl,
u64 exit_code)
{
while (tbl->reason != NULL) {
if (tbl->exit_code == exit_code)
return tbl->reason;
tbl++;
}
pr_err("unknown kvm exit code:%lld on %s\n",
(unsigned long long)exit_code, kvm->exit_reasons_isa);
return "UNKNOWN";
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
alexander yarygin | alexander yarygin | 65 | 98.48% | 1 | 50.00% |
xiao guangrong | xiao guangrong | 1 | 1.52% | 1 | 50.00% |
| Total | 66 | 100.00% | 2 | 100.00% |
void exit_event_decode_key(struct perf_kvm_stat *kvm,
struct event_key *key,
char *decode)
{
const char *exit_reason = get_exit_reason(kvm, key->exit_reasons,
key->key);
scnprintf(decode, decode_str_len, "%s", exit_reason);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
alexander yarygin | alexander yarygin | 22 | 45.83% | 3 | 42.86% |
xiao guangrong | xiao guangrong | 21 | 43.75% | 2 | 28.57% |
david ahern | david ahern | 4 | 8.33% | 1 | 14.29% |
hemant kumar | hemant kumar | 1 | 2.08% | 1 | 14.29% |
| Total | 48 | 100.00% | 7 | 100.00% |
static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
{
struct kvm_reg_events_ops *events_ops = kvm_reg_events_ops;
for (events_ops = kvm_reg_events_ops; events_ops->name; events_ops++) {
if (!strcmp(events_ops->name, kvm->report_event)) {
kvm->events_ops = events_ops->ops;
return true;
}
}
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 27 | 42.86% | 2 | 50.00% |
alexander yarygin | alexander yarygin | 27 | 42.86% | 1 | 25.00% |
david ahern | david ahern | 9 | 14.29% | 1 | 25.00% |
| Total | 63 | 100.00% | 4 | 100.00% |
struct vcpu_event_record {
int vcpu_id;
u64 start_time;
struct kvm_event *last_event;
};
static void init_kvm_event_record(struct perf_kvm_stat *kvm)
{
unsigned int i;
for (i = 0; i < EVENTS_CACHE_SIZE; i++)
INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 33 | 84.62% | 2 | 50.00% |
david ahern | david ahern | 6 | 15.38% | 2 | 50.00% |
| Total | 39 | 100.00% | 4 | 100.00% |
#ifdef HAVE_TIMERFD_SUPPORT
static void clear_events_cache_stats(struct list_head *kvm_events_cache)
{
struct list_head *head;
struct kvm_event *event;
unsigned int i;
int j;
for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
head = &kvm_events_cache[i];
list_for_each_entry(event, head, hash_entry) {
/* reset stats for event */
event->total.time = 0;
init_stats(&event->total.stats);
for (j = 0; j < event->max_vcpu; ++j) {
event->vcpu[j].time = 0;
init_stats(&event->vcpu[j].stats);
}
}
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david ahern | david ahern | 121 | 100.00% | 2 | 100.00% |
| Total | 121 | 100.00% | 2 | 100.00% |
#endif
static int kvm_events_hash_fn(u64 key)
{
return key & (EVENTS_CACHE_SIZE - 1);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 18 | 100.00% | 1 | 100.00% |
| Total | 18 | 100.00% | 1 | 100.00% |
static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
{
int old_max_vcpu = event->max_vcpu;
void *prev;
if (vcpu_id < event->max_vcpu)
return true;
while (event->max_vcpu <= vcpu_id)
event->max_vcpu += DEFAULT_VCPU_NUM;
prev = event->vcpu;
event->vcpu = realloc(event->vcpu,
event->max_vcpu * sizeof(*event->vcpu));
if (!event->vcpu) {
free(prev);
pr_err("Not enough memory\n");
return false;
}
memset(event->vcpu + old_max_vcpu, 0,
(event->max_vcpu - old_max_vcpu) * sizeof(*event->vcpu));
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 116 | 88.55% | 1 | 50.00% |
david ahern | david ahern | 15 | 11.45% | 1 | 50.00% |
| Total | 131 | 100.00% | 2 | 100.00% |
static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
{
struct kvm_event *event;
event = zalloc(sizeof(*event));
if (!event) {
pr_err("Not enough memory\n");
return NULL;
}
event->key = *key;
init_stats(&event->total.stats);
return event;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 54 | 84.38% | 1 | 50.00% |
alexander yarygin | alexander yarygin | 10 | 15.62% | 1 | 50.00% |
| Total | 64 | 100.00% | 2 | 100.00% |
static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
struct event_key *key)
{
struct kvm_event *event;
struct list_head *head;
BUG_ON(key->key == INVALID_KEY);
head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
list_for_each_entry(event, head, hash_entry) {
if (event->key.key == key->key && event->key.info == key->info)
return event;
}
event = kvm_alloc_init_event(key);
if (!event)
return NULL;
list_add(&event->hash_entry, head);
return event;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 107 | 93.04% | 2 | 50.00% |
david ahern | david ahern | 8 | 6.96% | 2 | 50.00% |
| Total | 115 | 100.00% | 4 | 100.00% |
static bool handle_begin_event(struct perf_kvm_stat *kvm,
struct vcpu_event_record *vcpu_record,
struct event_key *key, u64 timestamp)
{
struct kvm_event *event = NULL;
if (key->key != INVALID_KEY)
event = find_create_kvm_event(kvm, key);
vcpu_record->last_event = event;
vcpu_record->start_time = timestamp;
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 57 | 90.48% | 2 | 66.67% |
david ahern | david ahern | 6 | 9.52% | 1 | 33.33% |
| Total | 63 | 100.00% | 3 | 100.00% |
static void
kvm_update_event_stats(struct kvm_event_stats *kvm_stats, u64 time_diff)
{
kvm_stats->time += time_diff;
update_stats(&kvm_stats->stats, time_diff);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 30 | 100.00% | 1 | 100.00% |
| Total | 30 | 100.00% | 1 | 100.00% |
static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event)
{
struct kvm_event_stats *kvm_stats = &event->total;
if (vcpu_id != -1)
kvm_stats = &event->vcpu[vcpu_id];
return rel_stddev_stats(stddev_stats(&kvm_stats->stats),
avg_stats(&kvm_stats->stats));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 61 | 100.00% | 1 | 100.00% |
| Total | 61 | 100.00% | 1 | 100.00% |
static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
u64 time_diff)
{
if (vcpu_id == -1) {
kvm_update_event_stats(&event->total, time_diff);
return true;
}
if (!kvm_event_expand(event, vcpu_id))
return false;
kvm_update_event_stats(&event->vcpu[vcpu_id], time_diff);
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 56 | 82.35% | 1 | 50.00% |
david ahern | david ahern | 12 | 17.65% | 1 | 50.00% |
| Total | 68 | 100.00% | 2 | 100.00% |
static bool is_child_event(struct perf_kvm_stat *kvm,
struct perf_evsel *evsel,
struct perf_sample *sample,
struct event_key *key)
{
struct child_event_ops *child_ops;
child_ops = kvm->events_ops->child_ops;
if (!child_ops)
return false;
for (; child_ops->name; child_ops++) {
if (!strcmp(evsel->name, child_ops->name)) {
child_ops->get_key(evsel, sample, key);
return true;
}
}
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
alexander yarygin | alexander yarygin | 92 | 100.00% | 1 | 100.00% |
| Total | 92 | 100.00% | 1 | 100.00% |
static bool handle_child_event(struct perf_kvm_stat *kvm,
struct vcpu_event_record *vcpu_record,
struct event_key *key,
struct perf_sample *sample __maybe_unused)
{
struct kvm_event *event = NULL;
if (key->key != INVALID_KEY)
event = find_create_kvm_event(kvm, key);
vcpu_record->last_event = event;
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
alexander yarygin | alexander yarygin | 60 | 100.00% | 1 | 100.00% |
| Total | 60 | 100.00% | 1 | 100.00% |
static bool skip_event(const char *event)
{
const char * const *skip_events;
for (skip_events = kvm_skip_events; *skip_events; skip_events++)
if (!strcmp(event, *skip_events))
return true;
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
alexander yarygin | alexander yarygin | 47 | 100.00% | 1 | 100.00% |
| Total | 47 | 100.00% | 1 | 100.00% |
static bool handle_end_event(struct perf_kvm_stat *kvm,
struct vcpu_event_record *vcpu_record,
struct event_key *key,
struct perf_sample *sample)
{
struct kvm_event *event;
u64 time_begin, time_diff;
int vcpu;
if (kvm->trace_vcpu == -1)
vcpu = -1;
else
vcpu = vcpu_record->vcpu_id;
event = vcpu_record->last_event;
time_begin = vcpu_record->start_time;
/* The begin event is not caught. */
if (!time_begin)
return true;
/*
* In some case, the 'begin event' only records the start timestamp,
* the actual event is recognized in the 'end event' (e.g. mmio-event).
*/
/* Both begin and end events did not get the key. */
if (!event && key->key == INVALID_KEY)
return true;
if (!event)
event = find_create_kvm_event(kvm, key);
if (!event)
return false;
vcpu_record->last_event = NULL;
vcpu_record->start_time = 0;
/* seems to happen once in a while during live mode */
if (sample->time < time_begin) {
pr_debug("End time before begin time; skipping event.\n");
return true;
}
time_diff = sample->time - time_begin;
if (kvm->duration && time_diff > kvm->duration) {
char decode[decode_str_len];
kvm->events_ops->decode_key(kvm, &event->key, decode);
if (!skip_event(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);
}
}
return update_kvm_event(event, vcpu, time_diff);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david ahern | david ahern | 122 | 50.62% | 4 | 44.44% |
xiao guangrong | xiao guangrong | 115 | 47.72% | 2 | 22.22% |
alexander yarygin | alexander yarygin | 2 | 0.83% | 1 | 11.11% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 1 | 0.41% | 1 | 11.11% |
hemant kumar | hemant kumar | 1 | 0.41% | 1 | 11.11% |
| Total | 241 | 100.00% | 9 | 100.00% |
static
struct vcpu_event_record *per_vcpu_record(struct thread *thread,
struct perf_evsel *evsel,
struct perf_sample *sample)
{
/* Only kvm_entry records vcpu id. */
if (!thread__priv(thread) && kvm_entry_event(evsel)) {
struct vcpu_event_record *vcpu_record;
vcpu_record = zalloc(sizeof(*vcpu_record));
if (!vcpu_record) {
pr_err("%s: Not enough memory\n", __func__);
return NULL;
}
vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample,
vcpu_id_str);
thread__set_priv(thread, vcpu_record);
}
return thread__priv(thread);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 73 | 74.49% | 1 | 25.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 14 | 14.29% | 1 | 25.00% |
namhyung kim | namhyung kim | 10 | 10.20% | 1 | 25.00% |
hemant kumar | hemant kumar | 1 | 1.02% | 1 | 25.00% |
| Total | 98 | 100.00% | 4 | 100.00% |
static bool handle_kvm_event(struct perf_kvm_stat *kvm,
struct thread *thread,
struct perf_evsel *evsel,
struct perf_sample *sample)
{
struct vcpu_event_record *vcpu_record;
struct event_key key = { .key = INVALID_KEY,
.exit_reasons = kvm->exit_reasons };
vcpu_record = per_vcpu_record(thread, evsel, sample);
if (!vcpu_record)
return true;
/* only process events for vcpus user cares about */
if ((kvm->trace_vcpu != -1) &&
(kvm->trace_vcpu != vcpu_record->vcpu_id))
return true;
if (kvm->events_ops->is_begin_event(evsel, sample, &key))
return handle_begin_event(kvm, vcpu_record, &key, sample->time);
if (is_child_event(kvm, evsel, sample, &key))
return handle_child_event(kvm, vcpu_record, &key, sample);
if (kvm->events_ops->is_end_event(evsel, sample, &key))
return handle_end_event(kvm, vcpu_record, &key, sample);
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 75 | 40.98% | 2 | 33.33% |
david ahern | david ahern | 62 | 33.88% | 2 | 33.33% |
alexander yarygin | alexander yarygin | 34 | 18.58% | 1 | 16.67% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 12 | 6.56% | 1 | 16.67% |
| Total | 183 | 100.00% | 6 | 100.00% |
#define GET_EVENT_KEY(func, field) \
static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \
{ \
if (vcpu == -1) \
return event->total.field; \
\
if (vcpu >= event->max_vcpu) \
return 0; \
\
return event->vcpu[vcpu].field; \
}
#define COMPARE_EVENT_KEY(func, field) \
GET_EVENT_KEY(func, field) \
static int compare_kvm_event_ ## func(struct kvm_event *one, \
struct kvm_event *two, int vcpu)\
{ \
return get_event_ ##func(one, vcpu) > \
get_event_ ##func(two, vcpu); \
}
GET_EVENT_KEY(time, time);
COMPARE_EVENT_KEY(count, stats.n);
COMPARE_EVENT_KEY(mean, stats.mean);
GET_EVENT_KEY(max, stats.max);
GET_EVENT_KEY(min, stats.min);
#define DEF_SORT_NAME_KEY(name, compare_key) \
{ #name, compare_kvm_event_ ## compare_key }
static struct kvm_event_key keys[] = {
DEF_SORT_NAME_KEY(sample, count),
DEF_SORT_NAME_KEY(time, mean),
{ NULL, NULL }
};
static bool select_key(struct perf_kvm_stat *kvm)
{
int i;
for (i = 0; keys[i].name; i++) {
if (!strcmp(keys[i].name, kvm->sort_key)) {
kvm->compare = keys[i].key;
return true;
}
}
pr_err("Unknown compare key:%s\n", kvm->sort_key);
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 68 | 88.31% | 2 | 66.67% |
david ahern | david ahern | 9 | 11.69% | 1 | 33.33% |
| Total | 77 | 100.00% | 3 | 100.00% |
static void insert_to_result(struct rb_root *result, struct kvm_event *event,
key_cmp_fun bigger, int vcpu)
{
struct rb_node **rb = &result->rb_node;
struct rb_node *parent = NULL;
struct kvm_event *p;
while (*rb) {
p = container_of(*rb, struct kvm_event, rb);
parent = *rb;
if (bigger(event, p, vcpu))
rb = &(*rb)->rb_left;
else
rb = &(*rb)->rb_right;
}
rb_link_node(&event->rb, parent, rb);
rb_insert_color(&event->rb, result);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 118 | 95.16% | 1 | 50.00% |
david ahern | david ahern | 6 | 4.84% | 1 | 50.00% |
| Total | 124 | 100.00% | 2 | 100.00% |
static void
update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
{
int vcpu = kvm->trace_vcpu;
kvm->total_count += get_event_count(event, vcpu);
kvm->total_time += get_event_time(event, vcpu);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 30 | 66.67% | 2 | 66.67% |
david ahern | david ahern | 15 | 33.33% | 1 | 33.33% |
| Total | 45 | 100.00% | 3 | 100.00% |
static bool event_is_valid(struct kvm_event *event, int vcpu)
{
return !!get_event_count(event, vcpu);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 24 | 100.00% | 1 | 100.00% |
| Total | 24 | 100.00% | 1 | 100.00% |
static void sort_result(struct perf_kvm_stat *kvm)
{
unsigned int i;
int vcpu = kvm->trace_vcpu;
struct kvm_event *event;
for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) {
if (event_is_valid(event, vcpu)) {
update_total_count(kvm, event);
insert_to_result(&kvm->result, event,
kvm->compare, vcpu);
}
}
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 62 | 72.09% | 2 | 50.00% |
david ahern | david ahern | 24 | 27.91% | 2 | 50.00% |
| Total | 86 | 100.00% | 4 | 100.00% |
/* returns left most element of result, and erase it */
static struct kvm_event *pop_from_result(struct rb_root *result)
{
struct rb_node *node = rb_first(result);
if (!node)
return NULL;
rb_erase(node, result);
return container_of(node, struct kvm_event, rb);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
xiao guangrong | xiao guangrong | 45 | 91.84% | 1 | 50.00% |
david ahern | david ahern | 4 | 8.16% | 1 | 50.00% |
| Total | 49 | 100.00% | 2 | 100.00% |
static void print_vcpu_info(struct perf_kvm_stat *kvm)
{
int vcpu = kvm->trace_vcpu;
pr_info("Analyze events for ");
if (kvm->opts.target.system_wide)
pr_info("all VMs, ");
else if (kvm->opts.target.pid)
pr_info("pid(s) %s, ", kvm->opts.target.pid);
else
pr_info("dazed and confused on what is monitored, ");
if (vcpu == -1)
pr_info("all VCPUs:\n\n");
else
pr_info("VCPU %d:\n\n", vcpu);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david ahern | david ahern | 56 | 63.64% | 1 | 50.00% |
xiao guangrong | xiao guangrong | 32 | 36.36% | 1 | 50.00% |
| Total | 88 | 100.00% | 2 | 100.00% |
static void show_timeofday(void)
{
char date[64];
struct timeval tv;
struct tm ltime;
gettimeofday(&tv, NULL);
if (localtime_r(&tv.tv_sec, <ime)) {
strftime(date, sizeof(date), "%H:%M:%S", <ime);
pr_info("%s.%06ld", date, tv.tv_usec);
} else
pr_info("00:00:00.000000");
return;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david ahern | david ahern | 47 | 60.26% | 2 | 66.67% |
xiao guangrong | xiao guangrong | 31 | 39.74% | 1 | 33.33% |
| Total | 78 | 100.00% | 3 | 100.00% |
static void print_result(struct perf_kvm_stat *kvm)
{
char decode[decode_str_len];
struct kvm_event *event;
int vcpu = kvm->trace_vcpu;
if (kvm->live) {
puts(CONSOLE_CLEAR);
show_timeofday();
}
pr_info("\n\n");
print_vcpu_info(kvm);
pr_info("%*s ", decode_str_len, kvm->events_ops->name);
pr_info("%10s ", "Samples");
pr_info("%9s ", "Samples%");
pr_info("%9s ", "Time%");
pr_info("%11s ", "Min Time");
pr_info("%11s ", "Max Time");
pr_info("%16s ", "Avg time");
pr_info("\n\n");
while ((event = pop_from_result(&kvm->result))) {
u64 ecount, etime, max, min;
ecount = get_event_count(event, vcpu);
etime = get_event_time(event, vcpu);
max = get_event_max(event, vcpu);
min = get_event_min(event, vcpu);
kvm->events_ops->decode_key(kvm, &event->key, decode);
pr_info("%*s ", decode_str_len, decode);
pr_info("%10llu ", (unsigned long long)ecount);
pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
pr_info("%9.2fus ", (double)min / NSEC_PER_USEC);
pr_info("%9.2fus ", (double)max / NSEC_PER_USEC);
pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount / NSEC_PER_USEC,
kvm_event_rel_stddev(vcpu, event));
pr_info("\n");
}
pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n",
kvm->total_count, kvm->total_time / (double)NSEC_PER_USEC);
if (kvm->lost_events)
pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david ahern | david ahern | 175 | 52.71% | 4 | 44.44% |
xiao guangrong | xiao guangrong | 133 | 40.06% | 1 | 11.11% |
christian borntraeger | christian borntraeger | 10 | 3.01% | 1 | 11.11% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 7 | 2.11% | 1 | 11.11% |
alexander yarygin | alexander yarygin | 4 | 1.20% | 1 | 11.11% |
hemant kumar | hemant kumar | 3 | 0.90% | 1 | 11.11% |
| Total | 332 | 100.00% | 9 | 100.00% |
#ifdef HAVE_TIMERFD_SUPPORT
static int process_lost_event(struct perf_tool *tool,
union perf_event *event __maybe_unused,
struct perf_sample *sample __maybe_unused,
struct machine *machine __maybe_unused)
{
struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool);
kvm->lost_events++;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david ahern | david ahern | 51 | 98.08% | 1 | 50.00% |
xiao guangrong | xiao guangrong | 1 | 1.92% | 1 | 50.00% |
| Total | 52 | 100.00% | 2 | 100.00% |
#endif
static bool skip_sample(struct perf_kvm_stat *kvm,
struct perf_sample *sample)
{
if (kvm->pid_list && intlist__find(kvm->pid_list, sample->pid) == NULL)
return