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/ordered-events.h" 26 #include "util/kvm-stat.h" 27 #include "util/util.h" 28 #include "ui/browsers/hists.h" 29 #include "ui/progress.h" 30 #include "ui/ui.h" 31 #include "util/string2.h" 32 33 #include <sys/prctl.h> 34 #ifdef HAVE_TIMERFD_SUPPORT 35 #include <sys/timerfd.h> 36 #endif 37 #include <sys/time.h> 38 #include <sys/types.h> 39 #include <sys/stat.h> 40 #include <fcntl.h> 41 42 #include <linux/err.h> 43 #include <linux/kernel.h> 44 #include <linux/string.h> 45 #include <linux/time64.h> 46 #include <linux/zalloc.h> 47 #include <errno.h> 48 #include <inttypes.h> 49 #include <poll.h> 50 #include <termios.h> 51 #include <semaphore.h> 52 #include <signal.h> 53 #include <math.h> 54 #include <perf/mmap.h> 55 56 #if defined(HAVE_LIBTRACEEVENT) 57 #define GET_EVENT_KEY(func, field) \ 58 static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \ 59 { \ 60 if (vcpu == -1) \ 61 return event->total.field; \ 62 \ 63 if (vcpu >= event->max_vcpu) \ 64 return 0; \ 65 \ 66 return event->vcpu[vcpu].field; \ 67 } 68 69 #define COMPARE_EVENT_KEY(func, field) \ 70 GET_EVENT_KEY(func, field) \ 71 static int64_t cmp_event_ ## func(struct kvm_event *one, \ 72 struct kvm_event *two, int vcpu) \ 73 { \ 74 return get_event_ ##func(one, vcpu) - \ 75 get_event_ ##func(two, vcpu); \ 76 } 77 78 COMPARE_EVENT_KEY(time, time); 79 COMPARE_EVENT_KEY(max, stats.max); 80 COMPARE_EVENT_KEY(min, stats.min); 81 COMPARE_EVENT_KEY(count, stats.n); 82 COMPARE_EVENT_KEY(mean, stats.mean); 83 84 struct kvm_hists { 85 struct hists hists; 86 struct perf_hpp_list list; 87 }; 88 89 struct kvm_dimension { 90 const char *name; 91 const char *header; 92 int width; 93 int64_t (*cmp)(struct perf_hpp_fmt *fmt, struct hist_entry *left, 94 struct hist_entry *right); 95 int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 96 struct hist_entry *he); 97 }; 98 99 struct kvm_fmt { 100 struct perf_hpp_fmt fmt; 101 struct kvm_dimension *dim; 102 }; 103 104 static struct kvm_hists kvm_hists; 105 106 static int64_t ev_name_cmp(struct perf_hpp_fmt *fmt __maybe_unused, 107 struct hist_entry *left, 108 struct hist_entry *right) 109 { 110 /* Return opposite number for sorting in alphabetical order */ 111 return -strcmp(left->kvm_info->name, right->kvm_info->name); 112 } 113 114 static int fmt_width(struct perf_hpp_fmt *fmt, 115 struct perf_hpp *hpp __maybe_unused, 116 struct hists *hists __maybe_unused); 117 118 static int ev_name_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 119 struct hist_entry *he) 120 { 121 int width = fmt_width(fmt, hpp, he->hists); 122 123 return scnprintf(hpp->buf, hpp->size, "%*s", width, he->kvm_info->name); 124 } 125 126 static struct kvm_dimension dim_event = { 127 .header = "Event name", 128 .name = "ev_name", 129 .cmp = ev_name_cmp, 130 .entry = ev_name_entry, 131 .width = 40, 132 }; 133 134 #define EV_METRIC_CMP(metric) \ 135 static int64_t ev_cmp_##metric(struct perf_hpp_fmt *fmt __maybe_unused, \ 136 struct hist_entry *left, \ 137 struct hist_entry *right) \ 138 { \ 139 struct kvm_event *event_left; \ 140 struct kvm_event *event_right; \ 141 struct perf_kvm_stat *perf_kvm; \ 142 \ 143 event_left = container_of(left, struct kvm_event, he); \ 144 event_right = container_of(right, struct kvm_event, he); \ 145 \ 146 perf_kvm = event_left->perf_kvm; \ 147 return cmp_event_##metric(event_left, event_right, \ 148 perf_kvm->trace_vcpu); \ 149 } 150 151 EV_METRIC_CMP(time) 152 EV_METRIC_CMP(count) 153 EV_METRIC_CMP(max) 154 EV_METRIC_CMP(min) 155 EV_METRIC_CMP(mean) 156 157 #define EV_METRIC_ENTRY(metric) \ 158 static int ev_entry_##metric(struct perf_hpp_fmt *fmt, \ 159 struct perf_hpp *hpp, \ 160 struct hist_entry *he) \ 161 { \ 162 struct kvm_event *event; \ 163 int width = fmt_width(fmt, hpp, he->hists); \ 164 struct perf_kvm_stat *perf_kvm; \ 165 \ 166 event = container_of(he, struct kvm_event, he); \ 167 perf_kvm = event->perf_kvm; \ 168 return scnprintf(hpp->buf, hpp->size, "%*lu", width, \ 169 get_event_##metric(event, perf_kvm->trace_vcpu)); \ 170 } 171 172 EV_METRIC_ENTRY(time) 173 EV_METRIC_ENTRY(count) 174 EV_METRIC_ENTRY(max) 175 EV_METRIC_ENTRY(min) 176 177 static struct kvm_dimension dim_time = { 178 .header = "Time (ns)", 179 .name = "time", 180 .cmp = ev_cmp_time, 181 .entry = ev_entry_time, 182 .width = 12, 183 }; 184 185 static struct kvm_dimension dim_count = { 186 .header = "Samples", 187 .name = "sample", 188 .cmp = ev_cmp_count, 189 .entry = ev_entry_count, 190 .width = 12, 191 }; 192 193 static struct kvm_dimension dim_max_time = { 194 .header = "Max Time (ns)", 195 .name = "max_t", 196 .cmp = ev_cmp_max, 197 .entry = ev_entry_max, 198 .width = 14, 199 }; 200 201 static struct kvm_dimension dim_min_time = { 202 .header = "Min Time (ns)", 203 .name = "min_t", 204 .cmp = ev_cmp_min, 205 .entry = ev_entry_min, 206 .width = 14, 207 }; 208 209 static int ev_entry_mean(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 210 struct hist_entry *he) 211 { 212 struct kvm_event *event; 213 int width = fmt_width(fmt, hpp, he->hists); 214 struct perf_kvm_stat *perf_kvm; 215 216 event = container_of(he, struct kvm_event, he); 217 perf_kvm = event->perf_kvm; 218 return scnprintf(hpp->buf, hpp->size, "%*lu", width, 219 get_event_mean(event, perf_kvm->trace_vcpu)); 220 } 221 222 static struct kvm_dimension dim_mean_time = { 223 .header = "Mean Time (ns)", 224 .name = "mean_t", 225 .cmp = ev_cmp_mean, 226 .entry = ev_entry_mean, 227 .width = 14, 228 }; 229 230 #define PERC_STR(__s, __v) \ 231 ({ \ 232 scnprintf(__s, sizeof(__s), "%.2F%%", __v); \ 233 __s; \ 234 }) 235 236 static double percent(u64 st, u64 tot) 237 { 238 return tot ? 100. * (double) st / (double) tot : 0; 239 } 240 241 #define EV_METRIC_PERCENT(metric) \ 242 static int ev_percent_##metric(struct hist_entry *he) \ 243 { \ 244 struct kvm_event *event; \ 245 struct perf_kvm_stat *perf_kvm; \ 246 \ 247 event = container_of(he, struct kvm_event, he); \ 248 perf_kvm = event->perf_kvm; \ 249 \ 250 return percent(get_event_##metric(event, perf_kvm->trace_vcpu), \ 251 perf_kvm->total_##metric); \ 252 } 253 254 EV_METRIC_PERCENT(time) 255 EV_METRIC_PERCENT(count) 256 257 static int ev_entry_time_precent(struct perf_hpp_fmt *fmt, 258 struct perf_hpp *hpp, 259 struct hist_entry *he) 260 { 261 int width = fmt_width(fmt, hpp, he->hists); 262 double per; 263 char buf[10]; 264 265 per = ev_percent_time(he); 266 return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per)); 267 } 268 269 static int64_t 270 ev_cmp_time_precent(struct perf_hpp_fmt *fmt __maybe_unused, 271 struct hist_entry *left, struct hist_entry *right) 272 { 273 double per_left; 274 double per_right; 275 276 per_left = ev_percent_time(left); 277 per_right = ev_percent_time(right); 278 279 return per_left - per_right; 280 } 281 282 static struct kvm_dimension dim_time_percent = { 283 .header = "Time%", 284 .name = "percent_time", 285 .cmp = ev_cmp_time_precent, 286 .entry = ev_entry_time_precent, 287 .width = 12, 288 }; 289 290 static int ev_entry_count_precent(struct perf_hpp_fmt *fmt, 291 struct perf_hpp *hpp, 292 struct hist_entry *he) 293 { 294 int width = fmt_width(fmt, hpp, he->hists); 295 double per; 296 char buf[10]; 297 298 per = ev_percent_count(he); 299 return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per)); 300 } 301 302 static int64_t 303 ev_cmp_count_precent(struct perf_hpp_fmt *fmt __maybe_unused, 304 struct hist_entry *left, struct hist_entry *right) 305 { 306 double per_left; 307 double per_right; 308 309 per_left = ev_percent_count(left); 310 per_right = ev_percent_count(right); 311 312 return per_left - per_right; 313 } 314 315 static struct kvm_dimension dim_count_percent = { 316 .header = "Sample%", 317 .name = "percent_sample", 318 .cmp = ev_cmp_count_precent, 319 .entry = ev_entry_count_precent, 320 .width = 12, 321 }; 322 323 static struct kvm_dimension *dimensions[] = { 324 &dim_event, 325 &dim_time, 326 &dim_time_percent, 327 &dim_count, 328 &dim_count_percent, 329 &dim_max_time, 330 &dim_min_time, 331 &dim_mean_time, 332 NULL, 333 }; 334 335 static int fmt_width(struct perf_hpp_fmt *fmt, 336 struct perf_hpp *hpp __maybe_unused, 337 struct hists *hists __maybe_unused) 338 { 339 struct kvm_fmt *kvm_fmt; 340 341 kvm_fmt = container_of(fmt, struct kvm_fmt, fmt); 342 return kvm_fmt->dim->width; 343 } 344 345 static int fmt_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 346 struct hists *hists, int line __maybe_unused, 347 int *span __maybe_unused) 348 { 349 struct kvm_fmt *kvm_fmt; 350 struct kvm_dimension *dim; 351 int width = fmt_width(fmt, hpp, hists); 352 353 kvm_fmt = container_of(fmt, struct kvm_fmt, fmt); 354 dim = kvm_fmt->dim; 355 356 return scnprintf(hpp->buf, hpp->size, "%*s", width, dim->header); 357 } 358 359 static bool fmt_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b) 360 { 361 struct kvm_fmt *kvm_fmt_a = container_of(a, struct kvm_fmt, fmt); 362 struct kvm_fmt *kvm_fmt_b = container_of(b, struct kvm_fmt, fmt); 363 364 return kvm_fmt_a->dim == kvm_fmt_b->dim; 365 } 366 367 static void fmt_free(struct perf_hpp_fmt *fmt) 368 { 369 struct kvm_fmt *kvm_fmt; 370 371 kvm_fmt = container_of(fmt, struct kvm_fmt, fmt); 372 free(kvm_fmt); 373 } 374 375 static struct kvm_dimension *get_dimension(const char *name) 376 { 377 unsigned int i; 378 379 for (i = 0; dimensions[i] != NULL; i++) { 380 if (!strcmp(dimensions[i]->name, name)) 381 return dimensions[i]; 382 } 383 384 return NULL; 385 } 386 387 static struct kvm_fmt *get_format(const char *name) 388 { 389 struct kvm_dimension *dim = get_dimension(name); 390 struct kvm_fmt *kvm_fmt; 391 struct perf_hpp_fmt *fmt; 392 393 if (!dim) 394 return NULL; 395 396 kvm_fmt = zalloc(sizeof(*kvm_fmt)); 397 if (!kvm_fmt) 398 return NULL; 399 400 kvm_fmt->dim = dim; 401 402 fmt = &kvm_fmt->fmt; 403 INIT_LIST_HEAD(&fmt->list); 404 INIT_LIST_HEAD(&fmt->sort_list); 405 fmt->cmp = dim->cmp; 406 fmt->sort = dim->cmp; 407 fmt->color = NULL; 408 fmt->entry = dim->entry; 409 fmt->header = fmt_header; 410 fmt->width = fmt_width; 411 fmt->collapse = dim->cmp; 412 fmt->equal = fmt_equal; 413 fmt->free = fmt_free; 414 415 return kvm_fmt; 416 } 417 418 static int kvm_hists__init_output(struct perf_hpp_list *hpp_list, char *name) 419 { 420 struct kvm_fmt *kvm_fmt = get_format(name); 421 422 if (!kvm_fmt) { 423 pr_warning("Fail to find format for output field %s.\n", name); 424 return -EINVAL; 425 } 426 427 perf_hpp_list__column_register(hpp_list, &kvm_fmt->fmt); 428 return 0; 429 } 430 431 static int kvm_hists__init_sort(struct perf_hpp_list *hpp_list, char *name) 432 { 433 struct kvm_fmt *kvm_fmt = get_format(name); 434 435 if (!kvm_fmt) { 436 pr_warning("Fail to find format for sorting %s.\n", name); 437 return -EINVAL; 438 } 439 440 perf_hpp_list__register_sort_field(hpp_list, &kvm_fmt->fmt); 441 return 0; 442 } 443 444 static int kvm_hpp_list__init(char *list, 445 struct perf_hpp_list *hpp_list, 446 int (*fn)(struct perf_hpp_list *hpp_list, 447 char *name)) 448 { 449 char *tmp, *tok; 450 int ret; 451 452 if (!list || !fn) 453 return 0; 454 455 for (tok = strtok_r(list, ", ", &tmp); tok; 456 tok = strtok_r(NULL, ", ", &tmp)) { 457 ret = fn(hpp_list, tok); 458 if (!ret) 459 continue; 460 461 /* Handle errors */ 462 if (ret == -EINVAL) 463 pr_err("Invalid field key: '%s'", tok); 464 else if (ret == -ESRCH) 465 pr_err("Unknown field key: '%s'", tok); 466 else 467 pr_err("Fail to initialize for field key: '%s'", tok); 468 469 break; 470 } 471 472 return ret; 473 } 474 475 static int kvm_hpp_list__parse(struct perf_hpp_list *hpp_list, 476 const char *output_, const char *sort_) 477 { 478 char *output = output_ ? strdup(output_) : NULL; 479 char *sort = sort_ ? strdup(sort_) : NULL; 480 int ret; 481 482 ret = kvm_hpp_list__init(output, hpp_list, kvm_hists__init_output); 483 if (ret) 484 goto out; 485 486 ret = kvm_hpp_list__init(sort, hpp_list, kvm_hists__init_sort); 487 if (ret) 488 goto out; 489 490 /* Copy sort keys to output fields */ 491 perf_hpp__setup_output_field(hpp_list); 492 493 /* and then copy output fields to sort keys */ 494 perf_hpp__append_sort_keys(hpp_list); 495 out: 496 free(output); 497 free(sort); 498 return ret; 499 } 500 501 static int kvm_hists__init(void) 502 { 503 kvm_hists.list.nr_header_lines = 1; 504 __hists__init(&kvm_hists.hists, &kvm_hists.list); 505 perf_hpp_list__init(&kvm_hists.list); 506 return kvm_hpp_list__parse(&kvm_hists.list, NULL, "ev_name"); 507 } 508 509 static int kvm_hists__reinit(const char *output, const char *sort) 510 { 511 perf_hpp__reset_output_field(&kvm_hists.list); 512 return kvm_hpp_list__parse(&kvm_hists.list, output, sort); 513 } 514 static void print_result(struct perf_kvm_stat *kvm); 515 516 #ifdef HAVE_SLANG_SUPPORT 517 static void kvm_browser__update_nr_entries(struct hist_browser *hb) 518 { 519 struct rb_node *nd = rb_first_cached(&hb->hists->entries); 520 u64 nr_entries = 0; 521 522 for (; nd; nd = rb_next(nd)) { 523 struct hist_entry *he = rb_entry(nd, struct hist_entry, 524 rb_node); 525 526 if (!he->filtered) 527 nr_entries++; 528 } 529 530 hb->nr_non_filtered_entries = nr_entries; 531 } 532 533 static int kvm_browser__title(struct hist_browser *browser, 534 char *buf, size_t size) 535 { 536 scnprintf(buf, size, "KVM event statistics (%lu entries)", 537 browser->nr_non_filtered_entries); 538 return 0; 539 } 540 541 static struct hist_browser* 542 perf_kvm_browser__new(struct hists *hists) 543 { 544 struct hist_browser *browser = hist_browser__new(hists); 545 546 if (browser) 547 browser->title = kvm_browser__title; 548 549 return browser; 550 } 551 552 static int kvm__hists_browse(struct hists *hists) 553 { 554 struct hist_browser *browser; 555 int key = -1; 556 557 browser = perf_kvm_browser__new(hists); 558 if (browser == NULL) 559 return -1; 560 561 /* reset abort key so that it can get Ctrl-C as a key */ 562 SLang_reset_tty(); 563 SLang_init_tty(0, 0, 0); 564 565 kvm_browser__update_nr_entries(browser); 566 567 while (1) { 568 key = hist_browser__run(browser, "? - help", true, 0); 569 570 switch (key) { 571 case 'q': 572 goto out; 573 default: 574 break; 575 } 576 } 577 578 out: 579 hist_browser__delete(browser); 580 return 0; 581 } 582 583 static void kvm_display(struct perf_kvm_stat *kvm) 584 { 585 if (!use_browser) 586 print_result(kvm); 587 else 588 kvm__hists_browse(&kvm_hists.hists); 589 } 590 591 #else 592 593 static void kvm_display(struct perf_kvm_stat *kvm) 594 { 595 use_browser = 0; 596 print_result(kvm); 597 } 598 599 #endif /* HAVE_SLANG_SUPPORT */ 600 601 #endif // defined(HAVE_LIBTRACEEVENT) 602 603 static const char *get_filename_for_perf_kvm(void) 604 { 605 const char *filename; 606 607 if (perf_host && !perf_guest) 608 filename = strdup("perf.data.host"); 609 else if (!perf_host && perf_guest) 610 filename = strdup("perf.data.guest"); 611 else 612 filename = strdup("perf.data.kvm"); 613 614 return filename; 615 } 616 617 #if defined(HAVE_LIBTRACEEVENT) 618 619 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm, uint16_t e_machine) 620 { 621 const struct kvm_reg_events_ops *events_ops; 622 623 for (events_ops = kvm_reg_events_ops(e_machine); events_ops->name; events_ops++) { 624 if (!strcmp(events_ops->name, kvm->report_event)) { 625 kvm->events_ops = events_ops->ops; 626 return true; 627 } 628 } 629 630 return false; 631 } 632 633 struct vcpu_event_record { 634 int vcpu_id; 635 u64 start_time; 636 struct kvm_event *last_event; 637 }; 638 639 #ifdef HAVE_TIMERFD_SUPPORT 640 static void clear_events_cache_stats(void) 641 { 642 struct rb_root_cached *root; 643 struct rb_node *nd; 644 struct kvm_event *event; 645 int i; 646 647 if (hists__has(&kvm_hists.hists, need_collapse)) 648 root = &kvm_hists.hists.entries_collapsed; 649 else 650 root = kvm_hists.hists.entries_in; 651 652 for (nd = rb_first_cached(root); nd; nd = rb_next(nd)) { 653 struct hist_entry *he; 654 655 he = rb_entry(nd, struct hist_entry, rb_node_in); 656 event = container_of(he, struct kvm_event, he); 657 658 /* reset stats for event */ 659 event->total.time = 0; 660 init_stats(&event->total.stats); 661 662 for (i = 0; i < event->max_vcpu; ++i) { 663 event->vcpu[i].time = 0; 664 init_stats(&event->vcpu[i].stats); 665 } 666 } 667 } 668 #endif 669 670 static bool kvm_event_expand(struct kvm_event *event, int vcpu_id) 671 { 672 int old_max_vcpu = event->max_vcpu; 673 void *prev; 674 675 if (vcpu_id < event->max_vcpu) 676 return true; 677 678 while (event->max_vcpu <= vcpu_id) 679 event->max_vcpu += DEFAULT_VCPU_NUM; 680 681 prev = event->vcpu; 682 event->vcpu = realloc(event->vcpu, 683 event->max_vcpu * sizeof(*event->vcpu)); 684 if (!event->vcpu) { 685 free(prev); 686 pr_err("Not enough memory\n"); 687 return false; 688 } 689 690 memset(event->vcpu + old_max_vcpu, 0, 691 (event->max_vcpu - old_max_vcpu) * sizeof(*event->vcpu)); 692 return true; 693 } 694 695 static void *kvm_he_zalloc(size_t size) 696 { 697 struct kvm_event *kvm_ev; 698 699 kvm_ev = zalloc(size + sizeof(*kvm_ev)); 700 if (!kvm_ev) 701 return NULL; 702 703 init_stats(&kvm_ev->total.stats); 704 hists__inc_nr_samples(&kvm_hists.hists, 0); 705 return &kvm_ev->he; 706 } 707 708 static void kvm_he_free(void *he) 709 { 710 struct kvm_event *kvm_ev; 711 712 kvm_ev = container_of(he, struct kvm_event, he); 713 free(kvm_ev); 714 } 715 716 static struct hist_entry_ops kvm_ev_entry_ops = { 717 .new = kvm_he_zalloc, 718 .free = kvm_he_free, 719 }; 720 721 static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm, 722 struct event_key *key, 723 struct perf_sample *sample) 724 { 725 struct kvm_event *event; 726 struct hist_entry *he; 727 struct kvm_info *ki; 728 729 BUG_ON(key->key == INVALID_KEY); 730 731 ki = kvm_info__new(); 732 if (!ki) { 733 pr_err("Failed to allocate kvm info\n"); 734 return NULL; 735 } 736 737 kvm->events_ops->decode_key(kvm, key, ki->name); 738 he = hists__add_entry_ops(&kvm_hists.hists, &kvm_ev_entry_ops, 739 &kvm->al, NULL, NULL, NULL, ki, sample, true); 740 if (he == NULL) { 741 pr_err("Failed to allocate hist entry\n"); 742 free(ki); 743 return NULL; 744 } 745 746 event = container_of(he, struct kvm_event, he); 747 if (!event->perf_kvm) { 748 event->perf_kvm = kvm; 749 event->key = *key; 750 } 751 752 return event; 753 } 754 755 static bool handle_begin_event(struct perf_kvm_stat *kvm, 756 struct vcpu_event_record *vcpu_record, 757 struct event_key *key, 758 struct perf_sample *sample) 759 { 760 struct kvm_event *event = NULL; 761 762 if (key->key != INVALID_KEY) 763 event = find_create_kvm_event(kvm, key, sample); 764 765 vcpu_record->last_event = event; 766 vcpu_record->start_time = sample->time; 767 return true; 768 } 769 770 static void 771 kvm_update_event_stats(struct kvm_event_stats *kvm_stats, u64 time_diff) 772 { 773 kvm_stats->time += time_diff; 774 update_stats(&kvm_stats->stats, time_diff); 775 } 776 777 static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event) 778 { 779 struct kvm_event_stats *kvm_stats = &event->total; 780 781 if (vcpu_id != -1) 782 kvm_stats = &event->vcpu[vcpu_id]; 783 784 return rel_stddev_stats(stddev_stats(&kvm_stats->stats), 785 avg_stats(&kvm_stats->stats)); 786 } 787 788 static bool update_kvm_event(struct perf_kvm_stat *kvm, 789 struct kvm_event *event, int vcpu_id, 790 u64 time_diff) 791 { 792 /* Update overall statistics */ 793 kvm->total_count++; 794 kvm->total_time += time_diff; 795 796 if (vcpu_id == -1) { 797 kvm_update_event_stats(&event->total, time_diff); 798 return true; 799 } 800 801 if (!kvm_event_expand(event, vcpu_id)) 802 return false; 803 804 kvm_update_event_stats(&event->vcpu[vcpu_id], time_diff); 805 return true; 806 } 807 808 static bool is_child_event(struct perf_kvm_stat *kvm, 809 struct evsel *evsel, 810 struct perf_sample *sample, 811 struct event_key *key) 812 { 813 const struct child_event_ops *child_ops; 814 815 child_ops = kvm->events_ops->child_ops; 816 817 if (!child_ops) 818 return false; 819 820 for (; child_ops->name; child_ops++) { 821 if (evsel__name_is(evsel, child_ops->name)) { 822 child_ops->get_key(evsel, sample, key); 823 return true; 824 } 825 } 826 827 return false; 828 } 829 830 static bool handle_child_event(struct perf_kvm_stat *kvm, 831 struct vcpu_event_record *vcpu_record, 832 struct event_key *key, 833 struct perf_sample *sample) 834 { 835 struct kvm_event *event = NULL; 836 837 if (key->key != INVALID_KEY) 838 event = find_create_kvm_event(kvm, key, sample); 839 840 vcpu_record->last_event = event; 841 842 return true; 843 } 844 845 static bool skip_event(uint16_t e_machine, const char *event) 846 { 847 const char * const *skip_events; 848 849 for (skip_events = kvm_skip_events(e_machine); *skip_events; skip_events++) 850 if (!strcmp(event, *skip_events)) 851 return true; 852 853 return false; 854 } 855 856 static bool handle_end_event(struct perf_kvm_stat *kvm, 857 struct vcpu_event_record *vcpu_record, 858 struct event_key *key, 859 struct perf_sample *sample) 860 { 861 struct kvm_event *event; 862 u64 time_begin, time_diff; 863 int vcpu; 864 865 if (kvm->trace_vcpu == -1) 866 vcpu = -1; 867 else 868 vcpu = vcpu_record->vcpu_id; 869 870 event = vcpu_record->last_event; 871 time_begin = vcpu_record->start_time; 872 873 /* The begin event is not caught. */ 874 if (!time_begin) 875 return true; 876 877 /* 878 * In some case, the 'begin event' only records the start timestamp, 879 * the actual event is recognized in the 'end event' (e.g. mmio-event). 880 */ 881 882 /* Both begin and end events did not get the key. */ 883 if (!event && key->key == INVALID_KEY) 884 return true; 885 886 if (!event) 887 event = find_create_kvm_event(kvm, key, sample); 888 889 if (!event) 890 return false; 891 892 vcpu_record->last_event = NULL; 893 vcpu_record->start_time = 0; 894 895 /* seems to happen once in a while during live mode */ 896 if (sample->time < time_begin) { 897 pr_debug("End time before begin time; skipping event.\n"); 898 return true; 899 } 900 901 time_diff = sample->time - time_begin; 902 903 if (kvm->duration && time_diff > kvm->duration) { 904 char decode[KVM_EVENT_NAME_LEN]; 905 uint16_t e_machine = perf_session__e_machine(kvm->session); 906 907 kvm->events_ops->decode_key(kvm, &event->key, decode); 908 if (!skip_event(e_machine, decode)) { 909 pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n", 910 sample->time, sample->pid, vcpu_record->vcpu_id, 911 decode, time_diff / NSEC_PER_USEC); 912 } 913 } 914 915 return update_kvm_event(kvm, event, vcpu, time_diff); 916 } 917 918 static 919 struct vcpu_event_record *per_vcpu_record(struct thread *thread, 920 struct evsel *evsel, 921 struct perf_sample *sample) 922 { 923 /* Only kvm_entry records vcpu id. */ 924 if (!thread__priv(thread) && kvm_entry_event(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 = evsel__intval(evsel, 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 evsel *evsel, 945 struct perf_sample *sample) 946 { 947 struct vcpu_event_record *vcpu_record; 948 struct event_key key = { .key = INVALID_KEY, 949 .exit_reasons = kvm->exit_reasons }; 950 951 vcpu_record = per_vcpu_record(thread, evsel, sample); 952 if (!vcpu_record) 953 return true; 954 955 /* only process events for vcpus user cares about */ 956 if ((kvm->trace_vcpu != -1) && 957 (kvm->trace_vcpu != vcpu_record->vcpu_id)) 958 return true; 959 960 if (kvm->events_ops->is_begin_event(evsel, sample, &key)) 961 return handle_begin_event(kvm, vcpu_record, &key, sample); 962 963 if (is_child_event(kvm, evsel, sample, &key)) 964 return handle_child_event(kvm, vcpu_record, &key, sample); 965 966 if (kvm->events_ops->is_end_event(evsel, sample, &key)) 967 return handle_end_event(kvm, vcpu_record, &key, sample); 968 969 return true; 970 } 971 972 static bool is_valid_key(struct perf_kvm_stat *kvm) 973 { 974 static const char *key_array[] = { 975 "ev_name", "sample", "time", "max_t", "min_t", "mean_t", 976 }; 977 unsigned int i; 978 979 for (i = 0; i < ARRAY_SIZE(key_array); i++) 980 if (!strcmp(key_array[i], kvm->sort_key)) 981 return true; 982 983 pr_err("Unsupported sort key: %s\n", kvm->sort_key); 984 return false; 985 } 986 987 static bool event_is_valid(struct kvm_event *event, int vcpu) 988 { 989 return !!get_event_count(event, vcpu); 990 } 991 992 static int filter_cb(struct hist_entry *he, void *arg __maybe_unused) 993 { 994 struct kvm_event *event; 995 struct perf_kvm_stat *perf_kvm; 996 997 event = container_of(he, struct kvm_event, he); 998 perf_kvm = event->perf_kvm; 999 if (!event_is_valid(event, perf_kvm->trace_vcpu)) 1000 he->filtered = 1; 1001 else 1002 he->filtered = 0; 1003 return 0; 1004 } 1005 1006 static void sort_result(struct perf_kvm_stat *kvm) 1007 { 1008 struct ui_progress prog; 1009 const char *output_columns = "ev_name,sample,percent_sample," 1010 "time,percent_time,max_t,min_t,mean_t"; 1011 1012 kvm_hists__reinit(output_columns, kvm->sort_key); 1013 ui_progress__init(&prog, kvm_hists.hists.nr_entries, "Sorting..."); 1014 hists__collapse_resort(&kvm_hists.hists, NULL); 1015 hists__output_resort_cb(&kvm_hists.hists, NULL, filter_cb); 1016 ui_progress__finish(); 1017 } 1018 1019 static void print_vcpu_info(struct perf_kvm_stat *kvm) 1020 { 1021 int vcpu = kvm->trace_vcpu; 1022 1023 pr_info("Analyze events for "); 1024 1025 if (kvm->opts.target.system_wide) 1026 pr_info("all VMs, "); 1027 else if (kvm->opts.target.pid) 1028 pr_info("pid(s) %s, ", kvm->opts.target.pid); 1029 else 1030 pr_info("dazed and confused on what is monitored, "); 1031 1032 if (vcpu == -1) 1033 pr_info("all VCPUs:\n\n"); 1034 else 1035 pr_info("VCPU %d:\n\n", vcpu); 1036 } 1037 1038 static void show_timeofday(void) 1039 { 1040 char date[64]; 1041 struct timeval tv; 1042 struct tm ltime; 1043 1044 gettimeofday(&tv, NULL); 1045 if (localtime_r(&tv.tv_sec, <ime)) { 1046 strftime(date, sizeof(date), "%H:%M:%S", <ime); 1047 pr_info("%s.%06ld", date, tv.tv_usec); 1048 } else 1049 pr_info("00:00:00.000000"); 1050 1051 return; 1052 } 1053 1054 static void print_result(struct perf_kvm_stat *kvm) 1055 { 1056 char decode[KVM_EVENT_NAME_LEN]; 1057 struct kvm_event *event; 1058 int vcpu = kvm->trace_vcpu; 1059 struct rb_node *nd; 1060 1061 if (kvm->live) { 1062 puts(CONSOLE_CLEAR); 1063 show_timeofday(); 1064 } 1065 1066 pr_info("\n\n"); 1067 print_vcpu_info(kvm); 1068 pr_info("%*s ", KVM_EVENT_NAME_LEN, kvm->events_ops->name); 1069 pr_info("%10s ", "Samples"); 1070 pr_info("%9s ", "Samples%"); 1071 1072 pr_info("%9s ", "Time%"); 1073 pr_info("%11s ", "Min Time"); 1074 pr_info("%11s ", "Max Time"); 1075 pr_info("%16s ", "Avg time"); 1076 pr_info("\n\n"); 1077 1078 for (nd = rb_first_cached(&kvm_hists.hists.entries); nd; nd = rb_next(nd)) { 1079 struct hist_entry *he; 1080 u64 ecount, etime, max, min; 1081 1082 he = rb_entry(nd, struct hist_entry, rb_node); 1083 if (he->filtered) 1084 continue; 1085 1086 event = container_of(he, struct kvm_event, he); 1087 ecount = get_event_count(event, vcpu); 1088 etime = get_event_time(event, vcpu); 1089 max = get_event_max(event, vcpu); 1090 min = get_event_min(event, vcpu); 1091 1092 kvm->events_ops->decode_key(kvm, &event->key, decode); 1093 pr_info("%*s ", KVM_EVENT_NAME_LEN, decode); 1094 pr_info("%10llu ", (unsigned long long)ecount); 1095 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100); 1096 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100); 1097 pr_info("%9.2fus ", (double)min / NSEC_PER_USEC); 1098 pr_info("%9.2fus ", (double)max / NSEC_PER_USEC); 1099 pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount / NSEC_PER_USEC, 1100 kvm_event_rel_stddev(vcpu, event)); 1101 pr_info("\n"); 1102 } 1103 1104 pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n", 1105 kvm->total_count, kvm->total_time / (double)NSEC_PER_USEC); 1106 1107 if (kvm->lost_events) 1108 pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events); 1109 } 1110 1111 #if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 1112 static int process_lost_event(const struct perf_tool *tool, 1113 union perf_event *event __maybe_unused, 1114 struct perf_sample *sample __maybe_unused, 1115 struct machine *machine __maybe_unused) 1116 { 1117 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool); 1118 1119 kvm->lost_events++; 1120 return 0; 1121 } 1122 #endif 1123 1124 static bool skip_sample(struct perf_kvm_stat *kvm, 1125 struct perf_sample *sample) 1126 { 1127 if (kvm->pid_list && intlist__find(kvm->pid_list, sample->pid) == NULL) 1128 return true; 1129 1130 return false; 1131 } 1132 1133 static int process_sample_event(const struct perf_tool *tool, 1134 union perf_event *event, 1135 struct perf_sample *sample, 1136 struct evsel *evsel, 1137 struct machine *machine) 1138 { 1139 int err = 0; 1140 struct thread *thread; 1141 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, 1142 tool); 1143 1144 if (skip_sample(kvm, sample)) 1145 return 0; 1146 1147 if (machine__resolve(machine, &kvm->al, sample) < 0) { 1148 pr_warning("Fail to resolve address location, skip sample.\n"); 1149 return 0; 1150 } 1151 1152 thread = machine__findnew_thread(machine, sample->pid, sample->tid); 1153 if (thread == NULL) { 1154 pr_debug("problem processing %d event, skipping it.\n", 1155 event->header.type); 1156 return -1; 1157 } 1158 1159 if (!handle_kvm_event(kvm, thread, evsel, 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); 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[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 < kvm->evlist->core.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 = &kvm->evlist->core.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__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 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 if (!register_kvm_events_ops(kvm, perf_session__e_machine(kvm->session))) { 1578 ret = -EINVAL; 1579 goto out_delete; 1580 } 1581 1582 /* 1583 * Do not use 'isa' recorded in kvm_exit tracepoint since it is not 1584 * traced in the old kernel. 1585 */ 1586 ret = cpu_isa_config(kvm); 1587 if (ret < 0) 1588 goto out_delete; 1589 1590 ret = perf_session__process_events(kvm->session); 1591 1592 out_delete: 1593 perf_session__delete(kvm->session); 1594 return ret; 1595 } 1596 1597 static int parse_target_str(struct perf_kvm_stat *kvm) 1598 { 1599 if (kvm->opts.target.pid) { 1600 kvm->pid_list = intlist__new(kvm->opts.target.pid); 1601 if (kvm->pid_list == NULL) { 1602 pr_err("Error parsing process id string\n"); 1603 return -EINVAL; 1604 } 1605 } 1606 1607 return 0; 1608 } 1609 1610 static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm) 1611 { 1612 int ret = -EINVAL; 1613 int vcpu = kvm->trace_vcpu; 1614 1615 if (parse_target_str(kvm) != 0) 1616 goto exit; 1617 1618 if (!verify_vcpu(vcpu)) 1619 goto exit; 1620 1621 if (!is_valid_key(kvm)) 1622 goto exit; 1623 1624 if (kvm->use_stdio) { 1625 use_browser = 0; 1626 setup_pager(); 1627 } else { 1628 use_browser = 1; 1629 } 1630 1631 setup_browser(false); 1632 1633 kvm_hists__init(); 1634 1635 ret = read_events(kvm); 1636 if (ret) 1637 goto exit; 1638 1639 sort_result(kvm); 1640 kvm_display(kvm); 1641 1642 exit: 1643 hists__delete_entries(&kvm_hists.hists); 1644 return ret; 1645 } 1646 1647 static int 1648 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) 1649 { 1650 unsigned int rec_argc, i, j, events_tp_size; 1651 const char **rec_argv; 1652 const char * const record_args[] = { 1653 "record", 1654 "-R", 1655 "-m", "1024", 1656 "-c", "1", 1657 }; 1658 const char * const kvm_stat_record_usage[] = { 1659 "perf kvm stat record [<options>]", 1660 NULL 1661 }; 1662 const char * const *events_tp; 1663 int ret; 1664 uint16_t e_machine = EM_HOST; 1665 1666 events_tp_size = 0; 1667 ret = setup_kvm_events_tp(kvm, e_machine); 1668 if (ret < 0) { 1669 pr_err("Unable to setup the kvm tracepoints\n"); 1670 return ret; 1671 } 1672 1673 for (events_tp = kvm_events_tp(e_machine); *events_tp; events_tp++) 1674 events_tp_size++; 1675 1676 rec_argc = ARRAY_SIZE(record_args) + argc + 2 + 1677 2 * events_tp_size; 1678 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1679 1680 if (rec_argv == NULL) 1681 return -ENOMEM; 1682 1683 for (i = 0; i < ARRAY_SIZE(record_args); i++) 1684 rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]); 1685 1686 for (j = 0; j < events_tp_size; j++) { 1687 rec_argv[i++] = STRDUP_FAIL_EXIT("-e"); 1688 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp(e_machine)[j]); 1689 } 1690 1691 rec_argv[i++] = STRDUP_FAIL_EXIT("-o"); 1692 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name); 1693 1694 for (j = 1; j < (unsigned int)argc; j++, i++) 1695 rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 1696 1697 set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN); 1698 set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN); 1699 set_option_flag(record_options, 'R', "raw-samples", PARSE_OPT_HIDDEN); 1700 1701 set_option_flag(record_options, 'F', "freq", PARSE_OPT_DISABLED); 1702 set_option_flag(record_options, 0, "group", PARSE_OPT_DISABLED); 1703 set_option_flag(record_options, 'g', NULL, PARSE_OPT_DISABLED); 1704 set_option_flag(record_options, 0, "call-graph", PARSE_OPT_DISABLED); 1705 set_option_flag(record_options, 'd', "data", PARSE_OPT_DISABLED); 1706 set_option_flag(record_options, 'T', "timestamp", PARSE_OPT_DISABLED); 1707 set_option_flag(record_options, 'P', "period", PARSE_OPT_DISABLED); 1708 set_option_flag(record_options, 'n', "no-samples", PARSE_OPT_DISABLED); 1709 set_option_flag(record_options, 'N', "no-buildid-cache", PARSE_OPT_DISABLED); 1710 set_option_flag(record_options, 'B', "no-buildid", PARSE_OPT_DISABLED); 1711 set_option_flag(record_options, 'G', "cgroup", PARSE_OPT_DISABLED); 1712 set_option_flag(record_options, 'b', "branch-any", PARSE_OPT_DISABLED); 1713 set_option_flag(record_options, 'j', "branch-filter", PARSE_OPT_DISABLED); 1714 set_option_flag(record_options, 'W', "weight", PARSE_OPT_DISABLED); 1715 set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED); 1716 1717 record_usage = kvm_stat_record_usage; 1718 ret = cmd_record(i, rec_argv); 1719 1720 EXIT: 1721 for (i = 0; i < rec_argc; i++) 1722 free((void *)rec_argv[i]); 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__delete(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 kvm->evlist->core.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__delete(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 1999 /* 2000 * Besides the 2 more options "-o" and "filename", 2001 * kvm_add_default_arch_event() may add 2 extra options, 2002 * so allocate 4 more items. 2003 */ 2004 rec_argc = argc + 2 + 2; 2005 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2006 if (!rec_argv) 2007 return -ENOMEM; 2008 2009 rec_argv[i++] = STRDUP_FAIL_EXIT("record"); 2010 rec_argv[i++] = STRDUP_FAIL_EXIT("-o"); 2011 rec_argv[i++] = STRDUP_FAIL_EXIT(file_name); 2012 for (j = 1; j < argc; j++, i++) 2013 rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 2014 2015 BUG_ON(i + 2 != rec_argc); 2016 2017 ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); 2018 if (ret) 2019 goto EXIT; 2020 2021 ret = cmd_record(i, rec_argv); 2022 2023 EXIT: 2024 for (i = 0; i < rec_argc; i++) 2025 free((void *)rec_argv[i]); 2026 free(rec_argv); 2027 return ret; 2028 } 2029 2030 static int __cmd_report(const char *file_name, int argc, const char **argv) 2031 { 2032 int rec_argc, i = 0, j, ret; 2033 const char **rec_argv; 2034 2035 rec_argc = argc + 2; 2036 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2037 if (!rec_argv) 2038 return -ENOMEM; 2039 2040 rec_argv[i++] = STRDUP_FAIL_EXIT("report"); 2041 rec_argv[i++] = STRDUP_FAIL_EXIT("-i"); 2042 rec_argv[i++] = STRDUP_FAIL_EXIT(file_name); 2043 for (j = 1; j < argc; j++, i++) 2044 rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 2045 2046 BUG_ON(i != rec_argc); 2047 2048 ret = cmd_report(i, rec_argv); 2049 2050 EXIT: 2051 for (i = 0; i < rec_argc; i++) 2052 free((void *)rec_argv[i]); 2053 free(rec_argv); 2054 return ret; 2055 } 2056 2057 static int 2058 __cmd_buildid_list(const char *file_name, int argc, const char **argv) 2059 { 2060 int rec_argc, i = 0, j, ret; 2061 const char **rec_argv; 2062 2063 rec_argc = argc + 2; 2064 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2065 if (!rec_argv) 2066 return -ENOMEM; 2067 2068 rec_argv[i++] = STRDUP_FAIL_EXIT("buildid-list"); 2069 rec_argv[i++] = STRDUP_FAIL_EXIT("-i"); 2070 rec_argv[i++] = STRDUP_FAIL_EXIT(file_name); 2071 for (j = 1; j < argc; j++, i++) 2072 rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 2073 2074 BUG_ON(i != rec_argc); 2075 2076 ret = cmd_buildid_list(i, rec_argv); 2077 2078 EXIT: 2079 for (i = 0; i < rec_argc; i++) 2080 free((void *)rec_argv[i]); 2081 free(rec_argv); 2082 return ret; 2083 } 2084 2085 static int __cmd_top(int argc, const char **argv) 2086 { 2087 int rec_argc, i = 0, ret; 2088 const char **rec_argv; 2089 2090 /* 2091 * kvm_add_default_arch_event() may add 2 extra options, so 2092 * allocate 2 more pointers in adavance. 2093 */ 2094 rec_argc = argc + 2; 2095 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2096 if (!rec_argv) 2097 return -ENOMEM; 2098 2099 for (i = 0; i < argc; i++) 2100 rec_argv[i] = STRDUP_FAIL_EXIT(argv[i]); 2101 2102 BUG_ON(i != argc); 2103 2104 ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); 2105 if (ret) 2106 goto EXIT; 2107 2108 ret = cmd_top(i, rec_argv); 2109 2110 EXIT: 2111 for (i = 0; i < rec_argc; i++) 2112 free((void *)rec_argv[i]); 2113 free(rec_argv); 2114 return ret; 2115 } 2116 2117 int cmd_kvm(int argc, const char **argv) 2118 { 2119 const char *file_name = NULL; 2120 const struct option kvm_options[] = { 2121 OPT_STRING('i', "input", &file_name, "file", 2122 "Input file name"), 2123 OPT_STRING('o', "output", &file_name, "file", 2124 "Output file name"), 2125 OPT_BOOLEAN(0, "guest", &perf_guest, 2126 "Collect guest os data"), 2127 OPT_BOOLEAN(0, "host", &perf_host, 2128 "Collect host os data"), 2129 OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory", 2130 "guest mount directory under which every guest os" 2131 " instance has a subdir"), 2132 OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name, 2133 "file", "file saving guest os vmlinux"), 2134 OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms, 2135 "file", "file saving guest os /proc/kallsyms"), 2136 OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, 2137 "file", "file saving guest os /proc/modules"), 2138 OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code, 2139 "Guest code can be found in hypervisor process"), 2140 OPT_INCR('v', "verbose", &verbose, 2141 "be more verbose (show counter open errors, etc)"), 2142 OPT_END() 2143 }; 2144 2145 const char *const kvm_subcommands[] = { "top", "record", "report", "diff", 2146 "buildid-list", "stat", NULL }; 2147 const char *kvm_usage[] = { NULL, NULL }; 2148 2149 exclude_GH_default = true; 2150 perf_host = 0; 2151 perf_guest = 1; 2152 2153 argc = parse_options_subcommand(argc, argv, kvm_options, kvm_subcommands, kvm_usage, 2154 PARSE_OPT_STOP_AT_NON_OPTION); 2155 if (!argc) 2156 usage_with_options(kvm_usage, kvm_options); 2157 2158 if (!perf_host) 2159 perf_guest = 1; 2160 2161 if (!file_name) { 2162 file_name = get_filename_for_perf_kvm(); 2163 2164 if (!file_name) { 2165 pr_err("Failed to allocate memory for filename\n"); 2166 return -ENOMEM; 2167 } 2168 } 2169 2170 if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) 2171 return __cmd_record(file_name, argc, argv); 2172 else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) 2173 return __cmd_report(file_name, argc, argv); 2174 else if (strlen(argv[0]) > 2 && strstarts("diff", argv[0])) 2175 return cmd_diff(argc, argv); 2176 else if (!strcmp(argv[0], "top")) 2177 return __cmd_top(argc, argv); 2178 else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) 2179 return __cmd_buildid_list(file_name, argc, argv); 2180 #if defined(HAVE_LIBTRACEEVENT) 2181 else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) 2182 return kvm_cmd_stat(file_name, argc, argv); 2183 #endif 2184 else 2185 usage_with_options(kvm_usage, kvm_options); 2186 2187 /* free usage string allocated by parse_options_subcommand */ 2188 free((void *)kvm_usage[0]); 2189 2190 return 0; 2191 } 2192