diff options
Diffstat (limited to 'tools/perf/builtin-kvm.c')
-rw-r--r-- | tools/perf/builtin-kvm.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index fbc2888d6495..f8bf5f244d77 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -17,9 +17,12 @@ | |||
17 | #include "util/tool.h" | 17 | #include "util/tool.h" |
18 | #include "util/stat.h" | 18 | #include "util/stat.h" |
19 | #include "util/top.h" | 19 | #include "util/top.h" |
20 | #include "util/data.h" | ||
20 | 21 | ||
21 | #include <sys/prctl.h> | 22 | #include <sys/prctl.h> |
23 | #ifdef HAVE_TIMERFD_SUPPORT | ||
22 | #include <sys/timerfd.h> | 24 | #include <sys/timerfd.h> |
25 | #endif | ||
23 | 26 | ||
24 | #include <termios.h> | 27 | #include <termios.h> |
25 | #include <semaphore.h> | 28 | #include <semaphore.h> |
@@ -336,6 +339,7 @@ static void init_kvm_event_record(struct perf_kvm_stat *kvm) | |||
336 | INIT_LIST_HEAD(&kvm->kvm_events_cache[i]); | 339 | INIT_LIST_HEAD(&kvm->kvm_events_cache[i]); |
337 | } | 340 | } |
338 | 341 | ||
342 | #ifdef HAVE_TIMERFD_SUPPORT | ||
339 | static void clear_events_cache_stats(struct list_head *kvm_events_cache) | 343 | static void clear_events_cache_stats(struct list_head *kvm_events_cache) |
340 | { | 344 | { |
341 | struct list_head *head; | 345 | struct list_head *head; |
@@ -357,6 +361,7 @@ static void clear_events_cache_stats(struct list_head *kvm_events_cache) | |||
357 | } | 361 | } |
358 | } | 362 | } |
359 | } | 363 | } |
364 | #endif | ||
360 | 365 | ||
361 | static int kvm_events_hash_fn(u64 key) | 366 | static int kvm_events_hash_fn(u64 key) |
362 | { | 367 | { |
@@ -782,6 +787,7 @@ static void print_result(struct perf_kvm_stat *kvm) | |||
782 | pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events); | 787 | pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events); |
783 | } | 788 | } |
784 | 789 | ||
790 | #ifdef HAVE_TIMERFD_SUPPORT | ||
785 | static int process_lost_event(struct perf_tool *tool, | 791 | static int process_lost_event(struct perf_tool *tool, |
786 | union perf_event *event __maybe_unused, | 792 | union perf_event *event __maybe_unused, |
787 | struct perf_sample *sample __maybe_unused, | 793 | struct perf_sample *sample __maybe_unused, |
@@ -792,6 +798,7 @@ static int process_lost_event(struct perf_tool *tool, | |||
792 | kvm->lost_events++; | 798 | kvm->lost_events++; |
793 | return 0; | 799 | return 0; |
794 | } | 800 | } |
801 | #endif | ||
795 | 802 | ||
796 | static bool skip_sample(struct perf_kvm_stat *kvm, | 803 | static bool skip_sample(struct perf_kvm_stat *kvm, |
797 | struct perf_sample *sample) | 804 | struct perf_sample *sample) |
@@ -871,6 +878,7 @@ static bool verify_vcpu(int vcpu) | |||
871 | return true; | 878 | return true; |
872 | } | 879 | } |
873 | 880 | ||
881 | #ifdef HAVE_TIMERFD_SUPPORT | ||
874 | /* keeping the max events to a modest level to keep | 882 | /* keeping the max events to a modest level to keep |
875 | * the processing of samples per mmap smooth. | 883 | * the processing of samples per mmap smooth. |
876 | */ | 884 | */ |
@@ -1212,6 +1220,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) | |||
1212 | out: | 1220 | out: |
1213 | return rc; | 1221 | return rc; |
1214 | } | 1222 | } |
1223 | #endif | ||
1215 | 1224 | ||
1216 | static int read_events(struct perf_kvm_stat *kvm) | 1225 | static int read_events(struct perf_kvm_stat *kvm) |
1217 | { | 1226 | { |
@@ -1222,10 +1231,13 @@ static int read_events(struct perf_kvm_stat *kvm) | |||
1222 | .comm = perf_event__process_comm, | 1231 | .comm = perf_event__process_comm, |
1223 | .ordered_samples = true, | 1232 | .ordered_samples = true, |
1224 | }; | 1233 | }; |
1234 | struct perf_data_file file = { | ||
1235 | .path = input_name, | ||
1236 | .mode = PERF_DATA_MODE_READ, | ||
1237 | }; | ||
1225 | 1238 | ||
1226 | kvm->tool = eops; | 1239 | kvm->tool = eops; |
1227 | kvm->session = perf_session__new(kvm->file_name, O_RDONLY, 0, false, | 1240 | kvm->session = perf_session__new(&file, false, &kvm->tool); |
1228 | &kvm->tool); | ||
1229 | if (!kvm->session) { | 1241 | if (!kvm->session) { |
1230 | pr_err("Initializing perf session failed\n"); | 1242 | pr_err("Initializing perf session failed\n"); |
1231 | return -EINVAL; | 1243 | return -EINVAL; |
@@ -1375,6 +1387,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) | |||
1375 | return kvm_events_report_vcpu(kvm); | 1387 | return kvm_events_report_vcpu(kvm); |
1376 | } | 1388 | } |
1377 | 1389 | ||
1390 | #ifdef HAVE_TIMERFD_SUPPORT | ||
1378 | static struct perf_evlist *kvm_live_event_list(void) | 1391 | static struct perf_evlist *kvm_live_event_list(void) |
1379 | { | 1392 | { |
1380 | struct perf_evlist *evlist; | 1393 | struct perf_evlist *evlist; |
@@ -1433,8 +1446,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
1433 | const struct option live_options[] = { | 1446 | const struct option live_options[] = { |
1434 | OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid", | 1447 | OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid", |
1435 | "record events on existing process id"), | 1448 | "record events on existing process id"), |
1436 | OPT_UINTEGER('m', "mmap-pages", &kvm->opts.mmap_pages, | 1449 | OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages", |
1437 | "number of mmap data pages"), | 1450 | "number of mmap data pages", |
1451 | perf_evlist__parse_mmap_pages), | ||
1438 | OPT_INCR('v', "verbose", &verbose, | 1452 | OPT_INCR('v', "verbose", &verbose, |
1439 | "be more verbose (show counter open errors, etc)"), | 1453 | "be more verbose (show counter open errors, etc)"), |
1440 | OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide, | 1454 | OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide, |
@@ -1456,6 +1470,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
1456 | "perf kvm stat live [<options>]", | 1470 | "perf kvm stat live [<options>]", |
1457 | NULL | 1471 | NULL |
1458 | }; | 1472 | }; |
1473 | struct perf_data_file file = { | ||
1474 | .mode = PERF_DATA_MODE_WRITE, | ||
1475 | }; | ||
1459 | 1476 | ||
1460 | 1477 | ||
1461 | /* event handling */ | 1478 | /* event handling */ |
@@ -1493,13 +1510,13 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
1493 | /* | 1510 | /* |
1494 | * target related setups | 1511 | * target related setups |
1495 | */ | 1512 | */ |
1496 | err = perf_target__validate(&kvm->opts.target); | 1513 | err = target__validate(&kvm->opts.target); |
1497 | if (err) { | 1514 | if (err) { |
1498 | perf_target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ); | 1515 | target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ); |
1499 | ui__warning("%s", errbuf); | 1516 | ui__warning("%s", errbuf); |
1500 | } | 1517 | } |
1501 | 1518 | ||
1502 | if (perf_target__none(&kvm->opts.target)) | 1519 | if (target__none(&kvm->opts.target)) |
1503 | kvm->opts.target.system_wide = true; | 1520 | kvm->opts.target.system_wide = true; |
1504 | 1521 | ||
1505 | 1522 | ||
@@ -1520,25 +1537,15 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
1520 | /* | 1537 | /* |
1521 | * perf session | 1538 | * perf session |
1522 | */ | 1539 | */ |
1523 | kvm->session = perf_session__new(NULL, O_WRONLY, false, false, &kvm->tool); | 1540 | kvm->session = perf_session__new(&file, false, &kvm->tool); |
1524 | if (kvm->session == NULL) { | 1541 | if (kvm->session == NULL) { |
1525 | err = -ENOMEM; | 1542 | err = -ENOMEM; |
1526 | goto out; | 1543 | goto out; |
1527 | } | 1544 | } |
1528 | kvm->session->evlist = kvm->evlist; | 1545 | kvm->session->evlist = kvm->evlist; |
1529 | perf_session__set_id_hdr_size(kvm->session); | 1546 | perf_session__set_id_hdr_size(kvm->session); |
1530 | 1547 | machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, | |
1531 | 1548 | kvm->evlist->threads, false); | |
1532 | if (perf_target__has_task(&kvm->opts.target)) | ||
1533 | perf_event__synthesize_thread_map(&kvm->tool, | ||
1534 | kvm->evlist->threads, | ||
1535 | perf_event__process, | ||
1536 | &kvm->session->machines.host); | ||
1537 | else | ||
1538 | perf_event__synthesize_threads(&kvm->tool, perf_event__process, | ||
1539 | &kvm->session->machines.host); | ||
1540 | |||
1541 | |||
1542 | err = kvm_live_open_events(kvm); | 1549 | err = kvm_live_open_events(kvm); |
1543 | if (err) | 1550 | if (err) |
1544 | goto out; | 1551 | goto out; |
@@ -1558,6 +1565,7 @@ out: | |||
1558 | 1565 | ||
1559 | return err; | 1566 | return err; |
1560 | } | 1567 | } |
1568 | #endif | ||
1561 | 1569 | ||
1562 | static void print_kvm_stat_usage(void) | 1570 | static void print_kvm_stat_usage(void) |
1563 | { | 1571 | { |
@@ -1596,8 +1604,10 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) | |||
1596 | if (!strncmp(argv[1], "rep", 3)) | 1604 | if (!strncmp(argv[1], "rep", 3)) |
1597 | return kvm_events_report(&kvm, argc - 1 , argv + 1); | 1605 | return kvm_events_report(&kvm, argc - 1 , argv + 1); |
1598 | 1606 | ||
1607 | #ifdef HAVE_TIMERFD_SUPPORT | ||
1599 | if (!strncmp(argv[1], "live", 4)) | 1608 | if (!strncmp(argv[1], "live", 4)) |
1600 | return kvm_events_live(&kvm, argc - 1 , argv + 1); | 1609 | return kvm_events_live(&kvm, argc - 1 , argv + 1); |
1610 | #endif | ||
1601 | 1611 | ||
1602 | perf_stat: | 1612 | perf_stat: |
1603 | return cmd_stat(argc, argv, NULL); | 1613 | return cmd_stat(argc, argv, NULL); |