15 #include <subcmd/parse-options.h> 24 #include <sys/prctl.h> 25 #ifdef HAVE_TIMERFD_SUPPORT 26 #include <sys/timerfd.h> 29 #include <sys/types.h> 33 #include <linux/kernel.h> 34 #include <linux/time64.h> 39 #include <semaphore.h> 48 filename = strdup(
"perf.data.host");
50 filename = strdup(
"perf.data.guest");
52 filename = strdup(
"perf.data.kvm");
57 #ifdef HAVE_KVM_STAT_SUPPORT 100 while (tbl->
reason != NULL) {
106 pr_err(
"unknown kvm exit code:%lld on %s\n",
115 const char *exit_reason = get_exit_reason(kvm, key->
exit_reasons,
121 static bool register_kvm_events_ops(
struct perf_kvm_stat *kvm)
135 struct vcpu_event_record {
150 #ifdef HAVE_TIMERFD_SUPPORT 151 static void clear_events_cache_stats(
struct list_head *kvm_events_cache)
153 struct list_head *head;
159 head = &kvm_events_cache[i];
160 list_for_each_entry(event, head,
hash_entry) {
162 event->total.time = 0;
165 for (j = 0; j <
event->max_vcpu; ++j) {
166 event->vcpu[j].time = 0;
174 static int kvm_events_hash_fn(u64 key)
179 static bool kvm_event_expand(
struct kvm_event *
event,
int vcpu_id)
181 int old_max_vcpu =
event->max_vcpu;
191 event->vcpu = realloc(event->
vcpu,
195 pr_err(
"Not enough memory\n");
200 (event->
max_vcpu - old_max_vcpu) *
sizeof(*event->
vcpu));
208 event =
zalloc(
sizeof(*event));
210 pr_err(
"Not enough memory\n");
223 struct list_head *head;
228 list_for_each_entry(event, head, hash_entry) {
233 event = kvm_alloc_init_event(key);
242 struct vcpu_event_record *vcpu_record,
248 event = find_create_kvm_event(kvm, key);
250 vcpu_record->last_event =
event;
251 vcpu_record->start_time = timestamp;
256 kvm_update_event_stats(
struct kvm_event_stats *kvm_stats, u64 time_diff)
258 kvm_stats->
time += time_diff;
262 static double kvm_event_rel_stddev(
int vcpu_id,
struct kvm_event *event)
267 kvm_stats = &
event->vcpu[vcpu_id];
273 static bool update_kvm_event(
struct kvm_event *event,
int vcpu_id,
277 kvm_update_event_stats(&event->
total, time_diff);
281 if (!kvm_event_expand(event, vcpu_id))
284 kvm_update_event_stats(&event->
vcpu[vcpu_id], time_diff);
300 for (; child_ops->
name; child_ops++) {
301 if (!strcmp(evsel->
name, child_ops->
name)) {
302 child_ops->
get_key(evsel, sample, key);
311 struct vcpu_event_record *vcpu_record,
318 event = find_create_kvm_event(kvm, key);
320 vcpu_record->last_event =
event;
325 static bool skip_event(
const char *event)
327 const char *
const *skip_events;
330 if (!strcmp(event, *skip_events))
337 struct vcpu_event_record *vcpu_record,
342 u64 time_begin, time_diff;
348 vcpu = vcpu_record->vcpu_id;
350 event = vcpu_record->last_event;
351 time_begin = vcpu_record->start_time;
367 event = find_create_kvm_event(kvm, key);
372 vcpu_record->last_event = NULL;
373 vcpu_record->start_time = 0;
376 if (sample->
time < time_begin) {
377 pr_debug(
"End time before begin time; skipping event.\n");
381 time_diff = sample->
time - time_begin;
387 if (!skip_event(decode)) {
388 pr_info(
"%" PRIu64
" VM %d, vcpu %d: %s event took %" PRIu64
"usec\n",
389 sample->
time, sample->
pid, vcpu_record->vcpu_id,
390 decode, time_diff / NSEC_PER_USEC);
394 return update_kvm_event(event, vcpu, time_diff);
398 struct vcpu_event_record *per_vcpu_record(
struct thread *
thread,
404 struct vcpu_event_record *vcpu_record;
406 vcpu_record =
zalloc(
sizeof(*vcpu_record));
408 pr_err(
"%s: Not enough memory\n", __func__);
421 struct thread *thread,
425 struct vcpu_event_record *vcpu_record;
429 vcpu_record = per_vcpu_record(thread, evsel, sample);
439 return handle_begin_event(kvm, vcpu_record, &key, sample->
time);
441 if (is_child_event(kvm, evsel, sample, &key))
442 return handle_child_event(kvm, vcpu_record, &key, sample);
445 return handle_end_event(kvm, vcpu_record, &key, sample);
450 #define GET_EVENT_KEY(func, field) \ 451 static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \ 454 return event->total.field; \ 456 if (vcpu >= event->max_vcpu) \ 459 return event->vcpu[vcpu].field; \ 462 #define COMPARE_EVENT_KEY(func, field) \ 463 GET_EVENT_KEY(func, field) \ 464 static int compare_kvm_event_ ## func(struct kvm_event *one, \ 465 struct kvm_event *two, int vcpu)\ 467 return get_event_ ##func(one, vcpu) > \ 468 get_event_ ##func(two, vcpu); \ 472 COMPARE_EVENT_KEY(count,
stats.
n);
477 #define DEF_SORT_NAME_KEY(name, compare_key) \ 478 { #name, compare_kvm_event_ ## compare_key } 481 DEF_SORT_NAME_KEY(sample, count),
482 DEF_SORT_NAME_KEY(
time, mean),
490 for (i = 0; keys[i].
name; i++) {
504 struct rb_node **rb = &
result->rb_node;
505 struct rb_node *parent = NULL;
509 p = container_of(*rb,
struct kvm_event, rb);
512 if (bigger(event, p, vcpu))
513 rb = &(*rb)->rb_left;
515 rb = &(*rb)->rb_right;
518 rb_link_node(&event->
rb, parent, rb);
519 rb_insert_color(&event->
rb,
result);
528 kvm->
total_time += get_event_time(event, vcpu);
531 static bool event_is_valid(
struct kvm_event *event,
int vcpu)
533 return !!get_event_count(event, vcpu);
544 if (event_is_valid(event, vcpu)) {
545 update_total_count(kvm, event);
556 struct rb_node *
node = rb_first(result);
561 rb_erase(node, result);
562 return container_of(node,
struct kvm_event, rb);
569 pr_info(
"Analyze events for ");
576 pr_info(
"dazed and confused on what is monitored, ");
584 static void show_timeofday(
void)
590 gettimeofday(&tv, NULL);
591 if (localtime_r(&tv.tv_sec, <ime)) {
592 strftime(date,
sizeof(date),
"%H:%M:%S", <ime);
593 pr_info(
"%s.%06ld", date, tv.tv_usec);
612 print_vcpu_info(kvm);
624 u64 ecount, etime, max,
min;
626 ecount = get_event_count(event, vcpu);
627 etime = get_event_time(event, vcpu);
628 max = get_event_max(event, vcpu);
629 min = get_event_min(event, vcpu);
633 pr_info(
"%10llu ", (
unsigned long long)ecount);
636 pr_info(
"%9.2fus ", (
double)min / NSEC_PER_USEC);
637 pr_info(
"%9.2fus ", (
double)max / NSEC_PER_USEC);
638 pr_info(
"%9.2fus ( +-%7.2f%% )", (
double)etime / ecount / NSEC_PER_USEC,
639 kvm_event_rel_stddev(vcpu, event));
643 pr_info(
"\nTotal Samples:%" PRIu64
", Total events handled time:%.2fus.\n\n",
650 #ifdef HAVE_TIMERFD_SUPPORT 679 struct thread *thread;
683 if (skip_sample(kvm, sample))
687 if (thread == NULL) {
688 pr_debug(
"problem processing %d event, skipping it.\n",
693 if (!handle_kvm_event(kvm, thread, evsel, sample))
702 char buf[64], *
cpuid;
708 pr_err(
"Failed to look up CPU type\n");
716 pr_err(
"Failed to look up CPU type\n");
722 pr_err(
"CPU %s is not supported.\n", cpuid);
727 static bool verify_vcpu(
int vcpu)
729 if (vcpu != -1 && vcpu < 0) {
730 pr_err(
"Invalid vcpu:%d.\n", vcpu);
737 #ifdef HAVE_TIMERFD_SUPPORT 741 #define PERF_KVM__MAX_EVENTS_PER_MMAP 25 743 static s64 perf_kvm__mmap_read_idx(
struct perf_kvm_stat *kvm,
int idx,
753 *mmap_time = ULLONG_MAX;
754 md = &evlist->
mmap[idx];
757 return (err == -EAGAIN) ? 0 : -1;
763 pr_err(
"Failed to parse sample\n");
775 pr_err(
"Failed to enqueue sample: %d\n", err);
781 *mmap_time = timestamp;
785 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
795 int i,
err, throttled = 0;
797 u64 flush_time = ULLONG_MAX, mmap_time;
800 n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time);
811 if (mmap_time < flush_time)
812 flush_time = mmap_time;
815 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
827 pr_info(
"\nLost events: %" PRIu64
"\n\n",
836 static volatile int done;
843 static int perf_kvm__timerfd_create(
struct perf_kvm_stat *kvm)
845 struct itimerspec new_value;
848 kvm->
timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
850 pr_err(
"timerfd_create failed\n");
855 new_value.it_value.tv_nsec = 0;
857 new_value.it_interval.tv_nsec = 0;
859 if (timerfd_settime(kvm->
timerfd, 0, &new_value, NULL) != 0) {
860 pr_err(
"timerfd_settime failed: %d\n", errno);
870 static int perf_kvm__handle_timerfd(
struct perf_kvm_stat *kvm)
875 rc = read(kvm->
timerfd, &c,
sizeof(uint64_t));
880 pr_err(
"Failed to read timer fd: %d\n", errno);
884 if (rc !=
sizeof(uint64_t)) {
885 pr_err(
"Error reading timer fd - invalid size returned\n");
890 pr_debug(
"Missed timer beats: %" PRIu64
"\n", c-1);
905 static int fd_set_nonblock(
int fd)
909 arg = fcntl(fd, F_GETFL);
911 pr_err(
"Failed to get current flags for fd %d\n", fd);
915 if (fcntl(fd, F_SETFL, arg | O_NONBLOCK) < 0) {
916 pr_err(
"Failed to set non-block option on fd %d\n", fd);
923 static int perf_kvm__handle_stdin(
void)
936 int nr_stdin, ret,
err = -EINVAL;
942 ret = cpu_isa_config(kvm);
948 !register_kvm_events_ops(kvm)) {
953 init_kvm_event_record(kvm);
959 if (perf_kvm__timerfd_create(kvm) < 0) {
971 if (fd_set_nonblock(fileno(stdin)) != 0)
981 rc = perf_kvm__mmap_read(kvm);
985 err = perf_kvm__handle_timerfd(kvm);
989 if (fda->entries[nr_stdin].revents & POLLIN)
990 done = perf_kvm__handle_stdin();
993 err = fdarray__poll(fda, 100);
1007 tcsetattr(0, TCSAFLUSH, &save);
1025 struct perf_event_attr *
attr = &pos->
attr;
1042 attr->sample_period = 1;
1044 attr->watermark = 0;
1045 attr->wakeup_events = 1000;
1053 printf(
"Couldn't create the events: %s\n",
1054 str_error_r(errno, sbuf,
sizeof(sbuf)));
1059 ui__error(
"Failed to mmap the events: %s\n",
1060 str_error_r(errno, sbuf,
sizeof(sbuf)));
1080 .ordered_events =
true,
1087 .force = kvm->
force,
1093 pr_err(
"Initializing perf session failed\n");
1108 ret = cpu_isa_config(kvm);
1124 pr_err(
"Error parsing process id string\n");
1132 static int kvm_events_report_vcpu(
struct perf_kvm_stat *kvm)
1137 if (parse_target_str(kvm) != 0)
1140 if (!verify_vcpu(vcpu))
1146 if (!register_kvm_events_ops(kvm))
1149 init_kvm_event_record(kvm);
1152 ret = read_events(kvm);
1163 #define STRDUP_FAIL_EXIT(s) \ 1179 unsigned int rec_argc, i, j, events_tp_size;
1180 const char **rec_argv;
1181 const char *
const record_args[] = {
1187 const char *
const kvm_stat_record_usage[] = {
1188 "perf kvm stat record [<options>]",
1191 const char *
const *events_tp;
1197 pr_err(
"Unable to setup the kvm tracepoints\n");
1204 rec_argc = ARRAY_SIZE(record_args) +
argc + 2 +
1206 rec_argv = calloc(rec_argc + 1,
sizeof(
char *));
1208 if (rec_argv == NULL)
1211 for (i = 0; i < ARRAY_SIZE(record_args); i++)
1212 rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
1214 for (j = 0; j < events_tp_size; j++) {
1215 rec_argv[i++] =
"-e";
1219 rec_argv[i++] = STRDUP_FAIL_EXIT(
"-o");
1220 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->
file_name);
1222 for (j = 1; j < (
unsigned int)
argc; j++, i++)
1223 rec_argv[i] = argv[j];
1227 set_option_flag(
record_options,
'R',
"raw-samples", PARSE_OPT_HIDDEN);
1229 set_option_flag(
record_options,
'F',
"freq", PARSE_OPT_DISABLED);
1232 set_option_flag(
record_options, 0,
"call-graph", PARSE_OPT_DISABLED);
1233 set_option_flag(
record_options,
'd',
"data", PARSE_OPT_DISABLED);
1234 set_option_flag(
record_options,
'T',
"timestamp", PARSE_OPT_DISABLED);
1235 set_option_flag(
record_options,
'P',
"period", PARSE_OPT_DISABLED);
1236 set_option_flag(
record_options,
'n',
"no-samples", PARSE_OPT_DISABLED);
1237 set_option_flag(
record_options,
'N',
"no-buildid-cache", PARSE_OPT_DISABLED);
1238 set_option_flag(
record_options,
'B',
"no-buildid", PARSE_OPT_DISABLED);
1239 set_option_flag(
record_options,
'G',
"cgroup", PARSE_OPT_DISABLED);
1240 set_option_flag(
record_options,
'b',
"branch-any", PARSE_OPT_DISABLED);
1241 set_option_flag(
record_options,
'j',
"branch-filter", PARSE_OPT_DISABLED);
1242 set_option_flag(
record_options,
'W',
"weight", PARSE_OPT_DISABLED);
1243 set_option_flag(
record_options, 0,
"transaction", PARSE_OPT_DISABLED);
1252 const struct option kvm_events_report_options[] = {
1253 OPT_STRING(0,
"event", &kvm->
report_event,
"report event",
1254 "event for reporting: vmexit, " 1255 "mmio (x86 only), ioport (x86 only)"),
1257 "vcpu id to report"),
1258 OPT_STRING(
'k',
"key", &kvm->
sort_key,
"sort-key",
1259 "key for sorting: sample(sort by samples number)" 1260 " time (sort by avg time)"),
1262 "analyze events only for given process id(s)"),
1263 OPT_BOOLEAN(
'f',
"force", &kvm->
force,
"don't complain, do it"),
1267 const char *
const kvm_events_report_usage[] = {
1268 "perf kvm stat report [<options>]",
1274 kvm_events_report_options,
1275 kvm_events_report_usage, 0);
1277 usage_with_options(kvm_events_report_usage,
1278 kvm_events_report_options);
1284 return kvm_events_report_vcpu(kvm);
1287 #ifdef HAVE_TIMERFD_SUPPORT 1288 static struct perf_evlist *kvm_live_event_list(
void)
1291 char *tp, *
name, *sys;
1293 const char *
const *events_tp;
1301 tp = strdup(*events_tp);
1307 name = strchr(tp,
':');
1309 pr_err(
"Error parsing %s tracepoint: subsystem delimiter not found\n",
1318 pr_err(
"Failed to add %s tracepoint to the list\n", *events_tp);
1338 int argc,
const char **argv)
1340 char errbuf[BUFSIZ];
1343 const struct option live_options[] = {
1345 "record events on existing process id"),
1347 "number of mmap data pages",
1349 OPT_INCR(
'v',
"verbose", &
verbose,
1350 "be more verbose (show counter open errors, etc)"),
1352 "system-wide collection from all CPUs"),
1354 "time in seconds between display updates"),
1355 OPT_STRING(0,
"event", &kvm->
report_event,
"report event",
1356 "event for reporting: " 1357 "vmexit, mmio (x86 only), ioport (x86 only)"),
1359 "vcpu id to report"),
1360 OPT_STRING(
'k',
"key", &kvm->
sort_key,
"sort-key",
1361 "key for sorting: sample(sort by samples number)" 1362 " time (sort by avg time)"),
1363 OPT_U64(0,
"duration", &kvm->
duration,
1364 "show events other than" 1365 " HLT (x86 only) or Wait state (s390 only)" 1366 " that take longer than duration usecs"),
1368 "per thread proc mmap processing timeout in ms"),
1371 const char *
const live_usage[] = {
1372 "perf kvm stat live [<options>]",
1405 argc = parse_options(
argc, argv, live_options,
1408 usage_with_options(live_usage, live_options);
1431 pr_err(
"Unable to setup the kvm tracepoints\n");
1435 kvm->
evlist = kvm_live_event_list();
1436 if (kvm->
evlist == NULL) {
1442 usage_with_options(live_usage, live_options);
1458 err = kvm_live_open_events(kvm);
1462 err = kvm_events_live_report(kvm);
1473 static void print_kvm_stat_usage(
void)
1475 printf(
"Usage: perf kvm stat <command>\n\n");
1477 printf(
"# Available commands:\n");
1478 printf(
"\trecord: record kvm events\n");
1479 printf(
"\treport: report statistical data of kvm events\n");
1480 printf(
"\tlive: live reporting of statistical data of kvm events\n");
1482 printf(
"\nOtherwise, it is the alias of 'perf stat':\n");
1485 static int kvm_cmd_stat(
const char *file_name,
int argc,
const char **argv)
1491 .report_event =
"vmexit",
1492 .sort_key =
"sample",
1497 print_kvm_stat_usage();
1501 if (!strncmp(argv[1],
"rec", 3))
1502 return kvm_events_record(&kvm,
argc - 1, argv + 1);
1504 if (!strncmp(argv[1],
"rep", 3))
1505 return kvm_events_report(&kvm,
argc - 1 , argv + 1);
1507 #ifdef HAVE_TIMERFD_SUPPORT 1508 if (!strncmp(argv[1],
"live", 4))
1509 return kvm_events_live(&kvm,
argc - 1 , argv + 1);
1519 int rec_argc, i = 0, j;
1520 const char **rec_argv;
1522 rec_argc = argc + 2;
1523 rec_argv = calloc(rec_argc + 1,
sizeof(
char *));
1524 rec_argv[i++] = strdup(
"record");
1525 rec_argv[i++] = strdup(
"-o");
1526 rec_argv[i++] = strdup(file_name);
1527 for (j = 1; j <
argc; j++, i++)
1528 rec_argv[i] = argv[j];
1530 BUG_ON(i != rec_argc);
1537 int rec_argc, i = 0, j;
1538 const char **rec_argv;
1540 rec_argc = argc + 2;
1541 rec_argv = calloc(rec_argc + 1,
sizeof(
char *));
1542 rec_argv[i++] = strdup(
"report");
1543 rec_argv[i++] = strdup(
"-i");
1544 rec_argv[i++] = strdup(file_name);
1545 for (j = 1; j <
argc; j++, i++)
1546 rec_argv[i] = argv[j];
1548 BUG_ON(i != rec_argc);
1556 int rec_argc, i = 0, j;
1557 const char **rec_argv;
1559 rec_argc = argc + 2;
1560 rec_argv = calloc(rec_argc + 1,
sizeof(
char *));
1561 rec_argv[i++] = strdup(
"buildid-list");
1562 rec_argv[i++] = strdup(
"-i");
1563 rec_argv[i++] = strdup(file_name);
1564 for (j = 1; j <
argc; j++, i++)
1565 rec_argv[i] = argv[j];
1567 BUG_ON(i != rec_argc);
1575 const struct option kvm_options[] = {
1576 OPT_STRING(
'i',
"input", &file_name,
"file",
1578 OPT_STRING(
'o',
"output", &file_name,
"file",
1579 "Output file name"),
1581 "Collect guest os data"),
1583 "Collect host os data"),
1585 "guest mount directory under which every guest os" 1586 " instance has a subdir"),
1588 "file",
"file saving guest os vmlinux"),
1590 "file",
"file saving guest os /proc/kallsyms"),
1592 "file",
"file saving guest os /proc/modules"),
1593 OPT_INCR(
'v',
"verbose", &
verbose,
1594 "be more verbose (show counter open errors, etc)"),
1598 const char *
const kvm_subcommands[] = {
"top",
"record",
"report",
"diff",
1599 "buildid-list",
"stat", NULL };
1600 const char *kvm_usage[] = { NULL, NULL };
1605 argc = parse_options_subcommand(argc, argv, kvm_options, kvm_subcommands, kvm_usage,
1606 PARSE_OPT_STOP_AT_NON_OPTION);
1608 usage_with_options(kvm_usage, kvm_options);
1617 pr_err(
"Failed to allocate memory for filename\n");
1622 if (!strncmp(argv[0],
"rec", 3))
1624 else if (!strncmp(argv[0],
"rep", 3))
1626 else if (!strncmp(argv[0],
"diff", 4))
1628 else if (!strncmp(argv[0],
"top", 3))
1630 else if (!strncmp(argv[0],
"buildid-list", 12))
1632 #ifdef HAVE_KVM_STAT_SUPPORT 1633 else if (!strncmp(argv[0],
"stat", 4))
1634 return kvm_cmd_stat(file_name, argc, argv);
1637 usage_with_options(kvm_usage, kvm_options);
void perf_session__set_id_hdr_size(struct perf_session *session)
int cmd_report(int argc, const char **argv)
int cmd_kvm(int argc, const char **argv)
void perf_mmap__consume(struct perf_mmap *map)
bool(* is_end_event)(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key)
double avg_stats(struct stats *stats)
struct perf_evlist * evlist
struct kvm_event_stats * vcpu
static int __cmd_buildid_list(const char *file_name, int argc, const char **argv)
void(* get_key)(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key)
struct ordered_events ordered_events
int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
int ui__error(const char *format,...)
struct child_event_ops * child_ops
int cmd_record(int argc, const char **argv)
enum target_errno target__validate(struct target *target)
#define EVENTS_CACHE_SIZE
static int select_key(void)
void disable_buildid_cache(void)
void perf_evlist__enable(struct perf_evlist *evlist)
struct exit_reasons_table * exit_reasons
const char * default_guest_modules
static int machine__synthesize_threads(struct machine *machine, struct target *target, struct thread_map *threads, bool data_mmap, unsigned int proc_map_timeout, unsigned int nr_threads_synthesize)
struct list_head kvm_events_cache[EVENTS_CACHE_SIZE]
int ui__warning(const char *format,...)
static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine)
struct kvm_events_ops * ops
static struct sched_atom * last_event(struct task_desc *task)
unsigned int proc_map_timeout
struct perf_data_file file
void perf_evlist__delete(struct perf_evlist *evlist)
static struct lock_stat * pop_from_result(void)
void set_term_quiet_input(struct termios *old)
int perf_event__process_comm(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
const char * report_event
#define perf_evsel__set_sample_bit(evsel, bit)
int perf_event__process_exit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
struct kvm_events_ops * events_ops
int perf_event__process_fork(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
struct thread_map * threads
static int process_lost_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
const char * kvm_events_tp[NR_TPS+1]
double stddev_stats(struct stats *stats)
static bool target__none(struct target *target)
int perf_evlist__add_newtp(struct perf_evlist *evlist, const char *sys, const char *name, void *handler)
int setup_kvm_events_tp(struct perf_kvm_stat *kvm)
static void sort_result(void)
bool perf_session__has_traces(struct perf_session *session, const char *msg)
bool kvm_entry_event(struct perf_evsel *evsel)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
void perf_session__delete(struct perf_session *session)
int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, int unset __maybe_unused)
static void init_stats(struct stats *stats)
const char * default_guest_vmlinux_name
static void insert_to_result(struct lock_stat *st, int(*bigger)(struct lock_stat *, struct lock_stat *))
int target__strerror(struct target *target, int errnum, char *buf, size_t buflen)
struct int_node * intlist__find(struct intlist *ilist, int i)
static void print_result(struct perf_session *session)
int perf_mmap__read_init(struct perf_mmap *map)
void(* decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, char *decode)
const char *const * record_usage
#define pr_debug(fmt,...)
struct kvm_reg_events_ops kvm_reg_events_ops[]
int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
void update_stats(struct stats *stats, u64 val)
struct kvm_event_stats total
int perf_evlist__open(struct perf_evlist *evlist)
#define evlist__for_each_entry(evlist, evsel)
const char *const kvm_skip_events[]
static struct perf_tool tool
struct exit_reasons_table * exit_reasons
struct list_head hash_entry
double rel_stddev_stats(double stddev, double avg)
static const char * get_filename_for_perf_kvm(void)
int perf_evlist__parse_sample_timestamp(struct perf_evlist *evlist, union perf_event *event, u64 *timestamp)
u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, const char *name)
void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct callchain_param *callchain)
int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages)
int(* key_cmp_fun)(struct kvm_event *, struct kvm_event *, int)
bool exit_event_begin(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key)
static void ordered_events__set_copy_on_queue(struct ordered_events *oe, bool copy)
void perf_mmap__read_done(struct perf_mmap *map)
struct perf_event_header header
struct intlist * intlist__new(const char *slist)
void exit_event_decode_key(struct perf_kvm_stat *kvm, struct event_key *key, char *decode)
bool(* is_begin_event)(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key)
struct option * record_options
struct perf_session * perf_session__new(struct perf_data *data, bool repipe, struct perf_tool *tool)
const char * kvm_exit_reason
int perf_session__queue_event(struct perf_session *s, union perf_event *event, u64 timestamp, u64 file_offset)
union perf_event * perf_mmap__read_event(struct perf_mmap *map)
void thread__put(struct thread *thread)
bool kvm_exit_event(struct perf_evsel *evsel)
void perf_evlist__disable(struct perf_evlist *evlist)
int perf_session__process_events(struct perf_session *session)
unsigned int display_time
const char * default_guest_kallsyms
void exit_event_get_key(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key)
struct perf_header header
int symbol__init(struct perf_env *env)
static int __cmd_report(const char *file_name, int argc, const char **argv)
void perf_evlist__close(struct perf_evlist *evlist)
const char * exit_reasons_isa
int cmd_stat(int argc, const char **argv)
static void sig_handler(int sig __maybe_unused)
struct perf_session * session
#define perf_evsel__reset_sample_bit(evsel, bit)
static void thread__set_priv(struct thread *thread, void *p)
const char * kvm_exit_trace
int cmd_top(int argc, const char **argv)
int cmd_diff(int argc, const char **argv)
static struct perf_stat perf_stat
int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
const char * kvm_entry_trace
int cmd_buildid_list(int argc, const char **argv)
struct thread * machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid)
struct perf_evlist * evlist
struct perf_evlist * perf_evlist__new(void)
struct perf_event_attr attr
void perf_tool__fill_defaults(struct perf_tool *tool)
static int __cmd_record(const char *file_name, int argc, const char **argv)
bool exit_event_end(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key)
struct intlist * pid_list
static void * thread__priv(struct thread *thread)
void static void * zalloc(size_t size)