aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-kvm.c')
-rw-r--r--tools/perf/builtin-kvm.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 935d52216c89..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
339static void clear_events_cache_stats(struct list_head *kvm_events_cache) 343static 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
361static int kvm_events_hash_fn(u64 key) 366static 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
785static int process_lost_event(struct perf_tool *tool, 791static 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
796static bool skip_sample(struct perf_kvm_stat *kvm, 803static 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 */
@@ -888,11 +896,18 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
888 while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) { 896 while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) {
889 err = perf_evlist__parse_sample(kvm->evlist, event, &sample); 897 err = perf_evlist__parse_sample(kvm->evlist, event, &sample);
890 if (err) { 898 if (err) {
899 perf_evlist__mmap_consume(kvm->evlist, idx);
891 pr_err("Failed to parse sample\n"); 900 pr_err("Failed to parse sample\n");
892 return -1; 901 return -1;
893 } 902 }
894 903
895 err = perf_session_queue_event(kvm->session, event, &sample, 0); 904 err = perf_session_queue_event(kvm->session, event, &sample, 0);
905 /*
906 * FIXME: Here we can't consume the event, as perf_session_queue_event will
907 * point to it, and it'll get possibly overwritten by the kernel.
908 */
909 perf_evlist__mmap_consume(kvm->evlist, idx);
910
896 if (err) { 911 if (err) {
897 pr_err("Failed to enqueue sample: %d\n", err); 912 pr_err("Failed to enqueue sample: %d\n", err);
898 return -1; 913 return -1;
@@ -1205,6 +1220,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
1205out: 1220out:
1206 return rc; 1221 return rc;
1207} 1222}
1223#endif
1208 1224
1209static int read_events(struct perf_kvm_stat *kvm) 1225static int read_events(struct perf_kvm_stat *kvm)
1210{ 1226{
@@ -1215,10 +1231,13 @@ static int read_events(struct perf_kvm_stat *kvm)
1215 .comm = perf_event__process_comm, 1231 .comm = perf_event__process_comm,
1216 .ordered_samples = true, 1232 .ordered_samples = true,
1217 }; 1233 };
1234 struct perf_data_file file = {
1235 .path = input_name,
1236 .mode = PERF_DATA_MODE_READ,
1237 };
1218 1238
1219 kvm->tool = eops; 1239 kvm->tool = eops;
1220 kvm->session = perf_session__new(kvm->file_name, O_RDONLY, 0, false, 1240 kvm->session = perf_session__new(&file, false, &kvm->tool);
1221 &kvm->tool);
1222 if (!kvm->session) { 1241 if (!kvm->session) {
1223 pr_err("Initializing perf session failed\n"); 1242 pr_err("Initializing perf session failed\n");
1224 return -EINVAL; 1243 return -EINVAL;
@@ -1368,6 +1387,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1368 return kvm_events_report_vcpu(kvm); 1387 return kvm_events_report_vcpu(kvm);
1369} 1388}
1370 1389
1390#ifdef HAVE_TIMERFD_SUPPORT
1371static struct perf_evlist *kvm_live_event_list(void) 1391static struct perf_evlist *kvm_live_event_list(void)
1372{ 1392{
1373 struct perf_evlist *evlist; 1393 struct perf_evlist *evlist;
@@ -1426,8 +1446,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1426 const struct option live_options[] = { 1446 const struct option live_options[] = {
1427 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid", 1447 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1428 "record events on existing process id"), 1448 "record events on existing process id"),
1429 OPT_UINTEGER('m', "mmap-pages", &kvm->opts.mmap_pages, 1449 OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages",
1430 "number of mmap data pages"), 1450 "number of mmap data pages",
1451 perf_evlist__parse_mmap_pages),
1431 OPT_INCR('v', "verbose", &verbose, 1452 OPT_INCR('v', "verbose", &verbose,
1432 "be more verbose (show counter open errors, etc)"), 1453 "be more verbose (show counter open errors, etc)"),
1433 OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide, 1454 OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
@@ -1449,6 +1470,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1449 "perf kvm stat live [<options>]", 1470 "perf kvm stat live [<options>]",
1450 NULL 1471 NULL
1451 }; 1472 };
1473 struct perf_data_file file = {
1474 .mode = PERF_DATA_MODE_WRITE,
1475 };
1452 1476
1453 1477
1454 /* event handling */ 1478 /* event handling */
@@ -1486,13 +1510,13 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1486 /* 1510 /*
1487 * target related setups 1511 * target related setups
1488 */ 1512 */
1489 err = perf_target__validate(&kvm->opts.target); 1513 err = target__validate(&kvm->opts.target);
1490 if (err) { 1514 if (err) {
1491 perf_target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ); 1515 target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
1492 ui__warning("%s", errbuf); 1516 ui__warning("%s", errbuf);
1493 } 1517 }
1494 1518
1495 if (perf_target__none(&kvm->opts.target)) 1519 if (target__none(&kvm->opts.target))
1496 kvm->opts.target.system_wide = true; 1520 kvm->opts.target.system_wide = true;
1497 1521
1498 1522
@@ -1513,25 +1537,15 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1513 /* 1537 /*
1514 * perf session 1538 * perf session
1515 */ 1539 */
1516 kvm->session = perf_session__new(NULL, O_WRONLY, false, false, &kvm->tool); 1540 kvm->session = perf_session__new(&file, false, &kvm->tool);
1517 if (kvm->session == NULL) { 1541 if (kvm->session == NULL) {
1518 err = -ENOMEM; 1542 err = -ENOMEM;
1519 goto out; 1543 goto out;
1520 } 1544 }
1521 kvm->session->evlist = kvm->evlist; 1545 kvm->session->evlist = kvm->evlist;
1522 perf_session__set_id_hdr_size(kvm->session); 1546 perf_session__set_id_hdr_size(kvm->session);
1523 1547 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
1524 1548 kvm->evlist->threads, false);
1525 if (perf_target__has_task(&kvm->opts.target))
1526 perf_event__synthesize_thread_map(&kvm->tool,
1527 kvm->evlist->threads,
1528 perf_event__process,
1529 &kvm->session->machines.host);
1530 else
1531 perf_event__synthesize_threads(&kvm->tool, perf_event__process,
1532 &kvm->session->machines.host);
1533
1534
1535 err = kvm_live_open_events(kvm); 1549 err = kvm_live_open_events(kvm);
1536 if (err) 1550 if (err)
1537 goto out; 1551 goto out;
@@ -1551,6 +1565,7 @@ out:
1551 1565
1552 return err; 1566 return err;
1553} 1567}
1568#endif
1554 1569
1555static void print_kvm_stat_usage(void) 1570static void print_kvm_stat_usage(void)
1556{ 1571{
@@ -1589,8 +1604,10 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
1589 if (!strncmp(argv[1], "rep", 3)) 1604 if (!strncmp(argv[1], "rep", 3))
1590 return kvm_events_report(&kvm, argc - 1 , argv + 1); 1605 return kvm_events_report(&kvm, argc - 1 , argv + 1);
1591 1606
1607#ifdef HAVE_TIMERFD_SUPPORT
1592 if (!strncmp(argv[1], "live", 4)) 1608 if (!strncmp(argv[1], "live", 4))
1593 return kvm_events_live(&kvm, argc - 1 , argv + 1); 1609 return kvm_events_live(&kvm, argc - 1 , argv + 1);
1610#endif
1594 1611
1595perf_stat: 1612perf_stat:
1596 return cmd_stat(argc, argv, NULL); 1613 return cmd_stat(argc, argv, NULL);