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 return -1; 1157 } 1158 1159 if (!handle_kvm_event(kvm, thread, sample)) 1160 err = -1; 1161 1162 thread__put(thread); 1163 return err; 1164 } 1165 1166 static int cpu_isa_config(struct perf_kvm_stat *kvm) 1167 { 1168 char buf[128], *cpuid; 1169 int err; 1170 uint16_t e_machine; 1171 1172 if (kvm->live) { 1173 struct perf_cpu cpu = {-1}; 1174 1175 err = get_cpuid(buf, sizeof(buf), cpu); 1176 if (err != 0) { 1177 pr_err("Failed to look up CPU type: %s\n", 1178 str_error_r(err, buf, sizeof(buf))); 1179 return -err; 1180 } 1181 cpuid = buf; 1182 } else 1183 cpuid = perf_session__env(kvm->session)->cpuid; 1184 1185 if (!cpuid) { 1186 pr_err("Failed to look up CPU type\n"); 1187 return -EINVAL; 1188 } 1189 1190 e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); 1191 err = cpu_isa_init(kvm, e_machine, cpuid); 1192 if (err == -ENOTSUP) 1193 pr_err("CPU %s is not supported.\n", cpuid); 1194 1195 return err; 1196 } 1197 1198 static bool verify_vcpu(int vcpu) 1199 { 1200 if (vcpu != -1 && vcpu < 0) { 1201 pr_err("Invalid vcpu:%d.\n", vcpu); 1202 return false; 1203 } 1204 1205 return true; 1206 } 1207 1208 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1209 /* keeping the max events to a modest level to keep 1210 * the processing of samples per mmap smooth. 1211 */ 1212 #define PERF_KVM__MAX_EVENTS_PER_MMAP 25 1213 1214 static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx, 1215 u64 *mmap_time) 1216 { 1217 struct evlist *evlist = kvm->evlist; 1218 union perf_event *event; 1219 struct mmap *md; 1220 u64 timestamp; 1221 s64 n = 0; 1222 int err; 1223 1224 *mmap_time = ULLONG_MAX; 1225 md = &evlist__mmap(evlist)[idx]; 1226 err = perf_mmap__read_init(&md->core); 1227 if (err < 0) 1228 return (err == -EAGAIN) ? 0 : -1; 1229 1230 while ((event = perf_mmap__read_event(&md->core)) != NULL) { 1231 err = evlist__parse_sample_timestamp(evlist, event, ×tamp); 1232 if (err) { 1233 perf_mmap__consume(&md->core); 1234 pr_err("Failed to parse sample\n"); 1235 return -1; 1236 } 1237 1238 err = perf_session__queue_event(kvm->session, event, timestamp, 0, NULL); 1239 /* 1240 * FIXME: Here we can't consume the event, as perf_session__queue_event will 1241 * point to it, and it'll get possibly overwritten by the kernel. 1242 */ 1243 perf_mmap__consume(&md->core); 1244 1245 if (err) { 1246 pr_err("Failed to enqueue sample: %d\n", err); 1247 return -1; 1248 } 1249 1250 /* save time stamp of our first sample for this mmap */ 1251 if (n == 0) 1252 *mmap_time = timestamp; 1253 1254 /* limit events per mmap handled all at once */ 1255 n++; 1256 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP) 1257 break; 1258 } 1259 1260 perf_mmap__read_done(&md->core); 1261 return n; 1262 } 1263 1264 static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm) 1265 { 1266 int i, err, throttled = 0; 1267 s64 n, ntotal = 0; 1268 u64 flush_time = ULLONG_MAX, mmap_time; 1269 1270 for (i = 0; i < evlist__core(kvm->evlist)->nr_mmaps; i++) { 1271 n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time); 1272 if (n < 0) 1273 return -1; 1274 1275 /* flush time is going to be the minimum of all the individual 1276 * mmap times. Essentially, we flush all the samples queued up 1277 * from the last pass under our minimal start time -- that leaves 1278 * a very small race for samples to come in with a lower timestamp. 1279 * The ioctl to return the perf_clock timestamp should close the 1280 * race entirely. 1281 */ 1282 if (mmap_time < flush_time) 1283 flush_time = mmap_time; 1284 1285 ntotal += n; 1286 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP) 1287 throttled = 1; 1288 } 1289 1290 /* flush queue after each round in which we processed events */ 1291 if (ntotal) { 1292 struct ordered_events *oe = &kvm->session->ordered_events; 1293 1294 oe->next_flush = flush_time; 1295 err = ordered_events__flush(oe, OE_FLUSH__ROUND); 1296 if (err) { 1297 if (kvm->lost_events) 1298 pr_info("\nLost events: %" PRIu64 "\n\n", 1299 kvm->lost_events); 1300 return err; 1301 } 1302 } 1303 1304 return throttled; 1305 } 1306 1307 static volatile int done; 1308 1309 static void sig_handler(int sig __maybe_unused) 1310 { 1311 done = 1; 1312 } 1313 1314 static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm) 1315 { 1316 struct itimerspec new_value; 1317 int rc = -1; 1318 1319 kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); 1320 if (kvm->timerfd < 0) { 1321 pr_err("timerfd_create failed\n"); 1322 goto out; 1323 } 1324 1325 new_value.it_value.tv_sec = kvm->display_time; 1326 new_value.it_value.tv_nsec = 0; 1327 new_value.it_interval.tv_sec = kvm->display_time; 1328 new_value.it_interval.tv_nsec = 0; 1329 1330 if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) { 1331 pr_err("timerfd_settime failed: %d\n", errno); 1332 close(kvm->timerfd); 1333 goto out; 1334 } 1335 1336 rc = 0; 1337 out: 1338 return rc; 1339 } 1340 1341 static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm) 1342 { 1343 uint64_t c; 1344 int rc; 1345 1346 rc = read(kvm->timerfd, &c, sizeof(uint64_t)); 1347 if (rc < 0) { 1348 if (errno == EAGAIN) 1349 return 0; 1350 1351 pr_err("Failed to read timer fd: %d\n", errno); 1352 return -1; 1353 } 1354 1355 if (rc != sizeof(uint64_t)) { 1356 pr_err("Error reading timer fd - invalid size returned\n"); 1357 return -1; 1358 } 1359 1360 if (c != 1) 1361 pr_debug("Missed timer beats: %" PRIu64 "\n", c-1); 1362 1363 /* update display */ 1364 sort_result(kvm); 1365 print_result(kvm); 1366 1367 /* Reset sort list to "ev_name" */ 1368 kvm_hists__reinit(NULL, "ev_name"); 1369 1370 /* reset counts */ 1371 clear_events_cache_stats(); 1372 kvm->total_count = 0; 1373 kvm->total_time = 0; 1374 kvm->lost_events = 0; 1375 1376 return 0; 1377 } 1378 1379 static int fd_set_nonblock(int fd) 1380 { 1381 long arg = 0; 1382 1383 arg = fcntl(fd, F_GETFL); 1384 if (arg < 0) { 1385 pr_err("Failed to get current flags for fd %d\n", fd); 1386 return -1; 1387 } 1388 1389 if (fcntl(fd, F_SETFL, arg | O_NONBLOCK) < 0) { 1390 pr_err("Failed to set non-block option on fd %d\n", fd); 1391 return -1; 1392 } 1393 1394 return 0; 1395 } 1396 1397 static int perf_kvm__handle_stdin(void) 1398 { 1399 int c; 1400 1401 c = getc(stdin); 1402 if (c == 'q') 1403 return 1; 1404 1405 return 0; 1406 } 1407 1408 static int kvm_events_live_report(struct perf_kvm_stat *kvm) 1409 { 1410 int nr_stdin, ret, err = -EINVAL; 1411 struct termios save; 1412 1413 /* live flag must be set first */ 1414 kvm->live = true; 1415 1416 ret = cpu_isa_config(kvm); 1417 if (ret < 0) 1418 return ret; 1419 1420 if (!verify_vcpu(kvm->trace_vcpu) || 1421 !is_valid_key(kvm) || 1422 !register_kvm_events_ops(kvm, EM_HOST)) { 1423 goto out; 1424 } 1425 1426 set_term_quiet_input(&save); 1427 1428 kvm_hists__init(); 1429 1430 signal(SIGINT, sig_handler); 1431 signal(SIGTERM, sig_handler); 1432 1433 /* add timer fd */ 1434 if (perf_kvm__timerfd_create(kvm) < 0) { 1435 err = -1; 1436 goto out; 1437 } 1438 1439 if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0) 1440 goto out; 1441 1442 nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin)); 1443 if (nr_stdin < 0) 1444 goto out; 1445 1446 if (fd_set_nonblock(fileno(stdin)) != 0) 1447 goto out; 1448 1449 /* everything is good - enable the events and process */ 1450 evlist__enable(kvm->evlist); 1451 1452 while (!done) { 1453 struct fdarray *fda = &evlist__core(kvm->evlist)->pollfd; 1454 int rc; 1455 1456 rc = perf_kvm__mmap_read(kvm); 1457 if (rc < 0) 1458 break; 1459 1460 err = perf_kvm__handle_timerfd(kvm); 1461 if (err) 1462 goto out; 1463 1464 if (fda->entries[nr_stdin].revents & POLLIN) 1465 done = perf_kvm__handle_stdin(); 1466 1467 if (!rc && !done) 1468 err = evlist__poll(kvm->evlist, 100); 1469 } 1470 1471 evlist__disable(kvm->evlist); 1472 1473 if (err == 0) { 1474 sort_result(kvm); 1475 print_result(kvm); 1476 } 1477 1478 out: 1479 hists__delete_entries(&kvm_hists.hists); 1480 1481 if (kvm->timerfd >= 0) 1482 close(kvm->timerfd); 1483 1484 tcsetattr(0, TCSAFLUSH, &save); 1485 return err; 1486 } 1487 1488 static int kvm_live_open_events(struct perf_kvm_stat *kvm) 1489 { 1490 int err, rc = -1; 1491 struct evsel *pos; 1492 struct evlist *evlist = kvm->evlist; 1493 char sbuf[STRERR_BUFSIZE]; 1494 1495 evlist__config(evlist, &kvm->opts, NULL); 1496 1497 /* 1498 * Note: exclude_{guest,host} do not apply here. 1499 * This command processes KVM tracepoints from host only 1500 */ 1501 evlist__for_each_entry(evlist, pos) { 1502 struct perf_event_attr *attr = &pos->core.attr; 1503 1504 /* make sure these *are* set */ 1505 evsel__set_sample_bit(pos, TID); 1506 evsel__set_sample_bit(pos, TIME); 1507 evsel__set_sample_bit(pos, CPU); 1508 evsel__set_sample_bit(pos, RAW); 1509 /* make sure these are *not*; want as small a sample as possible */ 1510 evsel__reset_sample_bit(pos, PERIOD); 1511 evsel__reset_sample_bit(pos, IP); 1512 evsel__reset_sample_bit(pos, CALLCHAIN); 1513 evsel__reset_sample_bit(pos, ADDR); 1514 evsel__reset_sample_bit(pos, READ); 1515 attr->mmap = 0; 1516 attr->comm = 0; 1517 attr->task = 0; 1518 1519 attr->sample_period = 1; 1520 1521 attr->watermark = 0; 1522 attr->wakeup_events = 1000; 1523 1524 /* will enable all once we are ready */ 1525 attr->disabled = 1; 1526 } 1527 1528 err = evlist__open(evlist); 1529 if (err < 0) { 1530 printf("Couldn't create the events: %s\n", 1531 str_error_r(errno, sbuf, sizeof(sbuf))); 1532 goto out; 1533 } 1534 1535 if (evlist__do_mmap(evlist, kvm->opts.mmap_pages) < 0) { 1536 ui__error("Failed to mmap the events: %s\n", 1537 str_error_r(errno, sbuf, sizeof(sbuf))); 1538 evlist__close(evlist); 1539 goto out; 1540 } 1541 1542 rc = 0; 1543 1544 out: 1545 return rc; 1546 } 1547 #endif 1548 1549 static int read_events(struct perf_kvm_stat *kvm) 1550 { 1551 int ret; 1552 uint16_t e_machine; 1553 struct perf_data file = { 1554 .path = kvm->file_name, 1555 .mode = PERF_DATA_MODE_READ, 1556 .force = kvm->force, 1557 }; 1558 1559 perf_tool__init(&kvm->tool, /*ordered_events=*/true); 1560 kvm->tool.sample = process_sample_event; 1561 kvm->tool.comm = perf_event__process_comm; 1562 kvm->tool.namespaces = perf_event__process_namespaces; 1563 1564 kvm->session = perf_session__new(&file, &kvm->tool); 1565 if (IS_ERR(kvm->session)) { 1566 pr_err("Initializing perf session failed\n"); 1567 return PTR_ERR(kvm->session); 1568 } 1569 1570 symbol__init(perf_session__env(kvm->session)); 1571 1572 if (!perf_session__has_traces(kvm->session, "kvm record")) { 1573 ret = -EINVAL; 1574 goto out_delete; 1575 } 1576 1577 e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); 1578 if (!register_kvm_events_ops(kvm, e_machine)) { 1579 ret = -EINVAL; 1580 goto out_delete; 1581 } 1582 1583 /* 1584 * Do not use 'isa' recorded in kvm_exit tracepoint since it is not 1585 * traced in the old kernel. 1586 */ 1587 ret = cpu_isa_config(kvm); 1588 if (ret < 0) 1589 goto out_delete; 1590 1591 ret = perf_session__process_events(kvm->session); 1592 1593 out_delete: 1594 perf_session__delete(kvm->session); 1595 return ret; 1596 } 1597 1598 static int parse_target_str(struct perf_kvm_stat *kvm) 1599 { 1600 if (kvm->opts.target.pid) { 1601 kvm->pid_list = intlist__new(kvm->opts.target.pid); 1602 if (kvm->pid_list == NULL) { 1603 pr_err("Error parsing process id string\n"); 1604 return -EINVAL; 1605 } 1606 } 1607 1608 return 0; 1609 } 1610 1611 static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm) 1612 { 1613 int ret = -EINVAL; 1614 int vcpu = kvm->trace_vcpu; 1615 1616 if (parse_target_str(kvm) != 0) 1617 goto exit; 1618 1619 if (!verify_vcpu(vcpu)) 1620 goto exit; 1621 1622 if (!is_valid_key(kvm)) 1623 goto exit; 1624 1625 if (kvm->use_stdio) { 1626 use_browser = 0; 1627 setup_pager(); 1628 } else { 1629 use_browser = 1; 1630 } 1631 1632 setup_browser(false); 1633 1634 kvm_hists__init(); 1635 1636 ret = read_events(kvm); 1637 if (ret) 1638 goto exit; 1639 1640 sort_result(kvm); 1641 kvm_display(kvm); 1642 1643 exit: 1644 hists__delete_entries(&kvm_hists.hists); 1645 return ret; 1646 } 1647 1648 static int 1649 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) 1650 { 1651 unsigned int rec_argc, i, j, events_tp_size; 1652 const char **rec_argv; 1653 const char * const record_args[] = { 1654 "record", 1655 "-R", 1656 "-m", "1024", 1657 "-c", "1", 1658 }; 1659 const char * const kvm_stat_record_usage[] = { 1660 "perf kvm stat record [<options>]", 1661 NULL 1662 }; 1663 const char * const *events_tp; 1664 int ret; 1665 uint16_t e_machine = EM_HOST; 1666 1667 events_tp_size = 0; 1668 ret = setup_kvm_events_tp(kvm, e_machine); 1669 if (ret < 0) { 1670 pr_err("Unable to setup the kvm tracepoints\n"); 1671 return ret; 1672 } 1673 1674 for (events_tp = kvm_events_tp(e_machine); *events_tp; events_tp++) 1675 events_tp_size++; 1676 1677 rec_argc = ARRAY_SIZE(record_args) + argc + 2 + 1678 2 * events_tp_size; 1679 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1680 1681 if (rec_argv == NULL) 1682 return -ENOMEM; 1683 1684 for (i = 0; i < ARRAY_SIZE(record_args); i++) 1685 rec_argv[i] = record_args[i]; 1686 1687 for (j = 0; j < events_tp_size; j++) { 1688 rec_argv[i++] = "-e"; 1689 rec_argv[i++] = kvm_events_tp(e_machine)[j]; 1690 } 1691 1692 rec_argv[i++] = "-o"; 1693 rec_argv[i++] = kvm->file_name; 1694 1695 for (j = 1; j < (unsigned int)argc; j++, i++) 1696 rec_argv[i] = argv[j]; 1697 1698 set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN); 1699 set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN); 1700 set_option_flag(record_options, 'R', "raw-samples", PARSE_OPT_HIDDEN); 1701 1702 set_option_flag(record_options, 'F', "freq", PARSE_OPT_DISABLED); 1703 set_option_flag(record_options, 0, "group", PARSE_OPT_DISABLED); 1704 set_option_flag(record_options, 'g', NULL, PARSE_OPT_DISABLED); 1705 set_option_flag(record_options, 0, "call-graph", PARSE_OPT_DISABLED); 1706 set_option_flag(record_options, 'd', "data", PARSE_OPT_DISABLED); 1707 set_option_flag(record_options, 'T', "timestamp", PARSE_OPT_DISABLED); 1708 set_option_flag(record_options, 'P', "period", PARSE_OPT_DISABLED); 1709 set_option_flag(record_options, 'n', "no-samples", PARSE_OPT_DISABLED); 1710 set_option_flag(record_options, 'N', "no-buildid-cache", PARSE_OPT_DISABLED); 1711 set_option_flag(record_options, 'B', "no-buildid", PARSE_OPT_DISABLED); 1712 set_option_flag(record_options, 'G', "cgroup", PARSE_OPT_DISABLED); 1713 set_option_flag(record_options, 'b', "branch-any", PARSE_OPT_DISABLED); 1714 set_option_flag(record_options, 'j', "branch-filter", PARSE_OPT_DISABLED); 1715 set_option_flag(record_options, 'W', "weight", PARSE_OPT_DISABLED); 1716 set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED); 1717 1718 record_usage = kvm_stat_record_usage; 1719 ret = cmd_record(i, rec_argv); 1720 free(rec_argv); 1721 return ret; 1722 } 1723 1724 static int 1725 kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) 1726 { 1727 const struct option kvm_events_report_options[] = { 1728 OPT_STRING(0, "event", &kvm->report_event, "report event", 1729 "event for reporting: vmexit, " 1730 "mmio (x86 only), ioport (x86 only)"), 1731 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, 1732 "vcpu id to report"), 1733 OPT_STRING('k', "key", &kvm->sort_key, "sort-key", 1734 "key for sorting: sample(sort by samples number)" 1735 " time (sort by avg time)"), 1736 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid", 1737 "analyze events only for given process id(s)"), 1738 OPT_BOOLEAN('f', "force", &kvm->force, "don't complain, do it"), 1739 OPT_BOOLEAN(0, "stdio", &kvm->use_stdio, "use the stdio interface"), 1740 OPT_END() 1741 }; 1742 1743 const char * const kvm_events_report_usage[] = { 1744 "perf kvm stat report [<options>]", 1745 NULL 1746 }; 1747 1748 if (argc) { 1749 argc = parse_options(argc, argv, 1750 kvm_events_report_options, 1751 kvm_events_report_usage, 0); 1752 if (argc) 1753 usage_with_options(kvm_events_report_usage, 1754 kvm_events_report_options); 1755 } 1756 1757 #ifndef HAVE_SLANG_SUPPORT 1758 kvm->use_stdio = true; 1759 #endif 1760 1761 if (!kvm->opts.target.pid) 1762 kvm->opts.target.system_wide = true; 1763 1764 return kvm_events_report_vcpu(kvm); 1765 } 1766 1767 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1768 static struct evlist *kvm_live_event_list(void) 1769 { 1770 struct evlist *evlist; 1771 char *tp, *name, *sys; 1772 int err = -1; 1773 const char * const *events_tp; 1774 1775 evlist = evlist__new(); 1776 if (evlist == NULL) 1777 return NULL; 1778 1779 for (events_tp = kvm_events_tp(EM_HOST); *events_tp; events_tp++) { 1780 1781 tp = strdup(*events_tp); 1782 if (tp == NULL) 1783 goto out; 1784 1785 /* split tracepoint into subsystem and name */ 1786 sys = tp; 1787 name = strchr(tp, ':'); 1788 if (name == NULL) { 1789 pr_err("Error parsing %s tracepoint: subsystem delimiter not found\n", 1790 *events_tp); 1791 free(tp); 1792 goto out; 1793 } 1794 *name = '\0'; 1795 name++; 1796 1797 if (evlist__add_newtp(evlist, sys, name, NULL)) { 1798 pr_err("Failed to add %s tracepoint to the list\n", *events_tp); 1799 free(tp); 1800 goto out; 1801 } 1802 1803 free(tp); 1804 } 1805 1806 err = 0; 1807 1808 out: 1809 if (err) { 1810 evlist__put(evlist); 1811 evlist = NULL; 1812 } 1813 1814 return evlist; 1815 } 1816 1817 static int kvm_events_live(struct perf_kvm_stat *kvm, 1818 int argc, const char **argv) 1819 { 1820 char errbuf[BUFSIZ]; 1821 int err; 1822 1823 const struct option live_options[] = { 1824 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid", 1825 "record events on existing process id"), 1826 OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages", 1827 "number of mmap data pages", evlist__parse_mmap_pages), 1828 OPT_INCR('v', "verbose", &verbose, 1829 "be more verbose (show counter open errors, etc)"), 1830 OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide, 1831 "system-wide collection from all CPUs"), 1832 OPT_UINTEGER('d', "display", &kvm->display_time, 1833 "time in seconds between display updates"), 1834 OPT_STRING(0, "event", &kvm->report_event, "report event", 1835 "event for reporting: " 1836 "vmexit, mmio (x86 only), ioport (x86 only)"), 1837 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, 1838 "vcpu id to report"), 1839 OPT_STRING('k', "key", &kvm->sort_key, "sort-key", 1840 "key for sorting: sample(sort by samples number)" 1841 " time (sort by avg time)"), 1842 OPT_U64(0, "duration", &kvm->duration, 1843 "show events other than" 1844 " HLT (x86 only) or Wait state (s390 only)" 1845 " that take longer than duration usecs"), 1846 OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout, 1847 "per thread proc mmap processing timeout in ms"), 1848 OPT_END() 1849 }; 1850 const char * const live_usage[] = { 1851 "perf kvm stat live [<options>]", 1852 NULL 1853 }; 1854 struct perf_data data = { 1855 .mode = PERF_DATA_MODE_WRITE, 1856 }; 1857 1858 1859 /* event handling */ 1860 perf_tool__init(&kvm->tool, /*ordered_events=*/true); 1861 kvm->tool.sample = process_sample_event; 1862 kvm->tool.comm = perf_event__process_comm; 1863 kvm->tool.exit = perf_event__process_exit; 1864 kvm->tool.fork = perf_event__process_fork; 1865 kvm->tool.lost = process_lost_event; 1866 kvm->tool.namespaces = perf_event__process_namespaces; 1867 1868 /* set defaults */ 1869 kvm->display_time = 1; 1870 kvm->opts.user_interval = 1; 1871 kvm->opts.mmap_pages = 512; 1872 kvm->opts.target.uses_mmap = false; 1873 1874 symbol__init(NULL); 1875 disable_buildid_cache(); 1876 1877 use_browser = 0; 1878 1879 if (argc) { 1880 argc = parse_options(argc, argv, live_options, 1881 live_usage, 0); 1882 if (argc) 1883 usage_with_options(live_usage, live_options); 1884 } 1885 1886 kvm->duration *= NSEC_PER_USEC; /* convert usec to nsec */ 1887 1888 /* 1889 * target related setups 1890 */ 1891 err = target__validate(&kvm->opts.target); 1892 if (err) { 1893 target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ); 1894 ui__warning("%s", errbuf); 1895 } 1896 1897 if (target__none(&kvm->opts.target)) 1898 kvm->opts.target.system_wide = true; 1899 1900 1901 /* 1902 * generate the event list 1903 */ 1904 err = setup_kvm_events_tp(kvm, EM_HOST); 1905 if (err < 0) { 1906 pr_err("Unable to setup the kvm tracepoints\n"); 1907 return err; 1908 } 1909 1910 kvm->evlist = kvm_live_event_list(); 1911 if (kvm->evlist == NULL) { 1912 err = -1; 1913 goto out; 1914 } 1915 1916 if (evlist__create_maps(kvm->evlist, &kvm->opts.target) < 0) 1917 usage_with_options(live_usage, live_options); 1918 1919 /* 1920 * perf session 1921 */ 1922 kvm->session = perf_session__new(&data, &kvm->tool); 1923 if (IS_ERR(kvm->session)) { 1924 err = PTR_ERR(kvm->session); 1925 goto out; 1926 } 1927 kvm->session->evlist = kvm->evlist; 1928 perf_session__set_id_hdr_size(kvm->session); 1929 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); 1930 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, 1931 evlist__core(kvm->evlist)->threads, true, false, 1); 1932 err = kvm_live_open_events(kvm); 1933 if (err) 1934 goto out; 1935 1936 err = kvm_events_live_report(kvm); 1937 1938 out: 1939 perf_session__delete(kvm->session); 1940 kvm->session = NULL; 1941 evlist__put(kvm->evlist); 1942 1943 return err; 1944 } 1945 #endif 1946 1947 static void print_kvm_stat_usage(void) 1948 { 1949 printf("Usage: perf kvm stat <command>\n\n"); 1950 1951 printf("# Available commands:\n"); 1952 printf("\trecord: record kvm events\n"); 1953 printf("\treport: report statistical data of kvm events\n"); 1954 printf("\tlive: live reporting of statistical data of kvm events\n"); 1955 1956 printf("\nOtherwise, it is the alias of 'perf stat':\n"); 1957 } 1958 1959 static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) 1960 { 1961 struct perf_kvm_stat kvm = { 1962 .file_name = file_name, 1963 1964 .trace_vcpu = -1, 1965 .report_event = "vmexit", 1966 .sort_key = "sample", 1967 1968 }; 1969 1970 if (argc == 1) { 1971 print_kvm_stat_usage(); 1972 goto perf_stat; 1973 } 1974 1975 if (strlen(argv[1]) > 2 && strstarts("record", argv[1])) 1976 return kvm_events_record(&kvm, argc - 1, argv + 1); 1977 1978 if (strlen(argv[1]) > 2 && strstarts("report", argv[1])) 1979 return kvm_events_report(&kvm, argc - 1 , argv + 1); 1980 1981 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1982 if (!strncmp(argv[1], "live", 4)) 1983 return kvm_events_live(&kvm, argc - 1 , argv + 1); 1984 #endif 1985 1986 perf_stat: 1987 return cmd_stat(argc, argv); 1988 } 1989 #endif /* HAVE_LIBTRACEEVENT */ 1990 1991 static int __cmd_record(const char *file_name, int argc, const char **argv) 1992 { 1993 int rec_argc, i = 0, j, ret; 1994 const char **rec_argv; 1995 int need_arch_event = !!kvm_need_default_arch_event(EM_HOST, argc, argv); 1996 1997 /* 1998 * Besides the 2 more options "-o" and "filename", 1999 * kvm_add_default_arch_event() may add 2 extra options, 2000 * so allocate more items conditionally. 2001 */ 2002 rec_argc = argc + 2 + (2 * need_arch_event); 2003 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2004 if (!rec_argv) 2005 return -ENOMEM; 2006 2007 rec_argv[i++] = "record"; 2008 rec_argv[i++] = "-o"; 2009 rec_argv[i++] = file_name; 2010 if (need_arch_event) { 2011 ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); 2012 if (ret) 2013 goto EXIT; 2014 } 2015 2016 for (j = 1; j < argc; j++, i++) 2017 rec_argv[i] = argv[j]; 2018 2019 BUG_ON(i != rec_argc); 2020 2021 ret = cmd_record(i, rec_argv); 2022 2023 EXIT: 2024 free(rec_argv); 2025 return ret; 2026 } 2027 2028 static int __cmd_report(const char *file_name, int argc, const char **argv) 2029 { 2030 int rec_argc, i = 0, j, ret; 2031 const char **rec_argv; 2032 2033 rec_argc = argc + 2; 2034 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2035 if (!rec_argv) 2036 return -ENOMEM; 2037 2038 rec_argv[i++] = "report"; 2039 rec_argv[i++] = "-i"; 2040 rec_argv[i++] = file_name; 2041 for (j = 1; j < argc; j++, i++) 2042 rec_argv[i] = argv[j]; 2043 2044 BUG_ON(i != rec_argc); 2045 2046 ret = cmd_report(i, rec_argv); 2047 free(rec_argv); 2048 return ret; 2049 } 2050 2051 static int 2052 __cmd_buildid_list(const char *file_name, int argc, const char **argv) 2053 { 2054 int rec_argc, i = 0, j, ret; 2055 const char **rec_argv; 2056 2057 rec_argc = argc + 2; 2058 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2059 if (!rec_argv) 2060 return -ENOMEM; 2061 2062 rec_argv[i++] = "buildid-list"; 2063 rec_argv[i++] = "-i"; 2064 rec_argv[i++] = file_name; 2065 for (j = 1; j < argc; j++, i++) 2066 rec_argv[i] = argv[j]; 2067 2068 BUG_ON(i != rec_argc); 2069 2070 ret = cmd_buildid_list(i, rec_argv); 2071 free(rec_argv); 2072 return ret; 2073 } 2074 2075 static int __cmd_top(int argc, const char **argv) 2076 { 2077 int rec_argc, i = 0, ret; 2078 const char **rec_argv; 2079 2080 /* 2081 * kvm_add_default_arch_event() may add 2 extra options, so 2082 * allocate 2 more pointers in adavance. 2083 */ 2084 rec_argc = argc + 2; 2085 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2086 if (!rec_argv) 2087 return -ENOMEM; 2088 2089 for (i = 0; i < argc; i++) 2090 rec_argv[i] = argv[i]; 2091 2092 BUG_ON(i != argc); 2093 2094 if (kvm_need_default_arch_event(EM_HOST, argc, argv)) { 2095 ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); 2096 if (ret) 2097 goto EXIT; 2098 } 2099 2100 ret = cmd_top(i, rec_argv); 2101 2102 EXIT: 2103 free(rec_argv); 2104 return ret; 2105 } 2106 2107 int cmd_kvm(int argc, const char **argv) 2108 { 2109 const char *file_name = NULL; 2110 const struct option kvm_options[] = { 2111 OPT_STRING('i', "input", &file_name, "file", 2112 "Input file name"), 2113 OPT_STRING('o', "output", &file_name, "file", 2114 "Output file name"), 2115 OPT_BOOLEAN(0, "guest", &perf_guest, 2116 "Collect guest os data"), 2117 OPT_BOOLEAN(0, "host", &perf_host, 2118 "Collect host os data"), 2119 OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory", 2120 "guest mount directory under which every guest os" 2121 " instance has a subdir"), 2122 OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name, 2123 "file", "file saving guest os vmlinux"), 2124 OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms, 2125 "file", "file saving guest os /proc/kallsyms"), 2126 OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, 2127 "file", "file saving guest os /proc/modules"), 2128 OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code, 2129 "Guest code can be found in hypervisor process"), 2130 OPT_INCR('v', "verbose", &verbose, 2131 "be more verbose (show counter open errors, etc)"), 2132 OPT_END() 2133 }; 2134 2135 const char *const kvm_subcommands[] = { "top", "record", "report", "diff", 2136 "buildid-list", "stat", NULL }; 2137 const char *kvm_usage[] = { NULL, NULL }; 2138 int ret; 2139 2140 exclude_GH_default = true; 2141 perf_host = 0; 2142 perf_guest = 1; 2143 2144 argc = parse_options_subcommand(argc, argv, kvm_options, kvm_subcommands, kvm_usage, 2145 PARSE_OPT_STOP_AT_NON_OPTION); 2146 if (!argc) 2147 usage_with_options(kvm_usage, kvm_options); 2148 2149 if (!perf_host) 2150 perf_guest = 1; 2151 2152 if (!file_name) 2153 file_name = get_filename_for_perf_kvm(); 2154 2155 if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) 2156 ret = __cmd_record(file_name, argc, argv); 2157 else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) 2158 ret = __cmd_report(file_name, argc, argv); 2159 else if (strlen(argv[0]) > 2 && strstarts("diff", argv[0])) 2160 ret = cmd_diff(argc, argv); 2161 else if (!strcmp(argv[0], "top")) 2162 ret = __cmd_top(argc, argv); 2163 else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) 2164 ret = __cmd_buildid_list(file_name, argc, argv); 2165 #if defined(HAVE_LIBTRACEEVENT) 2166 else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) 2167 ret = kvm_cmd_stat(file_name, argc, argv); 2168 #endif 2169 else 2170 usage_with_options(kvm_usage, kvm_options); 2171 2172 /* free usage string allocated by parse_options_subcommand */ 2173 free((void *)kvm_usage[0]); 2174 2175 return ret; 2176 } 2177