1 // SPDX-License-Identifier: GPL-2.0 2 #include "builtin.h" 3 #include "perf.h" 4 5 #include <dwarf-regs.h> 6 #include "util/build-id.h" 7 #include "util/evsel.h" 8 #include "util/evlist.h" 9 #include "util/mmap.h" 10 #include "util/term.h" 11 #include "util/symbol.h" 12 #include "util/thread.h" 13 #include "util/header.h" 14 #include "util/session.h" 15 #include "util/intlist.h" 16 #include <subcmd/pager.h> 17 #include <subcmd/parse-options.h> 18 #include "util/trace-event.h" 19 #include "util/debug.h" 20 #include "util/tool.h" 21 #include "util/stat.h" 22 #include "util/synthetic-events.h" 23 #include "util/top.h" 24 #include "util/data.h" 25 #include "util/event.h" 26 #include "util/ordered-events.h" 27 #include "util/kvm-stat.h" 28 #include "util/util.h" 29 #include "ui/browsers/hists.h" 30 #include "ui/progress.h" 31 #include "ui/ui.h" 32 #include "util/string2.h" 33 34 #include <sys/prctl.h> 35 #ifdef HAVE_TIMERFD_SUPPORT 36 #include <sys/timerfd.h> 37 #endif 38 #include <sys/time.h> 39 #include <sys/types.h> 40 #include <sys/stat.h> 41 #include <fcntl.h> 42 43 #include <linux/err.h> 44 #include <linux/kernel.h> 45 #include <linux/string.h> 46 #include <linux/time64.h> 47 #include <linux/zalloc.h> 48 #include <errno.h> 49 #include <inttypes.h> 50 #include <poll.h> 51 #include <termios.h> 52 #include <semaphore.h> 53 #include <signal.h> 54 #include <stdlib.h> 55 #include <math.h> 56 #include <perf/mmap.h> 57 58 #if defined(HAVE_LIBTRACEEVENT) 59 #define GET_EVENT_KEY(func, field) \ 60 static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \ 61 { \ 62 if (vcpu == -1) \ 63 return event->total.field; \ 64 \ 65 if (vcpu >= event->max_vcpu) \ 66 return 0; \ 67 \ 68 return event->vcpu[vcpu].field; \ 69 } 70 71 #define COMPARE_EVENT_KEY(func, field) \ 72 GET_EVENT_KEY(func, field) \ 73 static int64_t cmp_event_ ## func(struct kvm_event *one, \ 74 struct kvm_event *two, int vcpu) \ 75 { \ 76 return get_event_ ##func(one, vcpu) - \ 77 get_event_ ##func(two, vcpu); \ 78 } 79 80 COMPARE_EVENT_KEY(time, time); 81 COMPARE_EVENT_KEY(max, stats.max); 82 COMPARE_EVENT_KEY(min, stats.min); 83 COMPARE_EVENT_KEY(count, stats.n); 84 COMPARE_EVENT_KEY(mean, stats.mean); 85 86 struct kvm_hists { 87 struct hists hists; 88 struct perf_hpp_list list; 89 }; 90 91 struct kvm_dimension { 92 const char *name; 93 const char *header; 94 int width; 95 int64_t (*cmp)(struct perf_hpp_fmt *fmt, struct hist_entry *left, 96 struct hist_entry *right); 97 int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 98 struct hist_entry *he); 99 }; 100 101 struct kvm_fmt { 102 struct perf_hpp_fmt fmt; 103 struct kvm_dimension *dim; 104 }; 105 106 static struct kvm_hists kvm_hists; 107 108 static int64_t ev_name_cmp(struct perf_hpp_fmt *fmt __maybe_unused, 109 struct hist_entry *left, 110 struct hist_entry *right) 111 { 112 /* Return opposite number for sorting in alphabetical order */ 113 return -strcmp(left->kvm_info->name, right->kvm_info->name); 114 } 115 116 static int fmt_width(struct perf_hpp_fmt *fmt, 117 struct perf_hpp *hpp __maybe_unused, 118 struct hists *hists __maybe_unused); 119 120 static int ev_name_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 121 struct hist_entry *he) 122 { 123 int width = fmt_width(fmt, hpp, he->hists); 124 125 return scnprintf(hpp->buf, hpp->size, "%*s", width, he->kvm_info->name); 126 } 127 128 static struct kvm_dimension dim_event = { 129 .header = "Event name", 130 .name = "ev_name", 131 .cmp = ev_name_cmp, 132 .entry = ev_name_entry, 133 .width = 40, 134 }; 135 136 #define EV_METRIC_CMP(metric) \ 137 static int64_t ev_cmp_##metric(struct perf_hpp_fmt *fmt __maybe_unused, \ 138 struct hist_entry *left, \ 139 struct hist_entry *right) \ 140 { \ 141 struct kvm_event *event_left; \ 142 struct kvm_event *event_right; \ 143 struct perf_kvm_stat *perf_kvm; \ 144 \ 145 event_left = container_of(left, struct kvm_event, he); \ 146 event_right = container_of(right, struct kvm_event, he); \ 147 \ 148 perf_kvm = event_left->perf_kvm; \ 149 return cmp_event_##metric(event_left, event_right, \ 150 perf_kvm->trace_vcpu); \ 151 } 152 153 EV_METRIC_CMP(time) 154 EV_METRIC_CMP(count) 155 EV_METRIC_CMP(max) 156 EV_METRIC_CMP(min) 157 EV_METRIC_CMP(mean) 158 159 #define EV_METRIC_ENTRY(metric) \ 160 static int ev_entry_##metric(struct perf_hpp_fmt *fmt, \ 161 struct perf_hpp *hpp, \ 162 struct hist_entry *he) \ 163 { \ 164 struct kvm_event *event; \ 165 int width = fmt_width(fmt, hpp, he->hists); \ 166 struct perf_kvm_stat *perf_kvm; \ 167 \ 168 event = container_of(he, struct kvm_event, he); \ 169 perf_kvm = event->perf_kvm; \ 170 return scnprintf(hpp->buf, hpp->size, "%*lu", width, \ 171 get_event_##metric(event, perf_kvm->trace_vcpu)); \ 172 } 173 174 EV_METRIC_ENTRY(time) 175 EV_METRIC_ENTRY(count) 176 EV_METRIC_ENTRY(max) 177 EV_METRIC_ENTRY(min) 178 179 static struct kvm_dimension dim_time = { 180 .header = "Time (ns)", 181 .name = "time", 182 .cmp = ev_cmp_time, 183 .entry = ev_entry_time, 184 .width = 12, 185 }; 186 187 static struct kvm_dimension dim_count = { 188 .header = "Samples", 189 .name = "sample", 190 .cmp = ev_cmp_count, 191 .entry = ev_entry_count, 192 .width = 12, 193 }; 194 195 static struct kvm_dimension dim_max_time = { 196 .header = "Max Time (ns)", 197 .name = "max_t", 198 .cmp = ev_cmp_max, 199 .entry = ev_entry_max, 200 .width = 14, 201 }; 202 203 static struct kvm_dimension dim_min_time = { 204 .header = "Min Time (ns)", 205 .name = "min_t", 206 .cmp = ev_cmp_min, 207 .entry = ev_entry_min, 208 .width = 14, 209 }; 210 211 static int ev_entry_mean(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 212 struct hist_entry *he) 213 { 214 struct kvm_event *event; 215 int width = fmt_width(fmt, hpp, he->hists); 216 struct perf_kvm_stat *perf_kvm; 217 218 event = container_of(he, struct kvm_event, he); 219 perf_kvm = event->perf_kvm; 220 return scnprintf(hpp->buf, hpp->size, "%*lu", width, 221 get_event_mean(event, perf_kvm->trace_vcpu)); 222 } 223 224 static struct kvm_dimension dim_mean_time = { 225 .header = "Mean Time (ns)", 226 .name = "mean_t", 227 .cmp = ev_cmp_mean, 228 .entry = ev_entry_mean, 229 .width = 14, 230 }; 231 232 #define PERC_STR(__s, __v) \ 233 ({ \ 234 scnprintf(__s, sizeof(__s), "%.2F%%", __v); \ 235 __s; \ 236 }) 237 238 static double percent(u64 st, u64 tot) 239 { 240 return tot ? 100. * (double) st / (double) tot : 0; 241 } 242 243 #define EV_METRIC_PERCENT(metric) \ 244 static int ev_percent_##metric(struct hist_entry *he) \ 245 { \ 246 struct kvm_event *event; \ 247 struct perf_kvm_stat *perf_kvm; \ 248 \ 249 event = container_of(he, struct kvm_event, he); \ 250 perf_kvm = event->perf_kvm; \ 251 \ 252 return percent(get_event_##metric(event, perf_kvm->trace_vcpu), \ 253 perf_kvm->total_##metric); \ 254 } 255 256 EV_METRIC_PERCENT(time) 257 EV_METRIC_PERCENT(count) 258 259 static int ev_entry_time_precent(struct perf_hpp_fmt *fmt, 260 struct perf_hpp *hpp, 261 struct hist_entry *he) 262 { 263 int width = fmt_width(fmt, hpp, he->hists); 264 double per; 265 char buf[10]; 266 267 per = ev_percent_time(he); 268 return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per)); 269 } 270 271 static int64_t 272 ev_cmp_time_precent(struct perf_hpp_fmt *fmt __maybe_unused, 273 struct hist_entry *left, struct hist_entry *right) 274 { 275 double per_left; 276 double per_right; 277 278 per_left = ev_percent_time(left); 279 per_right = ev_percent_time(right); 280 281 return per_left - per_right; 282 } 283 284 static struct kvm_dimension dim_time_percent = { 285 .header = "Time%", 286 .name = "percent_time", 287 .cmp = ev_cmp_time_precent, 288 .entry = ev_entry_time_precent, 289 .width = 12, 290 }; 291 292 static int ev_entry_count_precent(struct perf_hpp_fmt *fmt, 293 struct perf_hpp *hpp, 294 struct hist_entry *he) 295 { 296 int width = fmt_width(fmt, hpp, he->hists); 297 double per; 298 char buf[10]; 299 300 per = ev_percent_count(he); 301 return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per)); 302 } 303 304 static int64_t 305 ev_cmp_count_precent(struct perf_hpp_fmt *fmt __maybe_unused, 306 struct hist_entry *left, struct hist_entry *right) 307 { 308 double per_left; 309 double per_right; 310 311 per_left = ev_percent_count(left); 312 per_right = ev_percent_count(right); 313 314 return per_left - per_right; 315 } 316 317 static struct kvm_dimension dim_count_percent = { 318 .header = "Sample%", 319 .name = "percent_sample", 320 .cmp = ev_cmp_count_precent, 321 .entry = ev_entry_count_precent, 322 .width = 12, 323 }; 324 325 static struct kvm_dimension *dimensions[] = { 326 &dim_event, 327 &dim_time, 328 &dim_time_percent, 329 &dim_count, 330 &dim_count_percent, 331 &dim_max_time, 332 &dim_min_time, 333 &dim_mean_time, 334 NULL, 335 }; 336 337 static int fmt_width(struct perf_hpp_fmt *fmt, 338 struct perf_hpp *hpp __maybe_unused, 339 struct hists *hists __maybe_unused) 340 { 341 struct kvm_fmt *kvm_fmt; 342 343 kvm_fmt = container_of(fmt, struct kvm_fmt, fmt); 344 return kvm_fmt->dim->width; 345 } 346 347 static int fmt_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 348 struct hists *hists, int line __maybe_unused, 349 int *span __maybe_unused) 350 { 351 struct kvm_fmt *kvm_fmt; 352 struct kvm_dimension *dim; 353 int width = fmt_width(fmt, hpp, hists); 354 355 kvm_fmt = container_of(fmt, struct kvm_fmt, fmt); 356 dim = kvm_fmt->dim; 357 358 return scnprintf(hpp->buf, hpp->size, "%*s", width, dim->header); 359 } 360 361 static bool fmt_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b) 362 { 363 struct kvm_fmt *kvm_fmt_a = container_of(a, struct kvm_fmt, fmt); 364 struct kvm_fmt *kvm_fmt_b = container_of(b, struct kvm_fmt, fmt); 365 366 return kvm_fmt_a->dim == kvm_fmt_b->dim; 367 } 368 369 static void fmt_free(struct perf_hpp_fmt *fmt) 370 { 371 struct kvm_fmt *kvm_fmt; 372 373 kvm_fmt = container_of(fmt, struct kvm_fmt, fmt); 374 free(kvm_fmt); 375 } 376 377 static struct kvm_dimension *get_dimension(const char *name) 378 { 379 unsigned int i; 380 381 for (i = 0; dimensions[i] != NULL; i++) { 382 if (!strcmp(dimensions[i]->name, name)) 383 return dimensions[i]; 384 } 385 386 return NULL; 387 } 388 389 static struct kvm_fmt *get_format(const char *name) 390 { 391 struct kvm_dimension *dim = get_dimension(name); 392 struct kvm_fmt *kvm_fmt; 393 struct perf_hpp_fmt *fmt; 394 395 if (!dim) 396 return NULL; 397 398 kvm_fmt = zalloc(sizeof(*kvm_fmt)); 399 if (!kvm_fmt) 400 return NULL; 401 402 kvm_fmt->dim = dim; 403 404 fmt = &kvm_fmt->fmt; 405 INIT_LIST_HEAD(&fmt->list); 406 INIT_LIST_HEAD(&fmt->sort_list); 407 fmt->cmp = dim->cmp; 408 fmt->sort = dim->cmp; 409 fmt->color = NULL; 410 fmt->entry = dim->entry; 411 fmt->header = fmt_header; 412 fmt->width = fmt_width; 413 fmt->collapse = dim->cmp; 414 fmt->equal = fmt_equal; 415 fmt->free = fmt_free; 416 417 return kvm_fmt; 418 } 419 420 static int kvm_hists__init_output(struct perf_hpp_list *hpp_list, char *name) 421 { 422 struct kvm_fmt *kvm_fmt = get_format(name); 423 424 if (!kvm_fmt) { 425 pr_warning("Fail to find format for output field %s.\n", name); 426 return -EINVAL; 427 } 428 429 perf_hpp_list__column_register(hpp_list, &kvm_fmt->fmt); 430 return 0; 431 } 432 433 static int kvm_hists__init_sort(struct perf_hpp_list *hpp_list, char *name) 434 { 435 struct kvm_fmt *kvm_fmt = get_format(name); 436 437 if (!kvm_fmt) { 438 pr_warning("Fail to find format for sorting %s.\n", name); 439 return -EINVAL; 440 } 441 442 perf_hpp_list__register_sort_field(hpp_list, &kvm_fmt->fmt); 443 return 0; 444 } 445 446 static int kvm_hpp_list__init(char *list, 447 struct perf_hpp_list *hpp_list, 448 int (*fn)(struct perf_hpp_list *hpp_list, 449 char *name)) 450 { 451 char *tmp, *tok; 452 int ret; 453 454 if (!list || !fn) 455 return 0; 456 457 for (tok = strtok_r(list, ", ", &tmp); tok; 458 tok = strtok_r(NULL, ", ", &tmp)) { 459 ret = fn(hpp_list, tok); 460 if (!ret) 461 continue; 462 463 /* Handle errors */ 464 if (ret == -EINVAL) 465 pr_err("Invalid field key: '%s'", tok); 466 else if (ret == -ESRCH) 467 pr_err("Unknown field key: '%s'", tok); 468 else 469 pr_err("Fail to initialize for field key: '%s'", tok); 470 471 break; 472 } 473 474 return ret; 475 } 476 477 static int kvm_hpp_list__parse(struct perf_hpp_list *hpp_list, 478 const char *output_, const char *sort_) 479 { 480 char *output = output_ ? strdup(output_) : NULL; 481 char *sort = sort_ ? strdup(sort_) : NULL; 482 int ret; 483 484 ret = kvm_hpp_list__init(output, hpp_list, kvm_hists__init_output); 485 if (ret) 486 goto out; 487 488 ret = kvm_hpp_list__init(sort, hpp_list, kvm_hists__init_sort); 489 if (ret) 490 goto out; 491 492 /* Copy sort keys to output fields */ 493 perf_hpp__setup_output_field(hpp_list); 494 495 /* and then copy output fields to sort keys */ 496 perf_hpp__append_sort_keys(hpp_list); 497 out: 498 free(output); 499 free(sort); 500 return ret; 501 } 502 503 static int kvm_hists__init(void) 504 { 505 kvm_hists.list.nr_header_lines = 1; 506 __hists__init(&kvm_hists.hists, &kvm_hists.list); 507 perf_hpp_list__init(&kvm_hists.list); 508 return kvm_hpp_list__parse(&kvm_hists.list, NULL, "ev_name"); 509 } 510 511 static int kvm_hists__reinit(const char *output, const char *sort) 512 { 513 perf_hpp__reset_output_field(&kvm_hists.list); 514 return kvm_hpp_list__parse(&kvm_hists.list, output, sort); 515 } 516 static void print_result(struct perf_kvm_stat *kvm); 517 518 #ifdef HAVE_SLANG_SUPPORT 519 static void kvm_browser__update_nr_entries(struct hist_browser *hb) 520 { 521 struct rb_node *nd = rb_first_cached(&hb->hists->entries); 522 u64 nr_entries = 0; 523 524 for (; nd; nd = rb_next(nd)) { 525 struct hist_entry *he = rb_entry(nd, struct hist_entry, 526 rb_node); 527 528 if (!he->filtered) 529 nr_entries++; 530 } 531 532 hb->nr_non_filtered_entries = nr_entries; 533 } 534 535 static int kvm_browser__title(struct hist_browser *browser, 536 char *buf, size_t size) 537 { 538 scnprintf(buf, size, "KVM event statistics (%lu entries)", 539 browser->nr_non_filtered_entries); 540 return 0; 541 } 542 543 static struct hist_browser* 544 perf_kvm_browser__new(struct hists *hists) 545 { 546 struct hist_browser *browser = hist_browser__new(hists); 547 548 if (browser) 549 browser->title = kvm_browser__title; 550 551 return browser; 552 } 553 554 static int kvm__hists_browse(struct hists *hists) 555 { 556 struct hist_browser *browser; 557 int key = -1; 558 559 browser = perf_kvm_browser__new(hists); 560 if (browser == NULL) 561 return -1; 562 563 /* reset abort key so that it can get Ctrl-C as a key */ 564 SLang_reset_tty(); 565 SLang_init_tty(0, 0, 0); 566 567 kvm_browser__update_nr_entries(browser); 568 569 while (1) { 570 key = hist_browser__run(browser, "? - help", true, 0); 571 572 switch (key) { 573 case 'q': 574 goto out; 575 default: 576 break; 577 } 578 } 579 580 out: 581 hist_browser__delete(browser); 582 return 0; 583 } 584 585 static void kvm_display(struct perf_kvm_stat *kvm) 586 { 587 if (!use_browser) 588 print_result(kvm); 589 else 590 kvm__hists_browse(&kvm_hists.hists); 591 } 592 593 #else 594 595 static void kvm_display(struct perf_kvm_stat *kvm) 596 { 597 use_browser = 0; 598 print_result(kvm); 599 } 600 601 #endif /* HAVE_SLANG_SUPPORT */ 602 603 #endif // defined(HAVE_LIBTRACEEVENT) 604 605 static const char *get_filename_for_perf_kvm(void) 606 { 607 const char *filename; 608 609 if (perf_host && !perf_guest) 610 filename = "perf.data.host"; 611 else if (!perf_host && perf_guest) 612 filename = "perf.data.guest"; 613 else 614 filename = "perf.data.kvm"; 615 616 return filename; 617 } 618 619 #if defined(HAVE_LIBTRACEEVENT) 620 621 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm, uint16_t e_machine) 622 { 623 const struct kvm_reg_events_ops *events_ops; 624 625 for (events_ops = kvm_reg_events_ops(e_machine); events_ops->name; events_ops++) { 626 if (!strcmp(events_ops->name, kvm->report_event)) { 627 kvm->events_ops = events_ops->ops; 628 return true; 629 } 630 } 631 632 return false; 633 } 634 635 struct vcpu_event_record { 636 int vcpu_id; 637 u64 start_time; 638 struct kvm_event *last_event; 639 }; 640 641 #ifdef HAVE_TIMERFD_SUPPORT 642 static void clear_events_cache_stats(void) 643 { 644 struct rb_root_cached *root; 645 struct rb_node *nd; 646 struct kvm_event *event; 647 int i; 648 649 if (hists__has(&kvm_hists.hists, need_collapse)) 650 root = &kvm_hists.hists.entries_collapsed; 651 else 652 root = kvm_hists.hists.entries_in; 653 654 for (nd = rb_first_cached(root); nd; nd = rb_next(nd)) { 655 struct hist_entry *he; 656 657 he = rb_entry(nd, struct hist_entry, rb_node_in); 658 event = container_of(he, struct kvm_event, he); 659 660 /* reset stats for event */ 661 event->total.time = 0; 662 init_stats(&event->total.stats); 663 664 for (i = 0; i < event->max_vcpu; ++i) { 665 event->vcpu[i].time = 0; 666 init_stats(&event->vcpu[i].stats); 667 } 668 } 669 } 670 #endif 671 672 static bool kvm_event_expand(struct kvm_event *event, int vcpu_id) 673 { 674 int old_max_vcpu = event->max_vcpu; 675 void *prev; 676 677 if (vcpu_id < event->max_vcpu) 678 return true; 679 680 while (event->max_vcpu <= vcpu_id) 681 event->max_vcpu += DEFAULT_VCPU_NUM; 682 683 prev = event->vcpu; 684 event->vcpu = realloc(event->vcpu, 685 event->max_vcpu * sizeof(*event->vcpu)); 686 if (!event->vcpu) { 687 free(prev); 688 pr_err("Not enough memory\n"); 689 return false; 690 } 691 692 memset(event->vcpu + old_max_vcpu, 0, 693 (event->max_vcpu - old_max_vcpu) * sizeof(*event->vcpu)); 694 return true; 695 } 696 697 static void *kvm_he_zalloc(size_t size) 698 { 699 struct kvm_event *kvm_ev; 700 701 kvm_ev = zalloc(size + sizeof(*kvm_ev)); 702 if (!kvm_ev) 703 return NULL; 704 705 init_stats(&kvm_ev->total.stats); 706 hists__inc_nr_samples(&kvm_hists.hists, 0); 707 return &kvm_ev->he; 708 } 709 710 static void kvm_he_free(void *he) 711 { 712 struct kvm_event *kvm_ev; 713 714 kvm_ev = container_of(he, struct kvm_event, he); 715 free(kvm_ev); 716 } 717 718 static struct hist_entry_ops kvm_ev_entry_ops = { 719 .new = kvm_he_zalloc, 720 .free = kvm_he_free, 721 }; 722 723 static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm, 724 struct event_key *key, 725 struct perf_sample *sample) 726 { 727 struct kvm_event *event; 728 struct hist_entry *he; 729 struct kvm_info *ki; 730 731 BUG_ON(key->key == INVALID_KEY); 732 733 ki = kvm_info__new(); 734 if (!ki) { 735 pr_err("Failed to allocate kvm info\n"); 736 return NULL; 737 } 738 739 kvm->events_ops->decode_key(kvm, key, ki->name); 740 he = hists__add_entry_ops(&kvm_hists.hists, &kvm_ev_entry_ops, 741 &kvm->al, NULL, NULL, NULL, ki, sample, true); 742 if (he == NULL) { 743 pr_err("Failed to allocate hist entry\n"); 744 free(ki); 745 return NULL; 746 } 747 748 event = container_of(he, struct kvm_event, he); 749 if (!event->perf_kvm) { 750 event->perf_kvm = kvm; 751 event->key = *key; 752 } 753 754 return event; 755 } 756 757 static bool handle_begin_event(struct perf_kvm_stat *kvm, 758 struct vcpu_event_record *vcpu_record, 759 struct event_key *key, 760 struct perf_sample *sample) 761 { 762 struct kvm_event *event = NULL; 763 764 if (key->key != INVALID_KEY) 765 event = find_create_kvm_event(kvm, key, sample); 766 767 vcpu_record->last_event = event; 768 vcpu_record->start_time = sample->time; 769 return true; 770 } 771 772 static void 773 kvm_update_event_stats(struct kvm_event_stats *kvm_stats, u64 time_diff) 774 { 775 kvm_stats->time += time_diff; 776 update_stats(&kvm_stats->stats, time_diff); 777 } 778 779 static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event) 780 { 781 struct kvm_event_stats *kvm_stats = &event->total; 782 783 if (vcpu_id != -1) 784 kvm_stats = &event->vcpu[vcpu_id]; 785 786 return rel_stddev_stats(stddev_stats(&kvm_stats->stats), 787 avg_stats(&kvm_stats->stats)); 788 } 789 790 static bool update_kvm_event(struct perf_kvm_stat *kvm, 791 struct kvm_event *event, int vcpu_id, 792 u64 time_diff) 793 { 794 /* Update overall statistics */ 795 kvm->total_count++; 796 kvm->total_time += time_diff; 797 798 if (vcpu_id == -1) { 799 kvm_update_event_stats(&event->total, time_diff); 800 return true; 801 } 802 803 if (!kvm_event_expand(event, vcpu_id)) 804 return false; 805 806 kvm_update_event_stats(&event->vcpu[vcpu_id], time_diff); 807 return true; 808 } 809 810 static bool is_child_event(struct perf_kvm_stat *kvm, 811 struct perf_sample *sample, 812 struct event_key *key) 813 { 814 const struct child_event_ops *child_ops; 815 816 child_ops = kvm->events_ops->child_ops; 817 818 if (!child_ops) 819 return false; 820 821 for (; child_ops->name; child_ops++) { 822 if (evsel__name_is(sample->evsel, child_ops->name)) { 823 child_ops->get_key(sample, key); 824 return true; 825 } 826 } 827 828 return false; 829 } 830 831 static bool handle_child_event(struct perf_kvm_stat *kvm, 832 struct vcpu_event_record *vcpu_record, 833 struct event_key *key, 834 struct perf_sample *sample) 835 { 836 struct kvm_event *event = NULL; 837 838 if (key->key != INVALID_KEY) 839 event = find_create_kvm_event(kvm, key, sample); 840 841 vcpu_record->last_event = event; 842 843 return true; 844 } 845 846 static bool skip_event(uint16_t e_machine, const char *event) 847 { 848 const char * const *skip_events; 849 850 for (skip_events = kvm_skip_events(e_machine); *skip_events; skip_events++) 851 if (!strcmp(event, *skip_events)) 852 return true; 853 854 return false; 855 } 856 857 static bool handle_end_event(struct perf_kvm_stat *kvm, 858 struct vcpu_event_record *vcpu_record, 859 struct event_key *key, 860 struct perf_sample *sample) 861 { 862 struct kvm_event *event; 863 u64 time_begin, time_diff; 864 int vcpu; 865 866 if (kvm->trace_vcpu == -1) 867 vcpu = -1; 868 else 869 vcpu = vcpu_record->vcpu_id; 870 871 event = vcpu_record->last_event; 872 time_begin = vcpu_record->start_time; 873 874 /* The begin event is not caught. */ 875 if (!time_begin) 876 return true; 877 878 /* 879 * In some case, the 'begin event' only records the start timestamp, 880 * the actual event is recognized in the 'end event' (e.g. mmio-event). 881 */ 882 883 /* Both begin and end events did not get the key. */ 884 if (!event && key->key == INVALID_KEY) 885 return true; 886 887 if (!event) 888 event = find_create_kvm_event(kvm, key, sample); 889 890 if (!event) 891 return false; 892 893 vcpu_record->last_event = NULL; 894 vcpu_record->start_time = 0; 895 896 /* seems to happen once in a while during live mode */ 897 if (sample->time < time_begin) { 898 pr_debug("End time before begin time; skipping event.\n"); 899 return true; 900 } 901 902 time_diff = sample->time - time_begin; 903 904 if (kvm->duration && time_diff > kvm->duration) { 905 char decode[KVM_EVENT_NAME_LEN]; 906 uint16_t e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); 907 908 kvm->events_ops->decode_key(kvm, &event->key, decode); 909 if (!skip_event(e_machine, decode)) { 910 pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n", 911 sample->time, sample->pid, vcpu_record->vcpu_id, 912 decode, time_diff / NSEC_PER_USEC); 913 } 914 } 915 916 return update_kvm_event(kvm, event, vcpu, time_diff); 917 } 918 919 static 920 struct vcpu_event_record *per_vcpu_record(struct thread *thread, 921 struct perf_sample *sample) 922 { 923 /* Only kvm_entry records vcpu id. */ 924 if (!thread__priv(thread) && kvm_entry_event(sample->evsel)) { 925 struct vcpu_event_record *vcpu_record; 926 struct machine *machine = maps__machine(thread__maps(thread)); 927 uint16_t e_machine = thread__e_machine(thread, machine, /*e_flags=*/NULL); 928 929 vcpu_record = zalloc(sizeof(*vcpu_record)); 930 if (!vcpu_record) { 931 pr_err("%s: Not enough memory\n", __func__); 932 return NULL; 933 } 934 935 vcpu_record->vcpu_id = perf_sample__intval(sample, vcpu_id_str(e_machine)); 936 thread__set_priv(thread, vcpu_record); 937 } 938 939 return thread__priv(thread); 940 } 941 942 static bool handle_kvm_event(struct perf_kvm_stat *kvm, 943 struct thread *thread, 944 struct perf_sample *sample) 945 { 946 struct vcpu_event_record *vcpu_record; 947 struct event_key key = { .key = INVALID_KEY, 948 .exit_reasons = kvm->exit_reasons }; 949 950 vcpu_record = per_vcpu_record(thread, sample); 951 if (!vcpu_record) 952 return true; 953 954 /* only process events for vcpus user cares about */ 955 if ((kvm->trace_vcpu != -1) && 956 (kvm->trace_vcpu != vcpu_record->vcpu_id)) 957 return true; 958 959 if (kvm->events_ops->is_begin_event(sample, &key)) 960 return handle_begin_event(kvm, vcpu_record, &key, sample); 961 962 if (is_child_event(kvm, sample, &key)) 963 return handle_child_event(kvm, vcpu_record, &key, sample); 964 965 if (kvm->events_ops->is_end_event(sample, &key)) 966 return handle_end_event(kvm, vcpu_record, &key, sample); 967 968 return true; 969 } 970 971 static bool is_valid_key(struct perf_kvm_stat *kvm) 972 { 973 static const char *key_array[] = { 974 "ev_name", "sample", "time", "max_t", "min_t", "mean_t", 975 }; 976 unsigned int i; 977 978 for (i = 0; i < ARRAY_SIZE(key_array); i++) 979 if (!strcmp(key_array[i], kvm->sort_key)) 980 return true; 981 982 pr_err("Unsupported sort key: %s\n", kvm->sort_key); 983 return false; 984 } 985 986 static bool event_is_valid(struct kvm_event *event, int vcpu) 987 { 988 return !!get_event_count(event, vcpu); 989 } 990 991 static int filter_cb(struct hist_entry *he, void *arg __maybe_unused) 992 { 993 struct kvm_event *event; 994 struct perf_kvm_stat *perf_kvm; 995 996 event = container_of(he, struct kvm_event, he); 997 perf_kvm = event->perf_kvm; 998 if (!event_is_valid(event, perf_kvm->trace_vcpu)) 999 he->filtered = 1; 1000 else 1001 he->filtered = 0; 1002 return 0; 1003 } 1004 1005 static void sort_result(struct perf_kvm_stat *kvm) 1006 { 1007 struct ui_progress prog; 1008 const char *output_columns = "ev_name,sample,percent_sample," 1009 "time,percent_time,max_t,min_t,mean_t"; 1010 1011 kvm_hists__reinit(output_columns, kvm->sort_key); 1012 ui_progress__init(&prog, kvm_hists.hists.nr_entries, "Sorting..."); 1013 hists__collapse_resort(&kvm_hists.hists, NULL); 1014 hists__output_resort_cb(&kvm_hists.hists, NULL, filter_cb); 1015 ui_progress__finish(); 1016 } 1017 1018 static void print_vcpu_info(struct perf_kvm_stat *kvm) 1019 { 1020 int vcpu = kvm->trace_vcpu; 1021 1022 pr_info("Analyze events for "); 1023 1024 if (kvm->opts.target.system_wide) 1025 pr_info("all VMs, "); 1026 else if (kvm->opts.target.pid) 1027 pr_info("pid(s) %s, ", kvm->opts.target.pid); 1028 else 1029 pr_info("dazed and confused on what is monitored, "); 1030 1031 if (vcpu == -1) 1032 pr_info("all VCPUs:\n\n"); 1033 else 1034 pr_info("VCPU %d:\n\n", vcpu); 1035 } 1036 1037 static void show_timeofday(void) 1038 { 1039 char date[64]; 1040 struct timeval tv; 1041 struct tm ltime; 1042 1043 gettimeofday(&tv, NULL); 1044 if (localtime_r(&tv.tv_sec, <ime)) { 1045 strftime(date, sizeof(date), "%H:%M:%S", <ime); 1046 pr_info("%s.%06ld", date, tv.tv_usec); 1047 } else 1048 pr_info("00:00:00.000000"); 1049 1050 return; 1051 } 1052 1053 static void print_result(struct perf_kvm_stat *kvm) 1054 { 1055 char decode[KVM_EVENT_NAME_LEN]; 1056 struct kvm_event *event; 1057 int vcpu = kvm->trace_vcpu; 1058 struct rb_node *nd; 1059 1060 if (kvm->live) { 1061 puts(CONSOLE_CLEAR); 1062 show_timeofday(); 1063 } 1064 1065 pr_info("\n\n"); 1066 print_vcpu_info(kvm); 1067 pr_info("%*s ", KVM_EVENT_NAME_LEN, kvm->events_ops->name); 1068 pr_info("%10s ", "Samples"); 1069 pr_info("%9s ", "Samples%"); 1070 1071 pr_info("%9s ", "Time%"); 1072 pr_info("%11s ", "Min Time"); 1073 pr_info("%11s ", "Max Time"); 1074 pr_info("%16s ", "Avg time"); 1075 pr_info("\n\n"); 1076 1077 for (nd = rb_first_cached(&kvm_hists.hists.entries); nd; nd = rb_next(nd)) { 1078 struct hist_entry *he; 1079 u64 ecount, etime, max, min; 1080 1081 he = rb_entry(nd, struct hist_entry, rb_node); 1082 if (he->filtered) 1083 continue; 1084 1085 event = container_of(he, struct kvm_event, he); 1086 ecount = get_event_count(event, vcpu); 1087 etime = get_event_time(event, vcpu); 1088 max = get_event_max(event, vcpu); 1089 min = get_event_min(event, vcpu); 1090 1091 kvm->events_ops->decode_key(kvm, &event->key, decode); 1092 pr_info("%*s ", KVM_EVENT_NAME_LEN, decode); 1093 pr_info("%10llu ", (unsigned long long)ecount); 1094 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100); 1095 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100); 1096 pr_info("%9.2fus ", (double)min / NSEC_PER_USEC); 1097 pr_info("%9.2fus ", (double)max / NSEC_PER_USEC); 1098 pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount / NSEC_PER_USEC, 1099 kvm_event_rel_stddev(vcpu, event)); 1100 pr_info("\n"); 1101 } 1102 1103 pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n", 1104 kvm->total_count, kvm->total_time / (double)NSEC_PER_USEC); 1105 1106 if (kvm->lost_events) 1107 pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events); 1108 } 1109 1110 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1111 static int process_lost_event(const struct perf_tool *tool, 1112 union perf_event *event __maybe_unused, 1113 struct perf_sample *sample __maybe_unused, 1114 struct machine *machine __maybe_unused) 1115 { 1116 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool); 1117 1118 kvm->lost_events++; 1119 return 0; 1120 } 1121 #endif 1122 1123 static bool skip_sample(struct perf_kvm_stat *kvm, 1124 struct perf_sample *sample) 1125 { 1126 if (kvm->pid_list && intlist__find(kvm->pid_list, sample->pid) == NULL) 1127 return true; 1128 1129 return false; 1130 } 1131 1132 static int process_sample_event(const struct perf_tool *tool, 1133 union perf_event *event, 1134 struct perf_sample *sample, 1135 struct machine *machine) 1136 { 1137 int err = 0; 1138 struct thread *thread; 1139 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, 1140 tool); 1141 1142 if (skip_sample(kvm, sample)) 1143 return 0; 1144 1145 if (machine__resolve(machine, &kvm->al, sample) < 0) { 1146 pr_warning("WARNING: at offset %#" PRIx64 ": fail to resolve address location, skipping sample\n", 1147 sample->file_offset); 1148 return 0; 1149 } 1150 1151 thread = machine__findnew_thread(machine, sample->pid, sample->tid); 1152 if (thread == NULL) { 1153 pr_debug("problem processing %s (%u) event at offset %#" PRIx64 ", skipping it.\n", 1154 perf_event__name(event->header.type), event->header.type, 1155 sample->file_offset); 1156 err = -1; 1157 goto out; 1158 } 1159 1160 if (!handle_kvm_event(kvm, thread, sample)) 1161 err = -1; 1162 1163 thread__put(thread); 1164 out: 1165 addr_location__exit(&kvm->al); 1166 return err; 1167 } 1168 1169 static int cpu_isa_config(struct perf_kvm_stat *kvm) 1170 { 1171 char buf[128], *cpuid; 1172 int err; 1173 uint16_t e_machine; 1174 1175 if (kvm->live) { 1176 struct perf_cpu cpu = {-1}; 1177 1178 err = get_cpuid(buf, sizeof(buf), cpu); 1179 if (err != 0) { 1180 pr_err("Failed to look up CPU type: %s\n", 1181 str_error_r(err, buf, sizeof(buf))); 1182 return -err; 1183 } 1184 cpuid = buf; 1185 } else 1186 cpuid = perf_session__env(kvm->session)->cpuid; 1187 1188 if (!cpuid) { 1189 pr_err("Failed to look up CPU type\n"); 1190 return -EINVAL; 1191 } 1192 1193 e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); 1194 err = cpu_isa_init(kvm, e_machine, cpuid); 1195 if (err == -ENOTSUP) 1196 pr_err("CPU %s is not supported.\n", cpuid); 1197 1198 return err; 1199 } 1200 1201 static bool verify_vcpu(int vcpu) 1202 { 1203 if (vcpu != -1 && vcpu < 0) { 1204 pr_err("Invalid vcpu:%d.\n", vcpu); 1205 return false; 1206 } 1207 1208 return true; 1209 } 1210 1211 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1212 /* keeping the max events to a modest level to keep 1213 * the processing of samples per mmap smooth. 1214 */ 1215 #define PERF_KVM__MAX_EVENTS_PER_MMAP 25 1216 1217 static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx, 1218 u64 *mmap_time) 1219 { 1220 struct evlist *evlist = kvm->evlist; 1221 union perf_event *event; 1222 struct mmap *md; 1223 u64 timestamp; 1224 s64 n = 0; 1225 int err; 1226 1227 *mmap_time = ULLONG_MAX; 1228 md = &evlist__mmap(evlist)[idx]; 1229 err = perf_mmap__read_init(&md->core); 1230 if (err < 0) 1231 return (err == -EAGAIN) ? 0 : -1; 1232 1233 while ((event = perf_mmap__read_event(&md->core)) != NULL) { 1234 err = evlist__parse_sample_timestamp(evlist, event, ×tamp); 1235 if (err) { 1236 perf_mmap__consume(&md->core); 1237 pr_err("Failed to parse sample\n"); 1238 return -1; 1239 } 1240 1241 err = perf_session__queue_event(kvm->session, event, timestamp, 0, NULL); 1242 /* 1243 * FIXME: Here we can't consume the event, as perf_session__queue_event will 1244 * point to it, and it'll get possibly overwritten by the kernel. 1245 */ 1246 perf_mmap__consume(&md->core); 1247 1248 if (err) { 1249 pr_err("Failed to enqueue sample: %d\n", err); 1250 return -1; 1251 } 1252 1253 /* save time stamp of our first sample for this mmap */ 1254 if (n == 0) 1255 *mmap_time = timestamp; 1256 1257 /* limit events per mmap handled all at once */ 1258 n++; 1259 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP) 1260 break; 1261 } 1262 1263 perf_mmap__read_done(&md->core); 1264 return n; 1265 } 1266 1267 static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm) 1268 { 1269 int i, err, throttled = 0; 1270 s64 n, ntotal = 0; 1271 u64 flush_time = ULLONG_MAX, mmap_time; 1272 1273 for (i = 0; i < evlist__core(kvm->evlist)->nr_mmaps; i++) { 1274 n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time); 1275 if (n < 0) 1276 return -1; 1277 1278 /* flush time is going to be the minimum of all the individual 1279 * mmap times. Essentially, we flush all the samples queued up 1280 * from the last pass under our minimal start time -- that leaves 1281 * a very small race for samples to come in with a lower timestamp. 1282 * The ioctl to return the perf_clock timestamp should close the 1283 * race entirely. 1284 */ 1285 if (mmap_time < flush_time) 1286 flush_time = mmap_time; 1287 1288 ntotal += n; 1289 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP) 1290 throttled = 1; 1291 } 1292 1293 /* flush queue after each round in which we processed events */ 1294 if (ntotal) { 1295 struct ordered_events *oe = &kvm->session->ordered_events; 1296 1297 oe->next_flush = flush_time; 1298 err = ordered_events__flush(oe, OE_FLUSH__ROUND); 1299 if (err) { 1300 if (kvm->lost_events) 1301 pr_info("\nLost events: %" PRIu64 "\n\n", 1302 kvm->lost_events); 1303 return err; 1304 } 1305 } 1306 1307 return throttled; 1308 } 1309 1310 static volatile int done; 1311 1312 static void sig_handler(int sig __maybe_unused) 1313 { 1314 done = 1; 1315 } 1316 1317 static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm) 1318 { 1319 struct itimerspec new_value; 1320 int rc = -1; 1321 1322 kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); 1323 if (kvm->timerfd < 0) { 1324 pr_err("timerfd_create failed\n"); 1325 goto out; 1326 } 1327 1328 new_value.it_value.tv_sec = kvm->display_time; 1329 new_value.it_value.tv_nsec = 0; 1330 new_value.it_interval.tv_sec = kvm->display_time; 1331 new_value.it_interval.tv_nsec = 0; 1332 1333 if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) { 1334 pr_err("timerfd_settime failed: %d\n", errno); 1335 close(kvm->timerfd); 1336 goto out; 1337 } 1338 1339 rc = 0; 1340 out: 1341 return rc; 1342 } 1343 1344 static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm) 1345 { 1346 uint64_t c; 1347 int rc; 1348 1349 rc = read(kvm->timerfd, &c, sizeof(uint64_t)); 1350 if (rc < 0) { 1351 if (errno == EAGAIN) 1352 return 0; 1353 1354 pr_err("Failed to read timer fd: %d\n", errno); 1355 return -1; 1356 } 1357 1358 if (rc != sizeof(uint64_t)) { 1359 pr_err("Error reading timer fd - invalid size returned\n"); 1360 return -1; 1361 } 1362 1363 if (c != 1) 1364 pr_debug("Missed timer beats: %" PRIu64 "\n", c-1); 1365 1366 /* update display */ 1367 sort_result(kvm); 1368 print_result(kvm); 1369 1370 /* Reset sort list to "ev_name" */ 1371 kvm_hists__reinit(NULL, "ev_name"); 1372 1373 /* reset counts */ 1374 clear_events_cache_stats(); 1375 kvm->total_count = 0; 1376 kvm->total_time = 0; 1377 kvm->lost_events = 0; 1378 1379 return 0; 1380 } 1381 1382 static int fd_set_nonblock(int fd) 1383 { 1384 long arg = 0; 1385 1386 arg = fcntl(fd, F_GETFL); 1387 if (arg < 0) { 1388 pr_err("Failed to get current flags for fd %d\n", fd); 1389 return -1; 1390 } 1391 1392 if (fcntl(fd, F_SETFL, arg | O_NONBLOCK) < 0) { 1393 pr_err("Failed to set non-block option on fd %d\n", fd); 1394 return -1; 1395 } 1396 1397 return 0; 1398 } 1399 1400 static int perf_kvm__handle_stdin(void) 1401 { 1402 int c; 1403 1404 c = getc(stdin); 1405 if (c == 'q') 1406 return 1; 1407 1408 return 0; 1409 } 1410 1411 static int kvm_events_live_report(struct perf_kvm_stat *kvm) 1412 { 1413 int nr_stdin, ret, err = -EINVAL; 1414 struct termios save; 1415 1416 /* live flag must be set first */ 1417 kvm->live = true; 1418 1419 ret = cpu_isa_config(kvm); 1420 if (ret < 0) 1421 return ret; 1422 1423 if (!verify_vcpu(kvm->trace_vcpu) || 1424 !is_valid_key(kvm) || 1425 !register_kvm_events_ops(kvm, EM_HOST)) { 1426 goto out; 1427 } 1428 1429 set_term_quiet_input(&save); 1430 1431 kvm_hists__init(); 1432 1433 signal(SIGINT, sig_handler); 1434 signal(SIGTERM, sig_handler); 1435 1436 /* add timer fd */ 1437 if (perf_kvm__timerfd_create(kvm) < 0) { 1438 err = -1; 1439 goto out; 1440 } 1441 1442 if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0) 1443 goto out; 1444 1445 nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin)); 1446 if (nr_stdin < 0) 1447 goto out; 1448 1449 if (fd_set_nonblock(fileno(stdin)) != 0) 1450 goto out; 1451 1452 /* everything is good - enable the events and process */ 1453 evlist__enable(kvm->evlist); 1454 1455 while (!done) { 1456 struct fdarray *fda = &evlist__core(kvm->evlist)->pollfd; 1457 int rc; 1458 1459 rc = perf_kvm__mmap_read(kvm); 1460 if (rc < 0) 1461 break; 1462 1463 err = perf_kvm__handle_timerfd(kvm); 1464 if (err) 1465 goto out; 1466 1467 if (fda->entries[nr_stdin].revents & POLLIN) 1468 done = perf_kvm__handle_stdin(); 1469 1470 if (!rc && !done) 1471 err = evlist__poll(kvm->evlist, 100); 1472 } 1473 1474 evlist__disable(kvm->evlist); 1475 1476 if (err == 0) { 1477 sort_result(kvm); 1478 print_result(kvm); 1479 } 1480 1481 out: 1482 hists__delete_entries(&kvm_hists.hists); 1483 1484 if (kvm->timerfd >= 0) 1485 close(kvm->timerfd); 1486 1487 tcsetattr(0, TCSAFLUSH, &save); 1488 return err; 1489 } 1490 1491 static int kvm_live_open_events(struct perf_kvm_stat *kvm) 1492 { 1493 int err, rc = -1; 1494 struct evsel *pos; 1495 struct evlist *evlist = kvm->evlist; 1496 char sbuf[STRERR_BUFSIZE]; 1497 1498 evlist__config(evlist, &kvm->opts, NULL); 1499 1500 /* 1501 * Note: exclude_{guest,host} do not apply here. 1502 * This command processes KVM tracepoints from host only 1503 */ 1504 evlist__for_each_entry(evlist, pos) { 1505 struct perf_event_attr *attr = &pos->core.attr; 1506 1507 /* make sure these *are* set */ 1508 evsel__set_sample_bit(pos, TID); 1509 evsel__set_sample_bit(pos, TIME); 1510 evsel__set_sample_bit(pos, CPU); 1511 evsel__set_sample_bit(pos, RAW); 1512 /* make sure these are *not*; want as small a sample as possible */ 1513 evsel__reset_sample_bit(pos, PERIOD); 1514 evsel__reset_sample_bit(pos, IP); 1515 evsel__reset_sample_bit(pos, CALLCHAIN); 1516 evsel__reset_sample_bit(pos, ADDR); 1517 evsel__reset_sample_bit(pos, READ); 1518 attr->mmap = 0; 1519 attr->comm = 0; 1520 attr->task = 0; 1521 1522 attr->sample_period = 1; 1523 1524 attr->watermark = 0; 1525 attr->wakeup_events = 1000; 1526 1527 /* will enable all once we are ready */ 1528 attr->disabled = 1; 1529 } 1530 1531 err = evlist__open(evlist); 1532 if (err < 0) { 1533 printf("Couldn't create the events: %s\n", 1534 str_error_r(errno, sbuf, sizeof(sbuf))); 1535 goto out; 1536 } 1537 1538 if (evlist__do_mmap(evlist, kvm->opts.mmap_pages) < 0) { 1539 ui__error("Failed to mmap the events: %s\n", 1540 str_error_r(errno, sbuf, sizeof(sbuf))); 1541 evlist__close(evlist); 1542 goto out; 1543 } 1544 1545 rc = 0; 1546 1547 out: 1548 return rc; 1549 } 1550 #endif 1551 1552 static int read_events(struct perf_kvm_stat *kvm) 1553 { 1554 int ret; 1555 uint16_t e_machine; 1556 struct perf_data file = { 1557 .path = kvm->file_name, 1558 .mode = PERF_DATA_MODE_READ, 1559 .force = kvm->force, 1560 }; 1561 1562 perf_tool__init(&kvm->tool, /*ordered_events=*/true); 1563 kvm->tool.sample = process_sample_event; 1564 kvm->tool.comm = perf_event__process_comm; 1565 kvm->tool.namespaces = perf_event__process_namespaces; 1566 1567 kvm->session = perf_session__new(&file, &kvm->tool); 1568 if (IS_ERR(kvm->session)) { 1569 pr_err("Initializing perf session failed\n"); 1570 return PTR_ERR(kvm->session); 1571 } 1572 1573 symbol__init(perf_session__env(kvm->session)); 1574 1575 if (!perf_session__has_traces(kvm->session, "kvm record")) { 1576 ret = -EINVAL; 1577 goto out_delete; 1578 } 1579 1580 e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); 1581 if (!register_kvm_events_ops(kvm, e_machine)) { 1582 ret = -EINVAL; 1583 goto out_delete; 1584 } 1585 1586 /* 1587 * Do not use 'isa' recorded in kvm_exit tracepoint since it is not 1588 * traced in the old kernel. 1589 */ 1590 ret = cpu_isa_config(kvm); 1591 if (ret < 0) 1592 goto out_delete; 1593 1594 ret = perf_session__process_events(kvm->session); 1595 1596 out_delete: 1597 perf_session__delete(kvm->session); 1598 return ret; 1599 } 1600 1601 static int parse_target_str(struct perf_kvm_stat *kvm) 1602 { 1603 if (kvm->opts.target.pid) { 1604 kvm->pid_list = intlist__new(kvm->opts.target.pid); 1605 if (kvm->pid_list == NULL) { 1606 pr_err("Error parsing process id string\n"); 1607 return -EINVAL; 1608 } 1609 } 1610 1611 return 0; 1612 } 1613 1614 static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm) 1615 { 1616 int ret = -EINVAL; 1617 int vcpu = kvm->trace_vcpu; 1618 1619 if (parse_target_str(kvm) != 0) 1620 goto exit; 1621 1622 if (!verify_vcpu(vcpu)) 1623 goto exit; 1624 1625 if (!is_valid_key(kvm)) 1626 goto exit; 1627 1628 if (kvm->use_stdio) { 1629 use_browser = 0; 1630 setup_pager(); 1631 } else { 1632 use_browser = 1; 1633 } 1634 1635 setup_browser(false); 1636 1637 kvm_hists__init(); 1638 1639 ret = read_events(kvm); 1640 if (ret) 1641 goto exit; 1642 1643 sort_result(kvm); 1644 kvm_display(kvm); 1645 1646 exit: 1647 hists__delete_entries(&kvm_hists.hists); 1648 return ret; 1649 } 1650 1651 static int 1652 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) 1653 { 1654 unsigned int rec_argc, i, j, events_tp_size; 1655 const char **rec_argv; 1656 const char * const record_args[] = { 1657 "record", 1658 "-R", 1659 "-m", "1024", 1660 "-c", "1", 1661 }; 1662 const char * const kvm_stat_record_usage[] = { 1663 "perf kvm stat record [<options>]", 1664 NULL 1665 }; 1666 const char * const *events_tp; 1667 int ret; 1668 uint16_t e_machine = EM_HOST; 1669 1670 events_tp_size = 0; 1671 ret = setup_kvm_events_tp(kvm, e_machine); 1672 if (ret < 0) { 1673 pr_err("Unable to setup the kvm tracepoints\n"); 1674 return ret; 1675 } 1676 1677 for (events_tp = kvm_events_tp(e_machine); *events_tp; events_tp++) 1678 events_tp_size++; 1679 1680 rec_argc = ARRAY_SIZE(record_args) + argc + 2 + 1681 2 * events_tp_size; 1682 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1683 1684 if (rec_argv == NULL) 1685 return -ENOMEM; 1686 1687 for (i = 0; i < ARRAY_SIZE(record_args); i++) 1688 rec_argv[i] = record_args[i]; 1689 1690 for (j = 0; j < events_tp_size; j++) { 1691 rec_argv[i++] = "-e"; 1692 rec_argv[i++] = kvm_events_tp(e_machine)[j]; 1693 } 1694 1695 rec_argv[i++] = "-o"; 1696 rec_argv[i++] = kvm->file_name; 1697 1698 for (j = 1; j < (unsigned int)argc; j++, i++) 1699 rec_argv[i] = argv[j]; 1700 1701 set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN); 1702 set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN); 1703 set_option_flag(record_options, 'R', "raw-samples", PARSE_OPT_HIDDEN); 1704 1705 set_option_flag(record_options, 'F', "freq", PARSE_OPT_DISABLED); 1706 set_option_flag(record_options, 0, "group", PARSE_OPT_DISABLED); 1707 set_option_flag(record_options, 'g', NULL, PARSE_OPT_DISABLED); 1708 set_option_flag(record_options, 0, "call-graph", PARSE_OPT_DISABLED); 1709 set_option_flag(record_options, 'd', "data", PARSE_OPT_DISABLED); 1710 set_option_flag(record_options, 'T', "timestamp", PARSE_OPT_DISABLED); 1711 set_option_flag(record_options, 'P', "period", PARSE_OPT_DISABLED); 1712 set_option_flag(record_options, 'n', "no-samples", PARSE_OPT_DISABLED); 1713 set_option_flag(record_options, 'N', "no-buildid-cache", PARSE_OPT_DISABLED); 1714 set_option_flag(record_options, 'B', "no-buildid", PARSE_OPT_DISABLED); 1715 set_option_flag(record_options, 'G', "cgroup", PARSE_OPT_DISABLED); 1716 set_option_flag(record_options, 'b', "branch-any", PARSE_OPT_DISABLED); 1717 set_option_flag(record_options, 'j', "branch-filter", PARSE_OPT_DISABLED); 1718 set_option_flag(record_options, 'W', "weight", PARSE_OPT_DISABLED); 1719 set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED); 1720 1721 record_usage = kvm_stat_record_usage; 1722 ret = cmd_record(i, rec_argv); 1723 free(rec_argv); 1724 return ret; 1725 } 1726 1727 static int 1728 kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) 1729 { 1730 const struct option kvm_events_report_options[] = { 1731 OPT_STRING(0, "event", &kvm->report_event, "report event", 1732 "event for reporting: vmexit, " 1733 "mmio (x86 only), ioport (x86 only)"), 1734 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, 1735 "vcpu id to report"), 1736 OPT_STRING('k', "key", &kvm->sort_key, "sort-key", 1737 "key for sorting: sample(sort by samples number)" 1738 " time (sort by avg time)"), 1739 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid", 1740 "analyze events only for given process id(s)"), 1741 OPT_BOOLEAN('f', "force", &kvm->force, "don't complain, do it"), 1742 OPT_BOOLEAN(0, "stdio", &kvm->use_stdio, "use the stdio interface"), 1743 OPT_END() 1744 }; 1745 1746 const char * const kvm_events_report_usage[] = { 1747 "perf kvm stat report [<options>]", 1748 NULL 1749 }; 1750 1751 if (argc) { 1752 argc = parse_options(argc, argv, 1753 kvm_events_report_options, 1754 kvm_events_report_usage, 0); 1755 if (argc) 1756 usage_with_options(kvm_events_report_usage, 1757 kvm_events_report_options); 1758 } 1759 1760 #ifndef HAVE_SLANG_SUPPORT 1761 kvm->use_stdio = true; 1762 #endif 1763 1764 if (!kvm->opts.target.pid) 1765 kvm->opts.target.system_wide = true; 1766 1767 return kvm_events_report_vcpu(kvm); 1768 } 1769 1770 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1771 static struct evlist *kvm_live_event_list(void) 1772 { 1773 struct evlist *evlist; 1774 char *tp, *name, *sys; 1775 int err = -1; 1776 const char * const *events_tp; 1777 1778 evlist = evlist__new(); 1779 if (evlist == NULL) 1780 return NULL; 1781 1782 for (events_tp = kvm_events_tp(EM_HOST); *events_tp; events_tp++) { 1783 1784 tp = strdup(*events_tp); 1785 if (tp == NULL) 1786 goto out; 1787 1788 /* split tracepoint into subsystem and name */ 1789 sys = tp; 1790 name = strchr(tp, ':'); 1791 if (name == NULL) { 1792 pr_err("Error parsing %s tracepoint: subsystem delimiter not found\n", 1793 *events_tp); 1794 free(tp); 1795 goto out; 1796 } 1797 *name = '\0'; 1798 name++; 1799 1800 if (evlist__add_newtp(evlist, sys, name, NULL)) { 1801 pr_err("Failed to add %s tracepoint to the list\n", *events_tp); 1802 free(tp); 1803 goto out; 1804 } 1805 1806 free(tp); 1807 } 1808 1809 err = 0; 1810 1811 out: 1812 if (err) { 1813 evlist__put(evlist); 1814 evlist = NULL; 1815 } 1816 1817 return evlist; 1818 } 1819 1820 static int kvm_events_live(struct perf_kvm_stat *kvm, 1821 int argc, const char **argv) 1822 { 1823 char errbuf[BUFSIZ]; 1824 int err; 1825 1826 const struct option live_options[] = { 1827 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid", 1828 "record events on existing process id"), 1829 OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages", 1830 "number of mmap data pages", evlist__parse_mmap_pages), 1831 OPT_INCR('v', "verbose", &verbose, 1832 "be more verbose (show counter open errors, etc)"), 1833 OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide, 1834 "system-wide collection from all CPUs"), 1835 OPT_UINTEGER('d', "display", &kvm->display_time, 1836 "time in seconds between display updates"), 1837 OPT_STRING(0, "event", &kvm->report_event, "report event", 1838 "event for reporting: " 1839 "vmexit, mmio (x86 only), ioport (x86 only)"), 1840 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, 1841 "vcpu id to report"), 1842 OPT_STRING('k', "key", &kvm->sort_key, "sort-key", 1843 "key for sorting: sample(sort by samples number)" 1844 " time (sort by avg time)"), 1845 OPT_U64(0, "duration", &kvm->duration, 1846 "show events other than" 1847 " HLT (x86 only) or Wait state (s390 only)" 1848 " that take longer than duration usecs"), 1849 OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout, 1850 "per thread proc mmap processing timeout in ms"), 1851 OPT_END() 1852 }; 1853 const char * const live_usage[] = { 1854 "perf kvm stat live [<options>]", 1855 NULL 1856 }; 1857 struct perf_data data = { 1858 .mode = PERF_DATA_MODE_WRITE, 1859 }; 1860 1861 1862 /* event handling */ 1863 perf_tool__init(&kvm->tool, /*ordered_events=*/true); 1864 kvm->tool.sample = process_sample_event; 1865 kvm->tool.comm = perf_event__process_comm; 1866 kvm->tool.exit = perf_event__process_exit; 1867 kvm->tool.fork = perf_event__process_fork; 1868 kvm->tool.lost = process_lost_event; 1869 kvm->tool.namespaces = perf_event__process_namespaces; 1870 1871 /* set defaults */ 1872 kvm->display_time = 1; 1873 kvm->opts.user_interval = 1; 1874 kvm->opts.mmap_pages = 512; 1875 kvm->opts.target.uses_mmap = false; 1876 1877 symbol__init(NULL); 1878 disable_buildid_cache(); 1879 1880 use_browser = 0; 1881 1882 if (argc) { 1883 argc = parse_options(argc, argv, live_options, 1884 live_usage, 0); 1885 if (argc) 1886 usage_with_options(live_usage, live_options); 1887 } 1888 1889 kvm->duration *= NSEC_PER_USEC; /* convert usec to nsec */ 1890 1891 /* 1892 * target related setups 1893 */ 1894 err = target__validate(&kvm->opts.target); 1895 if (err) { 1896 target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ); 1897 ui__warning("%s", errbuf); 1898 } 1899 1900 if (target__none(&kvm->opts.target)) 1901 kvm->opts.target.system_wide = true; 1902 1903 1904 /* 1905 * generate the event list 1906 */ 1907 err = setup_kvm_events_tp(kvm, EM_HOST); 1908 if (err < 0) { 1909 pr_err("Unable to setup the kvm tracepoints\n"); 1910 return err; 1911 } 1912 1913 kvm->evlist = kvm_live_event_list(); 1914 if (kvm->evlist == NULL) { 1915 err = -1; 1916 goto out; 1917 } 1918 1919 if (evlist__create_maps(kvm->evlist, &kvm->opts.target) < 0) 1920 usage_with_options(live_usage, live_options); 1921 1922 /* 1923 * perf session 1924 */ 1925 kvm->session = perf_session__new(&data, &kvm->tool); 1926 if (IS_ERR(kvm->session)) { 1927 err = PTR_ERR(kvm->session); 1928 goto out; 1929 } 1930 kvm->session->evlist = kvm->evlist; 1931 perf_session__set_id_hdr_size(kvm->session); 1932 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); 1933 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, 1934 evlist__core(kvm->evlist)->threads, true, false, 1); 1935 err = kvm_live_open_events(kvm); 1936 if (err) 1937 goto out; 1938 1939 err = kvm_events_live_report(kvm); 1940 1941 out: 1942 perf_session__delete(kvm->session); 1943 kvm->session = NULL; 1944 evlist__put(kvm->evlist); 1945 1946 return err; 1947 } 1948 #endif 1949 1950 static void print_kvm_stat_usage(void) 1951 { 1952 printf("Usage: perf kvm stat <command>\n\n"); 1953 1954 printf("# Available commands:\n"); 1955 printf("\trecord: record kvm events\n"); 1956 printf("\treport: report statistical data of kvm events\n"); 1957 printf("\tlive: live reporting of statistical data of kvm events\n"); 1958 1959 printf("\nOtherwise, it is the alias of 'perf stat':\n"); 1960 } 1961 1962 static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) 1963 { 1964 struct perf_kvm_stat kvm = { 1965 .file_name = file_name, 1966 1967 .trace_vcpu = -1, 1968 .report_event = "vmexit", 1969 .sort_key = "sample", 1970 1971 }; 1972 1973 if (argc == 1) { 1974 print_kvm_stat_usage(); 1975 goto perf_stat; 1976 } 1977 1978 if (strlen(argv[1]) > 2 && strstarts("record", argv[1])) 1979 return kvm_events_record(&kvm, argc - 1, argv + 1); 1980 1981 if (strlen(argv[1]) > 2 && strstarts("report", argv[1])) 1982 return kvm_events_report(&kvm, argc - 1 , argv + 1); 1983 1984 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1985 if (!strncmp(argv[1], "live", 4)) 1986 return kvm_events_live(&kvm, argc - 1 , argv + 1); 1987 #endif 1988 1989 perf_stat: 1990 return cmd_stat(argc, argv); 1991 } 1992 #endif /* HAVE_LIBTRACEEVENT */ 1993 1994 static int __cmd_record(const char *file_name, int argc, const char **argv) 1995 { 1996 int rec_argc, i = 0, j, ret; 1997 const char **rec_argv; 1998 int need_arch_event = !!kvm_need_default_arch_event(EM_HOST, argc, argv); 1999 2000 /* 2001 * Besides the 2 more options "-o" and "filename", 2002 * kvm_add_default_arch_event() may add 2 extra options, 2003 * so allocate more items conditionally. 2004 */ 2005 rec_argc = argc + 2 + (2 * need_arch_event); 2006 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2007 if (!rec_argv) 2008 return -ENOMEM; 2009 2010 rec_argv[i++] = "record"; 2011 rec_argv[i++] = "-o"; 2012 rec_argv[i++] = file_name; 2013 if (need_arch_event) { 2014 ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); 2015 if (ret) 2016 goto EXIT; 2017 } 2018 2019 for (j = 1; j < argc; j++, i++) 2020 rec_argv[i] = argv[j]; 2021 2022 BUG_ON(i != rec_argc); 2023 2024 ret = cmd_record(i, rec_argv); 2025 2026 EXIT: 2027 free(rec_argv); 2028 return ret; 2029 } 2030 2031 static int __cmd_report(const char *file_name, int argc, const char **argv) 2032 { 2033 int rec_argc, i = 0, j, ret; 2034 const char **rec_argv; 2035 2036 rec_argc = argc + 2; 2037 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2038 if (!rec_argv) 2039 return -ENOMEM; 2040 2041 rec_argv[i++] = "report"; 2042 rec_argv[i++] = "-i"; 2043 rec_argv[i++] = file_name; 2044 for (j = 1; j < argc; j++, i++) 2045 rec_argv[i] = argv[j]; 2046 2047 BUG_ON(i != rec_argc); 2048 2049 ret = cmd_report(i, rec_argv); 2050 free(rec_argv); 2051 return ret; 2052 } 2053 2054 static int 2055 __cmd_buildid_list(const char *file_name, int argc, const char **argv) 2056 { 2057 int rec_argc, i = 0, j, ret; 2058 const char **rec_argv; 2059 2060 rec_argc = argc + 2; 2061 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2062 if (!rec_argv) 2063 return -ENOMEM; 2064 2065 rec_argv[i++] = "buildid-list"; 2066 rec_argv[i++] = "-i"; 2067 rec_argv[i++] = file_name; 2068 for (j = 1; j < argc; j++, i++) 2069 rec_argv[i] = argv[j]; 2070 2071 BUG_ON(i != rec_argc); 2072 2073 ret = cmd_buildid_list(i, rec_argv); 2074 free(rec_argv); 2075 return ret; 2076 } 2077 2078 static int __cmd_top(int argc, const char **argv) 2079 { 2080 int rec_argc, i = 0, ret; 2081 const char **rec_argv; 2082 2083 /* 2084 * kvm_add_default_arch_event() may add 2 extra options, so 2085 * allocate 2 more pointers in adavance. 2086 */ 2087 rec_argc = argc + 2; 2088 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2089 if (!rec_argv) 2090 return -ENOMEM; 2091 2092 for (i = 0; i < argc; i++) 2093 rec_argv[i] = argv[i]; 2094 2095 BUG_ON(i != argc); 2096 2097 if (kvm_need_default_arch_event(EM_HOST, argc, argv)) { 2098 ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); 2099 if (ret) 2100 goto EXIT; 2101 } 2102 2103 ret = cmd_top(i, rec_argv); 2104 2105 EXIT: 2106 free(rec_argv); 2107 return ret; 2108 } 2109 2110 int cmd_kvm(int argc, const char **argv) 2111 { 2112 const char *file_name = NULL; 2113 const struct option kvm_options[] = { 2114 OPT_STRING('i', "input", &file_name, "file", 2115 "Input file name"), 2116 OPT_STRING('o', "output", &file_name, "file", 2117 "Output file name"), 2118 OPT_BOOLEAN(0, "guest", &perf_guest, 2119 "Collect guest os data"), 2120 OPT_BOOLEAN(0, "host", &perf_host, 2121 "Collect host os data"), 2122 OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory", 2123 "guest mount directory under which every guest os" 2124 " instance has a subdir"), 2125 OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name, 2126 "file", "file saving guest os vmlinux"), 2127 OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms, 2128 "file", "file saving guest os /proc/kallsyms"), 2129 OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, 2130 "file", "file saving guest os /proc/modules"), 2131 OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code, 2132 "Guest code can be found in hypervisor process"), 2133 OPT_INCR('v', "verbose", &verbose, 2134 "be more verbose (show counter open errors, etc)"), 2135 OPT_END() 2136 }; 2137 2138 const char *const kvm_subcommands[] = { "top", "record", "report", "diff", 2139 "buildid-list", "stat", NULL }; 2140 const char *kvm_usage[] = { NULL, NULL }; 2141 int ret; 2142 2143 exclude_GH_default = true; 2144 perf_host = 0; 2145 perf_guest = 1; 2146 2147 argc = parse_options_subcommand(argc, argv, kvm_options, kvm_subcommands, kvm_usage, 2148 PARSE_OPT_STOP_AT_NON_OPTION); 2149 if (!argc) 2150 usage_with_options(kvm_usage, kvm_options); 2151 2152 thread__set_priv_destructor(free); 2153 2154 if (!perf_host) 2155 perf_guest = 1; 2156 2157 if (!file_name) 2158 file_name = get_filename_for_perf_kvm(); 2159 2160 if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) 2161 ret = __cmd_record(file_name, argc, argv); 2162 else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) 2163 ret = __cmd_report(file_name, argc, argv); 2164 else if (strlen(argv[0]) > 2 && strstarts("diff", argv[0])) 2165 ret = cmd_diff(argc, argv); 2166 else if (!strcmp(argv[0], "top")) 2167 ret = __cmd_top(argc, argv); 2168 else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) 2169 ret = __cmd_buildid_list(file_name, argc, argv); 2170 #if defined(HAVE_LIBTRACEEVENT) 2171 else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) 2172 ret = kvm_cmd_stat(file_name, argc, argv); 2173 #endif 2174 else 2175 usage_with_options(kvm_usage, kvm_options); 2176 2177 /* free usage string allocated by parse_options_subcommand */ 2178 free((void *)kvm_usage[0]); 2179 2180 return ret; 2181 } 2182