root/tools/perf/builtin-kvm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_filename_for_perf_kvm
  2. exit_event_get_key
  3. kvm_exit_event
  4. exit_event_begin
  5. kvm_entry_event
  6. exit_event_end
  7. get_exit_reason
  8. exit_event_decode_key
  9. register_kvm_events_ops
  10. init_kvm_event_record
  11. clear_events_cache_stats
  12. kvm_events_hash_fn
  13. kvm_event_expand
  14. kvm_alloc_init_event
  15. find_create_kvm_event
  16. handle_begin_event
  17. kvm_update_event_stats
  18. kvm_event_rel_stddev
  19. update_kvm_event
  20. is_child_event
  21. handle_child_event
  22. skip_event
  23. handle_end_event
  24. per_vcpu_record
  25. handle_kvm_event
  26. select_key
  27. insert_to_result
  28. update_total_count
  29. event_is_valid
  30. sort_result
  31. pop_from_result
  32. print_vcpu_info
  33. show_timeofday
  34. print_result
  35. process_lost_event
  36. skip_sample
  37. process_sample_event
  38. cpu_isa_config
  39. verify_vcpu
  40. perf_kvm__mmap_read_idx
  41. perf_kvm__mmap_read
  42. sig_handler
  43. perf_kvm__timerfd_create
  44. perf_kvm__handle_timerfd
  45. fd_set_nonblock
  46. perf_kvm__handle_stdin
  47. kvm_events_live_report
  48. kvm_live_open_events
  49. read_events
  50. parse_target_str
  51. kvm_events_report_vcpu
  52. setup_kvm_events_tp
  53. kvm_events_record
  54. kvm_events_report
  55. kvm_live_event_list
  56. kvm_events_live
  57. print_kvm_stat_usage
  58. kvm_cmd_stat
  59. kvm_add_default_arch_event
  60. __cmd_record
  61. __cmd_report
  62. __cmd_buildid_list
  63. cmd_kvm

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include "builtin.h"
   3 #include "perf.h"
   4 
   5 #include "util/build-id.h"
   6 #include "util/evsel.h"
   7 #include "util/evlist.h"
   8 #include "util/mmap.h"
   9 #include "util/term.h"
  10 #include "util/symbol.h"
  11 #include "util/thread.h"
  12 #include "util/header.h"
  13 #include "util/session.h"
  14 #include "util/intlist.h"
  15 #include <subcmd/pager.h>
  16 #include <subcmd/parse-options.h>
  17 #include "util/trace-event.h"
  18 #include "util/debug.h"
  19 #include "util/tool.h"
  20 #include "util/stat.h"
  21 #include "util/synthetic-events.h"
  22 #include "util/top.h"
  23 #include "util/data.h"
  24 #include "util/ordered-events.h"
  25 #include "util/kvm-stat.h"
  26 #include "ui/ui.h"
  27 
  28 #include <sys/prctl.h>
  29 #ifdef HAVE_TIMERFD_SUPPORT
  30 #include <sys/timerfd.h>
  31 #endif
  32 #include <sys/time.h>
  33 #include <sys/types.h>
  34 #include <sys/stat.h>
  35 #include <fcntl.h>
  36 
  37 #include <linux/err.h>
  38 #include <linux/kernel.h>
  39 #include <linux/string.h>
  40 #include <linux/time64.h>
  41 #include <linux/zalloc.h>
  42 #include <errno.h>
  43 #include <inttypes.h>
  44 #include <poll.h>
  45 #include <termios.h>
  46 #include <semaphore.h>
  47 #include <signal.h>
  48 #include <math.h>
  49 
  50 static const char *get_filename_for_perf_kvm(void)
  51 {
  52         const char *filename;
  53 
  54         if (perf_host && !perf_guest)
  55                 filename = strdup("perf.data.host");
  56         else if (!perf_host && perf_guest)
  57                 filename = strdup("perf.data.guest");
  58         else
  59                 filename = strdup("perf.data.kvm");
  60 
  61         return filename;
  62 }
  63 
  64 #ifdef HAVE_KVM_STAT_SUPPORT
  65 
  66 void exit_event_get_key(struct evsel *evsel,
  67                         struct perf_sample *sample,
  68                         struct event_key *key)
  69 {
  70         key->info = 0;
  71         key->key = perf_evsel__intval(evsel, sample, kvm_exit_reason);
  72 }
  73 
  74 bool kvm_exit_event(struct evsel *evsel)
  75 {
  76         return !strcmp(evsel->name, kvm_exit_trace);
  77 }
  78 
  79 bool exit_event_begin(struct evsel *evsel,
  80                       struct perf_sample *sample, struct event_key *key)
  81 {
  82         if (kvm_exit_event(evsel)) {
  83                 exit_event_get_key(evsel, sample, key);
  84                 return true;
  85         }
  86 
  87         return false;
  88 }
  89 
  90 bool kvm_entry_event(struct evsel *evsel)
  91 {
  92         return !strcmp(evsel->name, kvm_entry_trace);
  93 }
  94 
  95 bool exit_event_end(struct evsel *evsel,
  96                     struct perf_sample *sample __maybe_unused,
  97                     struct event_key *key __maybe_unused)
  98 {
  99         return kvm_entry_event(evsel);
 100 }
 101 
 102 static const char *get_exit_reason(struct perf_kvm_stat *kvm,
 103                                    struct exit_reasons_table *tbl,
 104                                    u64 exit_code)
 105 {
 106         while (tbl->reason != NULL) {
 107                 if (tbl->exit_code == exit_code)
 108                         return tbl->reason;
 109                 tbl++;
 110         }
 111 
 112         pr_err("unknown kvm exit code:%lld on %s\n",
 113                 (unsigned long long)exit_code, kvm->exit_reasons_isa);
 114         return "UNKNOWN";
 115 }
 116 
 117 void exit_event_decode_key(struct perf_kvm_stat *kvm,
 118                            struct event_key *key,
 119                            char *decode)
 120 {
 121         const char *exit_reason = get_exit_reason(kvm, key->exit_reasons,
 122                                                   key->key);
 123 
 124         scnprintf(decode, decode_str_len, "%s", exit_reason);
 125 }
 126 
 127 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
 128 {
 129         struct kvm_reg_events_ops *events_ops = kvm_reg_events_ops;
 130 
 131         for (events_ops = kvm_reg_events_ops; events_ops->name; events_ops++) {
 132                 if (!strcmp(events_ops->name, kvm->report_event)) {
 133                         kvm->events_ops = events_ops->ops;
 134                         return true;
 135                 }
 136         }
 137 
 138         return false;
 139 }
 140 
 141 struct vcpu_event_record {
 142         int vcpu_id;
 143         u64 start_time;
 144         struct kvm_event *last_event;
 145 };
 146 
 147 
 148 static void init_kvm_event_record(struct perf_kvm_stat *kvm)
 149 {
 150         unsigned int i;
 151 
 152         for (i = 0; i < EVENTS_CACHE_SIZE; i++)
 153                 INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
 154 }
 155 
 156 #ifdef HAVE_TIMERFD_SUPPORT
 157 static void clear_events_cache_stats(struct list_head *kvm_events_cache)
 158 {
 159         struct list_head *head;
 160         struct kvm_event *event;
 161         unsigned int i;
 162         int j;
 163 
 164         for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
 165                 head = &kvm_events_cache[i];
 166                 list_for_each_entry(event, head, hash_entry) {
 167                         /* reset stats for event */
 168                         event->total.time = 0;
 169                         init_stats(&event->total.stats);
 170 
 171                         for (j = 0; j < event->max_vcpu; ++j) {
 172                                 event->vcpu[j].time = 0;
 173                                 init_stats(&event->vcpu[j].stats);
 174                         }
 175                 }
 176         }
 177 }
 178 #endif
 179 
 180 static int kvm_events_hash_fn(u64 key)
 181 {
 182         return key & (EVENTS_CACHE_SIZE - 1);
 183 }
 184 
 185 static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
 186 {
 187         int old_max_vcpu = event->max_vcpu;
 188         void *prev;
 189 
 190         if (vcpu_id < event->max_vcpu)
 191                 return true;
 192 
 193         while (event->max_vcpu <= vcpu_id)
 194                 event->max_vcpu += DEFAULT_VCPU_NUM;
 195 
 196         prev = event->vcpu;
 197         event->vcpu = realloc(event->vcpu,
 198                               event->max_vcpu * sizeof(*event->vcpu));
 199         if (!event->vcpu) {
 200                 free(prev);
 201                 pr_err("Not enough memory\n");
 202                 return false;
 203         }
 204 
 205         memset(event->vcpu + old_max_vcpu, 0,
 206                (event->max_vcpu - old_max_vcpu) * sizeof(*event->vcpu));
 207         return true;
 208 }
 209 
 210 static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
 211 {
 212         struct kvm_event *event;
 213 
 214         event = zalloc(sizeof(*event));
 215         if (!event) {
 216                 pr_err("Not enough memory\n");
 217                 return NULL;
 218         }
 219 
 220         event->key = *key;
 221         init_stats(&event->total.stats);
 222         return event;
 223 }
 224 
 225 static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
 226                                                struct event_key *key)
 227 {
 228         struct kvm_event *event;
 229         struct list_head *head;
 230 
 231         BUG_ON(key->key == INVALID_KEY);
 232 
 233         head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
 234         list_for_each_entry(event, head, hash_entry) {
 235                 if (event->key.key == key->key && event->key.info == key->info)
 236                         return event;
 237         }
 238 
 239         event = kvm_alloc_init_event(key);
 240         if (!event)
 241                 return NULL;
 242 
 243         list_add(&event->hash_entry, head);
 244         return event;
 245 }
 246 
 247 static bool handle_begin_event(struct perf_kvm_stat *kvm,
 248                                struct vcpu_event_record *vcpu_record,
 249                                struct event_key *key, u64 timestamp)
 250 {
 251         struct kvm_event *event = NULL;
 252 
 253         if (key->key != INVALID_KEY)
 254                 event = find_create_kvm_event(kvm, key);
 255 
 256         vcpu_record->last_event = event;
 257         vcpu_record->start_time = timestamp;
 258         return true;
 259 }
 260 
 261 static void
 262 kvm_update_event_stats(struct kvm_event_stats *kvm_stats, u64 time_diff)
 263 {
 264         kvm_stats->time += time_diff;
 265         update_stats(&kvm_stats->stats, time_diff);
 266 }
 267 
 268 static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event)
 269 {
 270         struct kvm_event_stats *kvm_stats = &event->total;
 271 
 272         if (vcpu_id != -1)
 273                 kvm_stats = &event->vcpu[vcpu_id];
 274 
 275         return rel_stddev_stats(stddev_stats(&kvm_stats->stats),
 276                                 avg_stats(&kvm_stats->stats));
 277 }
 278 
 279 static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
 280                              u64 time_diff)
 281 {
 282         if (vcpu_id == -1) {
 283                 kvm_update_event_stats(&event->total, time_diff);
 284                 return true;
 285         }
 286 
 287         if (!kvm_event_expand(event, vcpu_id))
 288                 return false;
 289 
 290         kvm_update_event_stats(&event->vcpu[vcpu_id], time_diff);
 291         return true;
 292 }
 293 
 294 static bool is_child_event(struct perf_kvm_stat *kvm,
 295                            struct evsel *evsel,
 296                            struct perf_sample *sample,
 297                            struct event_key *key)
 298 {
 299         struct child_event_ops *child_ops;
 300 
 301         child_ops = kvm->events_ops->child_ops;
 302 
 303         if (!child_ops)
 304                 return false;
 305 
 306         for (; child_ops->name; child_ops++) {
 307                 if (!strcmp(evsel->name, child_ops->name)) {
 308                         child_ops->get_key(evsel, sample, key);
 309                         return true;
 310                 }
 311         }
 312 
 313         return false;
 314 }
 315 
 316 static bool handle_child_event(struct perf_kvm_stat *kvm,
 317                                struct vcpu_event_record *vcpu_record,
 318                                struct event_key *key,
 319                                struct perf_sample *sample __maybe_unused)
 320 {
 321         struct kvm_event *event = NULL;
 322 
 323         if (key->key != INVALID_KEY)
 324                 event = find_create_kvm_event(kvm, key);
 325 
 326         vcpu_record->last_event = event;
 327 
 328         return true;
 329 }
 330 
 331 static bool skip_event(const char *event)
 332 {
 333         const char * const *skip_events;
 334 
 335         for (skip_events = kvm_skip_events; *skip_events; skip_events++)
 336                 if (!strcmp(event, *skip_events))
 337                         return true;
 338 
 339         return false;
 340 }
 341 
 342 static bool handle_end_event(struct perf_kvm_stat *kvm,
 343                              struct vcpu_event_record *vcpu_record,
 344                              struct event_key *key,
 345                              struct perf_sample *sample)
 346 {
 347         struct kvm_event *event;
 348         u64 time_begin, time_diff;
 349         int vcpu;
 350 
 351         if (kvm->trace_vcpu == -1)
 352                 vcpu = -1;
 353         else
 354                 vcpu = vcpu_record->vcpu_id;
 355 
 356         event = vcpu_record->last_event;
 357         time_begin = vcpu_record->start_time;
 358 
 359         /* The begin event is not caught. */
 360         if (!time_begin)
 361                 return true;
 362 
 363         /*
 364          * In some case, the 'begin event' only records the start timestamp,
 365          * the actual event is recognized in the 'end event' (e.g. mmio-event).
 366          */
 367 
 368         /* Both begin and end events did not get the key. */
 369         if (!event && key->key == INVALID_KEY)
 370                 return true;
 371 
 372         if (!event)
 373                 event = find_create_kvm_event(kvm, key);
 374 
 375         if (!event)
 376                 return false;
 377 
 378         vcpu_record->last_event = NULL;
 379         vcpu_record->start_time = 0;
 380 
 381         /* seems to happen once in a while during live mode */
 382         if (sample->time < time_begin) {
 383                 pr_debug("End time before begin time; skipping event.\n");
 384                 return true;
 385         }
 386 
 387         time_diff = sample->time - time_begin;
 388 
 389         if (kvm->duration && time_diff > kvm->duration) {
 390                 char decode[decode_str_len];
 391 
 392                 kvm->events_ops->decode_key(kvm, &event->key, decode);
 393                 if (!skip_event(decode)) {
 394                         pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n",
 395                                  sample->time, sample->pid, vcpu_record->vcpu_id,
 396                                  decode, time_diff / NSEC_PER_USEC);
 397                 }
 398         }
 399 
 400         return update_kvm_event(event, vcpu, time_diff);
 401 }
 402 
 403 static
 404 struct vcpu_event_record *per_vcpu_record(struct thread *thread,
 405                                           struct evsel *evsel,
 406                                           struct perf_sample *sample)
 407 {
 408         /* Only kvm_entry records vcpu id. */
 409         if (!thread__priv(thread) && kvm_entry_event(evsel)) {
 410                 struct vcpu_event_record *vcpu_record;
 411 
 412                 vcpu_record = zalloc(sizeof(*vcpu_record));
 413                 if (!vcpu_record) {
 414                         pr_err("%s: Not enough memory\n", __func__);
 415                         return NULL;
 416                 }
 417 
 418                 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample,
 419                                                           vcpu_id_str);
 420                 thread__set_priv(thread, vcpu_record);
 421         }
 422 
 423         return thread__priv(thread);
 424 }
 425 
 426 static bool handle_kvm_event(struct perf_kvm_stat *kvm,
 427                              struct thread *thread,
 428                              struct evsel *evsel,
 429                              struct perf_sample *sample)
 430 {
 431         struct vcpu_event_record *vcpu_record;
 432         struct event_key key = { .key = INVALID_KEY,
 433                                  .exit_reasons = kvm->exit_reasons };
 434 
 435         vcpu_record = per_vcpu_record(thread, evsel, sample);
 436         if (!vcpu_record)
 437                 return true;
 438 
 439         /* only process events for vcpus user cares about */
 440         if ((kvm->trace_vcpu != -1) &&
 441             (kvm->trace_vcpu != vcpu_record->vcpu_id))
 442                 return true;
 443 
 444         if (kvm->events_ops->is_begin_event(evsel, sample, &key))
 445                 return handle_begin_event(kvm, vcpu_record, &key, sample->time);
 446 
 447         if (is_child_event(kvm, evsel, sample, &key))
 448                 return handle_child_event(kvm, vcpu_record, &key, sample);
 449 
 450         if (kvm->events_ops->is_end_event(evsel, sample, &key))
 451                 return handle_end_event(kvm, vcpu_record, &key, sample);
 452 
 453         return true;
 454 }
 455 
 456 #define GET_EVENT_KEY(func, field)                                      \
 457 static u64 get_event_ ##func(struct kvm_event *event, int vcpu)         \
 458 {                                                                       \
 459         if (vcpu == -1)                                                 \
 460                 return event->total.field;                              \
 461                                                                         \
 462         if (vcpu >= event->max_vcpu)                                    \
 463                 return 0;                                               \
 464                                                                         \
 465         return event->vcpu[vcpu].field;                                 \
 466 }
 467 
 468 #define COMPARE_EVENT_KEY(func, field)                                  \
 469 GET_EVENT_KEY(func, field)                                              \
 470 static int compare_kvm_event_ ## func(struct kvm_event *one,            \
 471                                         struct kvm_event *two, int vcpu)\
 472 {                                                                       \
 473         return get_event_ ##func(one, vcpu) >                           \
 474                                 get_event_ ##func(two, vcpu);           \
 475 }
 476 
 477 GET_EVENT_KEY(time, time);
 478 COMPARE_EVENT_KEY(count, stats.n);
 479 COMPARE_EVENT_KEY(mean, stats.mean);
 480 GET_EVENT_KEY(max, stats.max);
 481 GET_EVENT_KEY(min, stats.min);
 482 
 483 #define DEF_SORT_NAME_KEY(name, compare_key)                            \
 484         { #name, compare_kvm_event_ ## compare_key }
 485 
 486 static struct kvm_event_key keys[] = {
 487         DEF_SORT_NAME_KEY(sample, count),
 488         DEF_SORT_NAME_KEY(time, mean),
 489         { NULL, NULL }
 490 };
 491 
 492 static bool select_key(struct perf_kvm_stat *kvm)
 493 {
 494         int i;
 495 
 496         for (i = 0; keys[i].name; i++) {
 497                 if (!strcmp(keys[i].name, kvm->sort_key)) {
 498                         kvm->compare = keys[i].key;
 499                         return true;
 500                 }
 501         }
 502 
 503         pr_err("Unknown compare key:%s\n", kvm->sort_key);
 504         return false;
 505 }
 506 
 507 static void insert_to_result(struct rb_root *result, struct kvm_event *event,
 508                              key_cmp_fun bigger, int vcpu)
 509 {
 510         struct rb_node **rb = &result->rb_node;
 511         struct rb_node *parent = NULL;
 512         struct kvm_event *p;
 513 
 514         while (*rb) {
 515                 p = container_of(*rb, struct kvm_event, rb);
 516                 parent = *rb;
 517 
 518                 if (bigger(event, p, vcpu))
 519                         rb = &(*rb)->rb_left;
 520                 else
 521                         rb = &(*rb)->rb_right;
 522         }
 523 
 524         rb_link_node(&event->rb, parent, rb);
 525         rb_insert_color(&event->rb, result);
 526 }
 527 
 528 static void
 529 update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
 530 {
 531         int vcpu = kvm->trace_vcpu;
 532 
 533         kvm->total_count += get_event_count(event, vcpu);
 534         kvm->total_time += get_event_time(event, vcpu);
 535 }
 536 
 537 static bool event_is_valid(struct kvm_event *event, int vcpu)
 538 {
 539         return !!get_event_count(event, vcpu);
 540 }
 541 
 542 static void sort_result(struct perf_kvm_stat *kvm)
 543 {
 544         unsigned int i;
 545         int vcpu = kvm->trace_vcpu;
 546         struct kvm_event *event;
 547 
 548         for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
 549                 list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) {
 550                         if (event_is_valid(event, vcpu)) {
 551                                 update_total_count(kvm, event);
 552                                 insert_to_result(&kvm->result, event,
 553                                                  kvm->compare, vcpu);
 554                         }
 555                 }
 556         }
 557 }
 558 
 559 /* returns left most element of result, and erase it */
 560 static struct kvm_event *pop_from_result(struct rb_root *result)
 561 {
 562         struct rb_node *node = rb_first(result);
 563 
 564         if (!node)
 565                 return NULL;
 566 
 567         rb_erase(node, result);
 568         return container_of(node, struct kvm_event, rb);
 569 }
 570 
 571 static void print_vcpu_info(struct perf_kvm_stat *kvm)
 572 {
 573         int vcpu = kvm->trace_vcpu;
 574 
 575         pr_info("Analyze events for ");
 576 
 577         if (kvm->opts.target.system_wide)
 578                 pr_info("all VMs, ");
 579         else if (kvm->opts.target.pid)
 580                 pr_info("pid(s) %s, ", kvm->opts.target.pid);
 581         else
 582                 pr_info("dazed and confused on what is monitored, ");
 583 
 584         if (vcpu == -1)
 585                 pr_info("all VCPUs:\n\n");
 586         else
 587                 pr_info("VCPU %d:\n\n", vcpu);
 588 }
 589 
 590 static void show_timeofday(void)
 591 {
 592         char date[64];
 593         struct timeval tv;
 594         struct tm ltime;
 595 
 596         gettimeofday(&tv, NULL);
 597         if (localtime_r(&tv.tv_sec, &ltime)) {
 598                 strftime(date, sizeof(date), "%H:%M:%S", &ltime);
 599                 pr_info("%s.%06ld", date, tv.tv_usec);
 600         } else
 601                 pr_info("00:00:00.000000");
 602 
 603         return;
 604 }
 605 
 606 static void print_result(struct perf_kvm_stat *kvm)
 607 {
 608         char decode[decode_str_len];
 609         struct kvm_event *event;
 610         int vcpu = kvm->trace_vcpu;
 611 
 612         if (kvm->live) {
 613                 puts(CONSOLE_CLEAR);
 614                 show_timeofday();
 615         }
 616 
 617         pr_info("\n\n");
 618         print_vcpu_info(kvm);
 619         pr_info("%*s ", decode_str_len, kvm->events_ops->name);
 620         pr_info("%10s ", "Samples");
 621         pr_info("%9s ", "Samples%");
 622 
 623         pr_info("%9s ", "Time%");
 624         pr_info("%11s ", "Min Time");
 625         pr_info("%11s ", "Max Time");
 626         pr_info("%16s ", "Avg time");
 627         pr_info("\n\n");
 628 
 629         while ((event = pop_from_result(&kvm->result))) {
 630                 u64 ecount, etime, max, min;
 631 
 632                 ecount = get_event_count(event, vcpu);
 633                 etime = get_event_time(event, vcpu);
 634                 max = get_event_max(event, vcpu);
 635                 min = get_event_min(event, vcpu);
 636 
 637                 kvm->events_ops->decode_key(kvm, &event->key, decode);
 638                 pr_info("%*s ", decode_str_len, decode);
 639                 pr_info("%10llu ", (unsigned long long)ecount);
 640                 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
 641                 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
 642                 pr_info("%9.2fus ", (double)min / NSEC_PER_USEC);
 643                 pr_info("%9.2fus ", (double)max / NSEC_PER_USEC);
 644                 pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount / NSEC_PER_USEC,
 645                         kvm_event_rel_stddev(vcpu, event));
 646                 pr_info("\n");
 647         }
 648 
 649         pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n",
 650                 kvm->total_count, kvm->total_time / (double)NSEC_PER_USEC);
 651 
 652         if (kvm->lost_events)
 653                 pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
 654 }
 655 
 656 #ifdef HAVE_TIMERFD_SUPPORT
 657 static int process_lost_event(struct perf_tool *tool,
 658                               union perf_event *event __maybe_unused,
 659                               struct perf_sample *sample __maybe_unused,
 660                               struct machine *machine __maybe_unused)
 661 {
 662         struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool);
 663 
 664         kvm->lost_events++;
 665         return 0;
 666 }
 667 #endif
 668 
 669 static bool skip_sample(struct perf_kvm_stat *kvm,
 670                         struct perf_sample *sample)
 671 {
 672         if (kvm->pid_list && intlist__find(kvm->pid_list, sample->pid) == NULL)
 673                 return true;
 674 
 675         return false;
 676 }
 677 
 678 static int process_sample_event(struct perf_tool *tool,
 679                                 union perf_event *event,
 680                                 struct perf_sample *sample,
 681                                 struct evsel *evsel,
 682                                 struct machine *machine)
 683 {
 684         int err = 0;
 685         struct thread *thread;
 686         struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat,
 687                                                  tool);
 688 
 689         if (skip_sample(kvm, sample))
 690                 return 0;
 691 
 692         thread = machine__findnew_thread(machine, sample->pid, sample->tid);
 693         if (thread == NULL) {
 694                 pr_debug("problem processing %d event, skipping it.\n",
 695                         event->header.type);
 696                 return -1;
 697         }
 698 
 699         if (!handle_kvm_event(kvm, thread, evsel, sample))
 700                 err = -1;
 701 
 702         thread__put(thread);
 703         return err;
 704 }
 705 
 706 static int cpu_isa_config(struct perf_kvm_stat *kvm)
 707 {
 708         char buf[128], *cpuid;
 709         int err;
 710 
 711         if (kvm->live) {
 712                 err = get_cpuid(buf, sizeof(buf));
 713                 if (err != 0) {
 714                         pr_err("Failed to look up CPU type: %s\n",
 715                                str_error_r(err, buf, sizeof(buf)));
 716                         return -err;
 717                 }
 718                 cpuid = buf;
 719         } else
 720                 cpuid = kvm->session->header.env.cpuid;
 721 
 722         if (!cpuid) {
 723                 pr_err("Failed to look up CPU type\n");
 724                 return -EINVAL;
 725         }
 726 
 727         err = cpu_isa_init(kvm, cpuid);
 728         if (err == -ENOTSUP)
 729                 pr_err("CPU %s is not supported.\n", cpuid);
 730 
 731         return err;
 732 }
 733 
 734 static bool verify_vcpu(int vcpu)
 735 {
 736         if (vcpu != -1 && vcpu < 0) {
 737                 pr_err("Invalid vcpu:%d.\n", vcpu);
 738                 return false;
 739         }
 740 
 741         return true;
 742 }
 743 
 744 #ifdef HAVE_TIMERFD_SUPPORT
 745 /* keeping the max events to a modest level to keep
 746  * the processing of samples per mmap smooth.
 747  */
 748 #define PERF_KVM__MAX_EVENTS_PER_MMAP  25
 749 
 750 static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
 751                                    u64 *mmap_time)
 752 {
 753         struct evlist *evlist = kvm->evlist;
 754         union perf_event *event;
 755         struct mmap *md;
 756         u64 timestamp;
 757         s64 n = 0;
 758         int err;
 759 
 760         *mmap_time = ULLONG_MAX;
 761         md = &evlist->mmap[idx];
 762         err = perf_mmap__read_init(md);
 763         if (err < 0)
 764                 return (err == -EAGAIN) ? 0 : -1;
 765 
 766         while ((event = perf_mmap__read_event(md)) != NULL) {
 767                 err = perf_evlist__parse_sample_timestamp(evlist, event, &timestamp);
 768                 if (err) {
 769                         perf_mmap__consume(md);
 770                         pr_err("Failed to parse sample\n");
 771                         return -1;
 772                 }
 773 
 774                 err = perf_session__queue_event(kvm->session, event, timestamp, 0);
 775                 /*
 776                  * FIXME: Here we can't consume the event, as perf_session__queue_event will
 777                  *        point to it, and it'll get possibly overwritten by the kernel.
 778                  */
 779                 perf_mmap__consume(md);
 780 
 781                 if (err) {
 782                         pr_err("Failed to enqueue sample: %d\n", err);
 783                         return -1;
 784                 }
 785 
 786                 /* save time stamp of our first sample for this mmap */
 787                 if (n == 0)
 788                         *mmap_time = timestamp;
 789 
 790                 /* limit events per mmap handled all at once */
 791                 n++;
 792                 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
 793                         break;
 794         }
 795 
 796         perf_mmap__read_done(md);
 797         return n;
 798 }
 799 
 800 static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
 801 {
 802         int i, err, throttled = 0;
 803         s64 n, ntotal = 0;
 804         u64 flush_time = ULLONG_MAX, mmap_time;
 805 
 806         for (i = 0; i < kvm->evlist->core.nr_mmaps; i++) {
 807                 n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time);
 808                 if (n < 0)
 809                         return -1;
 810 
 811                 /* flush time is going to be the minimum of all the individual
 812                  * mmap times. Essentially, we flush all the samples queued up
 813                  * from the last pass under our minimal start time -- that leaves
 814                  * a very small race for samples to come in with a lower timestamp.
 815                  * The ioctl to return the perf_clock timestamp should close the
 816                  * race entirely.
 817                  */
 818                 if (mmap_time < flush_time)
 819                         flush_time = mmap_time;
 820 
 821                 ntotal += n;
 822                 if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
 823                         throttled = 1;
 824         }
 825 
 826         /* flush queue after each round in which we processed events */
 827         if (ntotal) {
 828                 struct ordered_events *oe = &kvm->session->ordered_events;
 829 
 830                 oe->next_flush = flush_time;
 831                 err = ordered_events__flush(oe, OE_FLUSH__ROUND);
 832                 if (err) {
 833                         if (kvm->lost_events)
 834                                 pr_info("\nLost events: %" PRIu64 "\n\n",
 835                                         kvm->lost_events);
 836                         return err;
 837                 }
 838         }
 839 
 840         return throttled;
 841 }
 842 
 843 static volatile int done;
 844 
 845 static void sig_handler(int sig __maybe_unused)
 846 {
 847         done = 1;
 848 }
 849 
 850 static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
 851 {
 852         struct itimerspec new_value;
 853         int rc = -1;
 854 
 855         kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
 856         if (kvm->timerfd < 0) {
 857                 pr_err("timerfd_create failed\n");
 858                 goto out;
 859         }
 860 
 861         new_value.it_value.tv_sec = kvm->display_time;
 862         new_value.it_value.tv_nsec = 0;
 863         new_value.it_interval.tv_sec = kvm->display_time;
 864         new_value.it_interval.tv_nsec = 0;
 865 
 866         if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) {
 867                 pr_err("timerfd_settime failed: %d\n", errno);
 868                 close(kvm->timerfd);
 869                 goto out;
 870         }
 871 
 872         rc = 0;
 873 out:
 874         return rc;
 875 }
 876 
 877 static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
 878 {
 879         uint64_t c;
 880         int rc;
 881 
 882         rc = read(kvm->timerfd, &c, sizeof(uint64_t));
 883         if (rc < 0) {
 884                 if (errno == EAGAIN)
 885                         return 0;
 886 
 887                 pr_err("Failed to read timer fd: %d\n", errno);
 888                 return -1;
 889         }
 890 
 891         if (rc != sizeof(uint64_t)) {
 892                 pr_err("Error reading timer fd - invalid size returned\n");
 893                 return -1;
 894         }
 895 
 896         if (c != 1)
 897                 pr_debug("Missed timer beats: %" PRIu64 "\n", c-1);
 898 
 899         /* update display */
 900         sort_result(kvm);
 901         print_result(kvm);
 902 
 903         /* reset counts */
 904         clear_events_cache_stats(kvm->kvm_events_cache);
 905         kvm->total_count = 0;
 906         kvm->total_time = 0;
 907         kvm->lost_events = 0;
 908 
 909         return 0;
 910 }
 911 
 912 static int fd_set_nonblock(int fd)
 913 {
 914         long arg = 0;
 915 
 916         arg = fcntl(fd, F_GETFL);
 917         if (arg < 0) {
 918                 pr_err("Failed to get current flags for fd %d\n", fd);
 919                 return -1;
 920         }
 921 
 922         if (fcntl(fd, F_SETFL, arg | O_NONBLOCK) < 0) {
 923                 pr_err("Failed to set non-block option on fd %d\n", fd);
 924                 return -1;
 925         }
 926 
 927         return 0;
 928 }
 929 
 930 static int perf_kvm__handle_stdin(void)
 931 {
 932         int c;
 933 
 934         c = getc(stdin);
 935         if (c == 'q')
 936                 return 1;
 937 
 938         return 0;
 939 }
 940 
 941 static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 942 {
 943         int nr_stdin, ret, err = -EINVAL;
 944         struct termios save;
 945 
 946         /* live flag must be set first */
 947         kvm->live = true;
 948 
 949         ret = cpu_isa_config(kvm);
 950         if (ret < 0)
 951                 return ret;
 952 
 953         if (!verify_vcpu(kvm->trace_vcpu) ||
 954             !select_key(kvm) ||
 955             !register_kvm_events_ops(kvm)) {
 956                 goto out;
 957         }
 958 
 959         set_term_quiet_input(&save);
 960         init_kvm_event_record(kvm);
 961 
 962         signal(SIGINT, sig_handler);
 963         signal(SIGTERM, sig_handler);
 964 
 965         /* add timer fd */
 966         if (perf_kvm__timerfd_create(kvm) < 0) {
 967                 err = -1;
 968                 goto out;
 969         }
 970 
 971         if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
 972                 goto out;
 973 
 974         nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin));
 975         if (nr_stdin < 0)
 976                 goto out;
 977 
 978         if (fd_set_nonblock(fileno(stdin)) != 0)
 979                 goto out;
 980 
 981         /* everything is good - enable the events and process */
 982         evlist__enable(kvm->evlist);
 983 
 984         while (!done) {
 985                 struct fdarray *fda = &kvm->evlist->core.pollfd;
 986                 int rc;
 987 
 988                 rc = perf_kvm__mmap_read(kvm);
 989                 if (rc < 0)
 990                         break;
 991 
 992                 err = perf_kvm__handle_timerfd(kvm);
 993                 if (err)
 994                         goto out;
 995 
 996                 if (fda->entries[nr_stdin].revents & POLLIN)
 997                         done = perf_kvm__handle_stdin();
 998 
 999                 if (!rc && !done)
1000                         err = fdarray__poll(fda, 100);
1001         }
1002 
1003         evlist__disable(kvm->evlist);
1004 
1005         if (err == 0) {
1006                 sort_result(kvm);
1007                 print_result(kvm);
1008         }
1009 
1010 out:
1011         if (kvm->timerfd >= 0)
1012                 close(kvm->timerfd);
1013 
1014         tcsetattr(0, TCSAFLUSH, &save);
1015         return err;
1016 }
1017 
1018 static int kvm_live_open_events(struct perf_kvm_stat *kvm)
1019 {
1020         int err, rc = -1;
1021         struct evsel *pos;
1022         struct evlist *evlist = kvm->evlist;
1023         char sbuf[STRERR_BUFSIZE];
1024 
1025         perf_evlist__config(evlist, &kvm->opts, NULL);
1026 
1027         /*
1028          * Note: exclude_{guest,host} do not apply here.
1029          *       This command processes KVM tracepoints from host only
1030          */
1031         evlist__for_each_entry(evlist, pos) {
1032                 struct perf_event_attr *attr = &pos->core.attr;
1033 
1034                 /* make sure these *are* set */
1035                 perf_evsel__set_sample_bit(pos, TID);
1036                 perf_evsel__set_sample_bit(pos, TIME);
1037                 perf_evsel__set_sample_bit(pos, CPU);
1038                 perf_evsel__set_sample_bit(pos, RAW);
1039                 /* make sure these are *not*; want as small a sample as possible */
1040                 perf_evsel__reset_sample_bit(pos, PERIOD);
1041                 perf_evsel__reset_sample_bit(pos, IP);
1042                 perf_evsel__reset_sample_bit(pos, CALLCHAIN);
1043                 perf_evsel__reset_sample_bit(pos, ADDR);
1044                 perf_evsel__reset_sample_bit(pos, READ);
1045                 attr->mmap = 0;
1046                 attr->comm = 0;
1047                 attr->task = 0;
1048 
1049                 attr->sample_period = 1;
1050 
1051                 attr->watermark = 0;
1052                 attr->wakeup_events = 1000;
1053 
1054                 /* will enable all once we are ready */
1055                 attr->disabled = 1;
1056         }
1057 
1058         err = evlist__open(evlist);
1059         if (err < 0) {
1060                 printf("Couldn't create the events: %s\n",
1061                        str_error_r(errno, sbuf, sizeof(sbuf)));
1062                 goto out;
1063         }
1064 
1065         if (evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) {
1066                 ui__error("Failed to mmap the events: %s\n",
1067                           str_error_r(errno, sbuf, sizeof(sbuf)));
1068                 evlist__close(evlist);
1069                 goto out;
1070         }
1071 
1072         rc = 0;
1073 
1074 out:
1075         return rc;
1076 }
1077 #endif
1078 
1079 static int read_events(struct perf_kvm_stat *kvm)
1080 {
1081         int ret;
1082 
1083         struct perf_tool eops = {
1084                 .sample                 = process_sample_event,
1085                 .comm                   = perf_event__process_comm,
1086                 .namespaces             = perf_event__process_namespaces,
1087                 .ordered_events         = true,
1088         };
1089         struct perf_data file = {
1090                 .path  = kvm->file_name,
1091                 .mode  = PERF_DATA_MODE_READ,
1092                 .force = kvm->force,
1093         };
1094 
1095         kvm->tool = eops;
1096         kvm->session = perf_session__new(&file, false, &kvm->tool);
1097         if (IS_ERR(kvm->session)) {
1098                 pr_err("Initializing perf session failed\n");
1099                 return PTR_ERR(kvm->session);
1100         }
1101 
1102         symbol__init(&kvm->session->header.env);
1103 
1104         if (!perf_session__has_traces(kvm->session, "kvm record")) {
1105                 ret = -EINVAL;
1106                 goto out_delete;
1107         }
1108 
1109         /*
1110          * Do not use 'isa' recorded in kvm_exit tracepoint since it is not
1111          * traced in the old kernel.
1112          */
1113         ret = cpu_isa_config(kvm);
1114         if (ret < 0)
1115                 goto out_delete;
1116 
1117         ret = perf_session__process_events(kvm->session);
1118 
1119 out_delete:
1120         perf_session__delete(kvm->session);
1121         return ret;
1122 }
1123 
1124 static int parse_target_str(struct perf_kvm_stat *kvm)
1125 {
1126         if (kvm->opts.target.pid) {
1127                 kvm->pid_list = intlist__new(kvm->opts.target.pid);
1128                 if (kvm->pid_list == NULL) {
1129                         pr_err("Error parsing process id string\n");
1130                         return -EINVAL;
1131                 }
1132         }
1133 
1134         return 0;
1135 }
1136 
1137 static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
1138 {
1139         int ret = -EINVAL;
1140         int vcpu = kvm->trace_vcpu;
1141 
1142         if (parse_target_str(kvm) != 0)
1143                 goto exit;
1144 
1145         if (!verify_vcpu(vcpu))
1146                 goto exit;
1147 
1148         if (!select_key(kvm))
1149                 goto exit;
1150 
1151         if (!register_kvm_events_ops(kvm))
1152                 goto exit;
1153 
1154         init_kvm_event_record(kvm);
1155         setup_pager();
1156 
1157         ret = read_events(kvm);
1158         if (ret)
1159                 goto exit;
1160 
1161         sort_result(kvm);
1162         print_result(kvm);
1163 
1164 exit:
1165         return ret;
1166 }
1167 
1168 #define STRDUP_FAIL_EXIT(s)             \
1169         ({      char *_p;               \
1170         _p = strdup(s);         \
1171                 if (!_p)                \
1172                         return -ENOMEM; \
1173                 _p;                     \
1174         })
1175 
1176 int __weak setup_kvm_events_tp(struct perf_kvm_stat *kvm __maybe_unused)
1177 {
1178         return 0;
1179 }
1180 
1181 static int
1182 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
1183 {
1184         unsigned int rec_argc, i, j, events_tp_size;
1185         const char **rec_argv;
1186         const char * const record_args[] = {
1187                 "record",
1188                 "-R",
1189                 "-m", "1024",
1190                 "-c", "1",
1191         };
1192         const char * const kvm_stat_record_usage[] = {
1193                 "perf kvm stat record [<options>]",
1194                 NULL
1195         };
1196         const char * const *events_tp;
1197         int ret;
1198 
1199         events_tp_size = 0;
1200         ret = setup_kvm_events_tp(kvm);
1201         if (ret < 0) {
1202                 pr_err("Unable to setup the kvm tracepoints\n");
1203                 return ret;
1204         }
1205 
1206         for (events_tp = kvm_events_tp; *events_tp; events_tp++)
1207                 events_tp_size++;
1208 
1209         rec_argc = ARRAY_SIZE(record_args) + argc + 2 +
1210                    2 * events_tp_size;
1211         rec_argv = calloc(rec_argc + 1, sizeof(char *));
1212 
1213         if (rec_argv == NULL)
1214                 return -ENOMEM;
1215 
1216         for (i = 0; i < ARRAY_SIZE(record_args); i++)
1217                 rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
1218 
1219         for (j = 0; j < events_tp_size; j++) {
1220                 rec_argv[i++] = "-e";
1221                 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp[j]);
1222         }
1223 
1224         rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
1225         rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
1226 
1227         for (j = 1; j < (unsigned int)argc; j++, i++)
1228                 rec_argv[i] = argv[j];
1229 
1230         set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN);
1231         set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN);
1232         set_option_flag(record_options, 'R', "raw-samples", PARSE_OPT_HIDDEN);
1233 
1234         set_option_flag(record_options, 'F', "freq", PARSE_OPT_DISABLED);
1235         set_option_flag(record_options, 0, "group", PARSE_OPT_DISABLED);
1236         set_option_flag(record_options, 'g', NULL, PARSE_OPT_DISABLED);
1237         set_option_flag(record_options, 0, "call-graph", PARSE_OPT_DISABLED);
1238         set_option_flag(record_options, 'd', "data", PARSE_OPT_DISABLED);
1239         set_option_flag(record_options, 'T', "timestamp", PARSE_OPT_DISABLED);
1240         set_option_flag(record_options, 'P', "period", PARSE_OPT_DISABLED);
1241         set_option_flag(record_options, 'n', "no-samples", PARSE_OPT_DISABLED);
1242         set_option_flag(record_options, 'N', "no-buildid-cache", PARSE_OPT_DISABLED);
1243         set_option_flag(record_options, 'B', "no-buildid", PARSE_OPT_DISABLED);
1244         set_option_flag(record_options, 'G', "cgroup", PARSE_OPT_DISABLED);
1245         set_option_flag(record_options, 'b', "branch-any", PARSE_OPT_DISABLED);
1246         set_option_flag(record_options, 'j', "branch-filter", PARSE_OPT_DISABLED);
1247         set_option_flag(record_options, 'W', "weight", PARSE_OPT_DISABLED);
1248         set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED);
1249 
1250         record_usage = kvm_stat_record_usage;
1251         return cmd_record(i, rec_argv);
1252 }
1253 
1254 static int
1255 kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1256 {
1257         const struct option kvm_events_report_options[] = {
1258                 OPT_STRING(0, "event", &kvm->report_event, "report event",
1259                            "event for reporting: vmexit, "
1260                            "mmio (x86 only), ioport (x86 only)"),
1261                 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
1262                             "vcpu id to report"),
1263                 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1264                             "key for sorting: sample(sort by samples number)"
1265                             " time (sort by avg time)"),
1266                 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1267                            "analyze events only for given process id(s)"),
1268                 OPT_BOOLEAN('f', "force", &kvm->force, "don't complain, do it"),
1269                 OPT_END()
1270         };
1271 
1272         const char * const kvm_events_report_usage[] = {
1273                 "perf kvm stat report [<options>]",
1274                 NULL
1275         };
1276 
1277         if (argc) {
1278                 argc = parse_options(argc, argv,
1279                                      kvm_events_report_options,
1280                                      kvm_events_report_usage, 0);
1281                 if (argc)
1282                         usage_with_options(kvm_events_report_usage,
1283                                            kvm_events_report_options);
1284         }
1285 
1286         if (!kvm->opts.target.pid)
1287                 kvm->opts.target.system_wide = true;
1288 
1289         return kvm_events_report_vcpu(kvm);
1290 }
1291 
1292 #ifdef HAVE_TIMERFD_SUPPORT
1293 static struct evlist *kvm_live_event_list(void)
1294 {
1295         struct evlist *evlist;
1296         char *tp, *name, *sys;
1297         int err = -1;
1298         const char * const *events_tp;
1299 
1300         evlist = evlist__new();
1301         if (evlist == NULL)
1302                 return NULL;
1303 
1304         for (events_tp = kvm_events_tp; *events_tp; events_tp++) {
1305 
1306                 tp = strdup(*events_tp);
1307                 if (tp == NULL)
1308                         goto out;
1309 
1310                 /* split tracepoint into subsystem and name */
1311                 sys = tp;
1312                 name = strchr(tp, ':');
1313                 if (name == NULL) {
1314                         pr_err("Error parsing %s tracepoint: subsystem delimiter not found\n",
1315                                *events_tp);
1316                         free(tp);
1317                         goto out;
1318                 }
1319                 *name = '\0';
1320                 name++;
1321 
1322                 if (perf_evlist__add_newtp(evlist, sys, name, NULL)) {
1323                         pr_err("Failed to add %s tracepoint to the list\n", *events_tp);
1324                         free(tp);
1325                         goto out;
1326                 }
1327 
1328                 free(tp);
1329         }
1330 
1331         err = 0;
1332 
1333 out:
1334         if (err) {
1335                 evlist__delete(evlist);
1336                 evlist = NULL;
1337         }
1338 
1339         return evlist;
1340 }
1341 
1342 static int kvm_events_live(struct perf_kvm_stat *kvm,
1343                            int argc, const char **argv)
1344 {
1345         char errbuf[BUFSIZ];
1346         int err;
1347 
1348         const struct option live_options[] = {
1349                 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1350                         "record events on existing process id"),
1351                 OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages",
1352                         "number of mmap data pages",
1353                         perf_evlist__parse_mmap_pages),
1354                 OPT_INCR('v', "verbose", &verbose,
1355                         "be more verbose (show counter open errors, etc)"),
1356                 OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
1357                         "system-wide collection from all CPUs"),
1358                 OPT_UINTEGER('d', "display", &kvm->display_time,
1359                         "time in seconds between display updates"),
1360                 OPT_STRING(0, "event", &kvm->report_event, "report event",
1361                         "event for reporting: "
1362                         "vmexit, mmio (x86 only), ioport (x86 only)"),
1363                 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
1364                         "vcpu id to report"),
1365                 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1366                         "key for sorting: sample(sort by samples number)"
1367                         " time (sort by avg time)"),
1368                 OPT_U64(0, "duration", &kvm->duration,
1369                         "show events other than"
1370                         " HLT (x86 only) or Wait state (s390 only)"
1371                         " that take longer than duration usecs"),
1372                 OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout,
1373                                 "per thread proc mmap processing timeout in ms"),
1374                 OPT_END()
1375         };
1376         const char * const live_usage[] = {
1377                 "perf kvm stat live [<options>]",
1378                 NULL
1379         };
1380         struct perf_data data = {
1381                 .mode = PERF_DATA_MODE_WRITE,
1382         };
1383 
1384 
1385         /* event handling */
1386         kvm->tool.sample = process_sample_event;
1387         kvm->tool.comm   = perf_event__process_comm;
1388         kvm->tool.exit   = perf_event__process_exit;
1389         kvm->tool.fork   = perf_event__process_fork;
1390         kvm->tool.lost   = process_lost_event;
1391         kvm->tool.namespaces  = perf_event__process_namespaces;
1392         kvm->tool.ordered_events = true;
1393         perf_tool__fill_defaults(&kvm->tool);
1394 
1395         /* set defaults */
1396         kvm->display_time = 1;
1397         kvm->opts.user_interval = 1;
1398         kvm->opts.mmap_pages = 512;
1399         kvm->opts.target.uses_mmap = false;
1400         kvm->opts.target.uid_str = NULL;
1401         kvm->opts.target.uid = UINT_MAX;
1402 
1403         symbol__init(NULL);
1404         disable_buildid_cache();
1405 
1406         use_browser = 0;
1407 
1408         if (argc) {
1409                 argc = parse_options(argc, argv, live_options,
1410                                      live_usage, 0);
1411                 if (argc)
1412                         usage_with_options(live_usage, live_options);
1413         }
1414 
1415         kvm->duration *= NSEC_PER_USEC;   /* convert usec to nsec */
1416 
1417         /*
1418          * target related setups
1419          */
1420         err = target__validate(&kvm->opts.target);
1421         if (err) {
1422                 target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
1423                 ui__warning("%s", errbuf);
1424         }
1425 
1426         if (target__none(&kvm->opts.target))
1427                 kvm->opts.target.system_wide = true;
1428 
1429 
1430         /*
1431          * generate the event list
1432          */
1433         err = setup_kvm_events_tp(kvm);
1434         if (err < 0) {
1435                 pr_err("Unable to setup the kvm tracepoints\n");
1436                 return err;
1437         }
1438 
1439         kvm->evlist = kvm_live_event_list();
1440         if (kvm->evlist == NULL) {
1441                 err = -1;
1442                 goto out;
1443         }
1444 
1445         if (perf_evlist__create_maps(kvm->evlist, &kvm->opts.target) < 0)
1446                 usage_with_options(live_usage, live_options);
1447 
1448         /*
1449          * perf session
1450          */
1451         kvm->session = perf_session__new(&data, false, &kvm->tool);
1452         if (IS_ERR(kvm->session)) {
1453                 err = PTR_ERR(kvm->session);
1454                 goto out;
1455         }
1456         kvm->session->evlist = kvm->evlist;
1457         perf_session__set_id_hdr_size(kvm->session);
1458         ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true);
1459         machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
1460                                     kvm->evlist->core.threads, false, 1);
1461         err = kvm_live_open_events(kvm);
1462         if (err)
1463                 goto out;
1464 
1465         err = kvm_events_live_report(kvm);
1466 
1467 out:
1468         perf_session__delete(kvm->session);
1469         kvm->session = NULL;
1470         evlist__delete(kvm->evlist);
1471 
1472         return err;
1473 }
1474 #endif
1475 
1476 static void print_kvm_stat_usage(void)
1477 {
1478         printf("Usage: perf kvm stat <command>\n\n");
1479 
1480         printf("# Available commands:\n");
1481         printf("\trecord: record kvm events\n");
1482         printf("\treport: report statistical data of kvm events\n");
1483         printf("\tlive:   live reporting of statistical data of kvm events\n");
1484 
1485         printf("\nOtherwise, it is the alias of 'perf stat':\n");
1486 }
1487 
1488 static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
1489 {
1490         struct perf_kvm_stat kvm = {
1491                 .file_name = file_name,
1492 
1493                 .trace_vcpu     = -1,
1494                 .report_event   = "vmexit",
1495                 .sort_key       = "sample",
1496 
1497         };
1498 
1499         if (argc == 1) {
1500                 print_kvm_stat_usage();
1501                 goto perf_stat;
1502         }
1503 
1504         if (!strncmp(argv[1], "rec", 3))
1505                 return kvm_events_record(&kvm, argc - 1, argv + 1);
1506 
1507         if (!strncmp(argv[1], "rep", 3))
1508                 return kvm_events_report(&kvm, argc - 1 , argv + 1);
1509 
1510 #ifdef HAVE_TIMERFD_SUPPORT
1511         if (!strncmp(argv[1], "live", 4))
1512                 return kvm_events_live(&kvm, argc - 1 , argv + 1);
1513 #endif
1514 
1515 perf_stat:
1516         return cmd_stat(argc, argv);
1517 }
1518 #endif /* HAVE_KVM_STAT_SUPPORT */
1519 
1520 int __weak kvm_add_default_arch_event(int *argc __maybe_unused,
1521                                         const char **argv __maybe_unused)
1522 {
1523         return 0;
1524 }
1525 
1526 static int __cmd_record(const char *file_name, int argc, const char **argv)
1527 {
1528         int rec_argc, i = 0, j, ret;
1529         const char **rec_argv;
1530 
1531         ret = kvm_add_default_arch_event(&argc, argv);
1532         if (ret)
1533                 return -EINVAL;
1534 
1535         rec_argc = argc + 2;
1536         rec_argv = calloc(rec_argc + 1, sizeof(char *));
1537         rec_argv[i++] = strdup("record");
1538         rec_argv[i++] = strdup("-o");
1539         rec_argv[i++] = strdup(file_name);
1540         for (j = 1; j < argc; j++, i++)
1541                 rec_argv[i] = argv[j];
1542 
1543         BUG_ON(i != rec_argc);
1544 
1545         return cmd_record(i, rec_argv);
1546 }
1547 
1548 static int __cmd_report(const char *file_name, int argc, const char **argv)
1549 {
1550         int rec_argc, i = 0, j;
1551         const char **rec_argv;
1552 
1553         rec_argc = argc + 2;
1554         rec_argv = calloc(rec_argc + 1, sizeof(char *));
1555         rec_argv[i++] = strdup("report");
1556         rec_argv[i++] = strdup("-i");
1557         rec_argv[i++] = strdup(file_name);
1558         for (j = 1; j < argc; j++, i++)
1559                 rec_argv[i] = argv[j];
1560 
1561         BUG_ON(i != rec_argc);
1562 
1563         return cmd_report(i, rec_argv);
1564 }
1565 
1566 static int
1567 __cmd_buildid_list(const char *file_name, int argc, const char **argv)
1568 {
1569         int rec_argc, i = 0, j;
1570         const char **rec_argv;
1571 
1572         rec_argc = argc + 2;
1573         rec_argv = calloc(rec_argc + 1, sizeof(char *));
1574         rec_argv[i++] = strdup("buildid-list");
1575         rec_argv[i++] = strdup("-i");
1576         rec_argv[i++] = strdup(file_name);
1577         for (j = 1; j < argc; j++, i++)
1578                 rec_argv[i] = argv[j];
1579 
1580         BUG_ON(i != rec_argc);
1581 
1582         return cmd_buildid_list(i, rec_argv);
1583 }
1584 
1585 int cmd_kvm(int argc, const char **argv)
1586 {
1587         const char *file_name = NULL;
1588         const struct option kvm_options[] = {
1589                 OPT_STRING('i', "input", &file_name, "file",
1590                            "Input file name"),
1591                 OPT_STRING('o', "output", &file_name, "file",
1592                            "Output file name"),
1593                 OPT_BOOLEAN(0, "guest", &perf_guest,
1594                             "Collect guest os data"),
1595                 OPT_BOOLEAN(0, "host", &perf_host,
1596                             "Collect host os data"),
1597                 OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
1598                            "guest mount directory under which every guest os"
1599                            " instance has a subdir"),
1600                 OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
1601                            "file", "file saving guest os vmlinux"),
1602                 OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
1603                            "file", "file saving guest os /proc/kallsyms"),
1604                 OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
1605                            "file", "file saving guest os /proc/modules"),
1606                 OPT_INCR('v', "verbose", &verbose,
1607                             "be more verbose (show counter open errors, etc)"),
1608                 OPT_END()
1609         };
1610 
1611         const char *const kvm_subcommands[] = { "top", "record", "report", "diff",
1612                                                 "buildid-list", "stat", NULL };
1613         const char *kvm_usage[] = { NULL, NULL };
1614 
1615         perf_host  = 0;
1616         perf_guest = 1;
1617 
1618         argc = parse_options_subcommand(argc, argv, kvm_options, kvm_subcommands, kvm_usage,
1619                                         PARSE_OPT_STOP_AT_NON_OPTION);
1620         if (!argc)
1621                 usage_with_options(kvm_usage, kvm_options);
1622 
1623         if (!perf_host)
1624                 perf_guest = 1;
1625 
1626         if (!file_name) {
1627                 file_name = get_filename_for_perf_kvm();
1628 
1629                 if (!file_name) {
1630                         pr_err("Failed to allocate memory for filename\n");
1631                         return -ENOMEM;
1632                 }
1633         }
1634 
1635         if (!strncmp(argv[0], "rec", 3))
1636                 return __cmd_record(file_name, argc, argv);
1637         else if (!strncmp(argv[0], "rep", 3))
1638                 return __cmd_report(file_name, argc, argv);
1639         else if (!strncmp(argv[0], "diff", 4))
1640                 return cmd_diff(argc, argv);
1641         else if (!strncmp(argv[0], "top", 3))
1642                 return cmd_top(argc, argv);
1643         else if (!strncmp(argv[0], "buildid-list", 12))
1644                 return __cmd_buildid_list(file_name, argc, argv);
1645 #ifdef HAVE_KVM_STAT_SUPPORT
1646         else if (!strncmp(argv[0], "stat", 4))
1647                 return kvm_cmd_stat(file_name, argc, argv);
1648 #endif
1649         else
1650                 usage_with_options(kvm_usage, kvm_options);
1651 
1652         return 0;
1653 }

/* [<][>][^][v][top][bottom][index][help] */