diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-09-27 03:15:48 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-09-27 03:15:48 -0400 |
commit | 07394b5f13a04f86b27e0ddd96a36c7d9bfe1a4f (patch) | |
tree | 684f1103022db370242cc21199ca3cd5985eaac1 | |
parent | cf8102f64c8d23f0bd4af0659bbd94d0c1d8d1c7 (diff) | |
parent | 49757c9cc7887bc79f742eb8aacf16e464ca5f0b (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
User visible changes:
o Restore "--callchain graph" output, broken in recent cset to end
up being the same as "fractal" (Namhyung Kim)
o Allow profiling when kptr_restrict == 1 for non root users,
kernel samples will just remain unresolved (Andi Kleen)
o Allow configuring default options for callchains in config file (Namhyung Kim)
o Fix line number in the config file error message (Jiri Olsa)
o Fix --per-core on multi socket systems (Andi Kleen)
Cleanups:
o Use ACCESS_ONCE() instead of volatile cast. (Pranith Kumar)
o Modify error code for when perf_session__new() fails (Taeung Song)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | tools/perf/builtin-annotate.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-diff.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-evlist.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-inject.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-kmem.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-kvm.c | 4 | ||||
-rw-r--r-- | tools/perf/builtin-lock.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-mem.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 119 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 9 | ||||
-rw-r--r-- | tools/perf/builtin-timechart.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 6 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 2 | ||||
-rw-r--r-- | tools/perf/perf.h | 3 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 3 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 193 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 6 | ||||
-rw-r--r-- | tools/perf/util/config.c | 16 | ||||
-rw-r--r-- | tools/perf/util/event.c | 8 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 11 | ||||
-rw-r--r-- | tools/perf/util/session.c | 2 | ||||
-rw-r--r-- | tools/perf/util/session.h | 2 |
24 files changed, 241 insertions, 163 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index d4da6929597f..be5939418425 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -340,7 +340,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) | |||
340 | 340 | ||
341 | annotate.session = perf_session__new(&file, false, &annotate.tool); | 341 | annotate.session = perf_session__new(&file, false, &annotate.tool); |
342 | if (annotate.session == NULL) | 342 | if (annotate.session == NULL) |
343 | return -ENOMEM; | 343 | return -1; |
344 | 344 | ||
345 | symbol_conf.priv_size = sizeof(struct annotation); | 345 | symbol_conf.priv_size = sizeof(struct annotation); |
346 | symbol_conf.try_vmlinux_path = true; | 346 | symbol_conf.try_vmlinux_path = true; |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 190d0b6b28cc..a3ce19f7aebd 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -683,7 +683,7 @@ static int __cmd_diff(void) | |||
683 | d->session = perf_session__new(&d->file, false, &tool); | 683 | d->session = perf_session__new(&d->file, false, &tool); |
684 | if (!d->session) { | 684 | if (!d->session) { |
685 | pr_err("Failed to open %s\n", d->file.path); | 685 | pr_err("Failed to open %s\n", d->file.path); |
686 | ret = -ENOMEM; | 686 | ret = -1; |
687 | goto out_delete; | 687 | goto out_delete; |
688 | } | 688 | } |
689 | 689 | ||
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 66e12f55c052..0f93f859b782 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c | |||
@@ -28,7 +28,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details | |||
28 | 28 | ||
29 | session = perf_session__new(&file, 0, NULL); | 29 | session = perf_session__new(&file, 0, NULL); |
30 | if (session == NULL) | 30 | if (session == NULL) |
31 | return -ENOMEM; | 31 | return -1; |
32 | 32 | ||
33 | evlist__for_each(session->evlist, pos) | 33 | evlist__for_each(session->evlist, pos) |
34 | perf_evsel__fprintf(pos, details, stdout); | 34 | perf_evsel__fprintf(pos, details, stdout); |
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 3a62b6b3c8fd..de99ca1bb942 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
@@ -460,7 +460,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) | |||
460 | file.path = inject.input_name; | 460 | file.path = inject.input_name; |
461 | inject.session = perf_session__new(&file, true, &inject.tool); | 461 | inject.session = perf_session__new(&file, true, &inject.tool); |
462 | if (inject.session == NULL) | 462 | if (inject.session == NULL) |
463 | return -ENOMEM; | 463 | return -1; |
464 | 464 | ||
465 | if (symbol__init(&inject.session->header.env) < 0) | 465 | if (symbol__init(&inject.session->header.env) < 0) |
466 | return -1; | 466 | return -1; |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 23762187a219..f295141025bc 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -698,7 +698,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) | |||
698 | 698 | ||
699 | session = perf_session__new(&file, false, &perf_kmem); | 699 | session = perf_session__new(&file, false, &perf_kmem); |
700 | if (session == NULL) | 700 | if (session == NULL) |
701 | return -ENOMEM; | 701 | return -1; |
702 | 702 | ||
703 | symbol__init(&session->header.env); | 703 | symbol__init(&session->header.env); |
704 | 704 | ||
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 1e639d6265cc..d8bf2271f4ea 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -1058,7 +1058,7 @@ static int read_events(struct perf_kvm_stat *kvm) | |||
1058 | kvm->session = perf_session__new(&file, false, &kvm->tool); | 1058 | kvm->session = perf_session__new(&file, false, &kvm->tool); |
1059 | if (!kvm->session) { | 1059 | if (!kvm->session) { |
1060 | pr_err("Initializing perf session failed\n"); | 1060 | pr_err("Initializing perf session failed\n"); |
1061 | return -EINVAL; | 1061 | return -1; |
1062 | } | 1062 | } |
1063 | 1063 | ||
1064 | symbol__init(&kvm->session->header.env); | 1064 | symbol__init(&kvm->session->header.env); |
@@ -1361,7 +1361,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
1361 | */ | 1361 | */ |
1362 | kvm->session = perf_session__new(&file, false, &kvm->tool); | 1362 | kvm->session = perf_session__new(&file, false, &kvm->tool); |
1363 | if (kvm->session == NULL) { | 1363 | if (kvm->session == NULL) { |
1364 | err = -ENOMEM; | 1364 | err = -1; |
1365 | goto out; | 1365 | goto out; |
1366 | } | 1366 | } |
1367 | kvm->session->evlist = kvm->evlist; | 1367 | kvm->session->evlist = kvm->evlist; |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 92790ed7af45..e7ec71589da6 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
@@ -862,7 +862,7 @@ static int __cmd_report(bool display_info) | |||
862 | session = perf_session__new(&file, false, &eops); | 862 | session = perf_session__new(&file, false, &eops); |
863 | if (!session) { | 863 | if (!session) { |
864 | pr_err("Initializing perf session failed\n"); | 864 | pr_err("Initializing perf session failed\n"); |
865 | return -ENOMEM; | 865 | return -1; |
866 | } | 866 | } |
867 | 867 | ||
868 | symbol__init(&session->header.env); | 868 | symbol__init(&session->header.env); |
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 8b4a87fe3858..24db6ffe2957 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c | |||
@@ -124,7 +124,7 @@ static int report_raw_events(struct perf_mem *mem) | |||
124 | &mem->tool); | 124 | &mem->tool); |
125 | 125 | ||
126 | if (session == NULL) | 126 | if (session == NULL) |
127 | return -ENOMEM; | 127 | return -1; |
128 | 128 | ||
129 | if (mem->cpu_list) { | 129 | if (mem->cpu_list) { |
130 | ret = perf_session__cpu_bitmap(session, mem->cpu_list, | 130 | ret = perf_session__cpu_bitmap(session, mem->cpu_list, |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 320b198b54dd..44c6f3d55ce7 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -624,145 +624,56 @@ error: | |||
624 | return ret; | 624 | return ret; |
625 | } | 625 | } |
626 | 626 | ||
627 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | 627 | static void callchain_debug(void) |
628 | static int get_stack_size(char *str, unsigned long *_size) | ||
629 | { | ||
630 | char *endptr; | ||
631 | unsigned long size; | ||
632 | unsigned long max_size = round_down(USHRT_MAX, sizeof(u64)); | ||
633 | |||
634 | size = strtoul(str, &endptr, 0); | ||
635 | |||
636 | do { | ||
637 | if (*endptr) | ||
638 | break; | ||
639 | |||
640 | size = round_up(size, sizeof(u64)); | ||
641 | if (!size || size > max_size) | ||
642 | break; | ||
643 | |||
644 | *_size = size; | ||
645 | return 0; | ||
646 | |||
647 | } while (0); | ||
648 | |||
649 | pr_err("callchain: Incorrect stack dump size (max %ld): %s\n", | ||
650 | max_size, str); | ||
651 | return -1; | ||
652 | } | ||
653 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ | ||
654 | |||
655 | int record_parse_callchain(const char *arg, struct record_opts *opts) | ||
656 | { | ||
657 | char *tok, *name, *saveptr = NULL; | ||
658 | char *buf; | ||
659 | int ret = -1; | ||
660 | |||
661 | /* We need buffer that we know we can write to. */ | ||
662 | buf = malloc(strlen(arg) + 1); | ||
663 | if (!buf) | ||
664 | return -ENOMEM; | ||
665 | |||
666 | strcpy(buf, arg); | ||
667 | |||
668 | tok = strtok_r((char *)buf, ",", &saveptr); | ||
669 | name = tok ? : (char *)buf; | ||
670 | |||
671 | do { | ||
672 | /* Framepointer style */ | ||
673 | if (!strncmp(name, "fp", sizeof("fp"))) { | ||
674 | if (!strtok_r(NULL, ",", &saveptr)) { | ||
675 | opts->call_graph = CALLCHAIN_FP; | ||
676 | ret = 0; | ||
677 | } else | ||
678 | pr_err("callchain: No more arguments " | ||
679 | "needed for -g fp\n"); | ||
680 | break; | ||
681 | |||
682 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
683 | /* Dwarf style */ | ||
684 | } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) { | ||
685 | const unsigned long default_stack_dump_size = 8192; | ||
686 | |||
687 | ret = 0; | ||
688 | opts->call_graph = CALLCHAIN_DWARF; | ||
689 | opts->stack_dump_size = default_stack_dump_size; | ||
690 | |||
691 | tok = strtok_r(NULL, ",", &saveptr); | ||
692 | if (tok) { | ||
693 | unsigned long size = 0; | ||
694 | |||
695 | ret = get_stack_size(tok, &size); | ||
696 | opts->stack_dump_size = size; | ||
697 | } | ||
698 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ | ||
699 | } else { | ||
700 | pr_err("callchain: Unknown --call-graph option " | ||
701 | "value: %s\n", arg); | ||
702 | break; | ||
703 | } | ||
704 | |||
705 | } while (0); | ||
706 | |||
707 | free(buf); | ||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | static void callchain_debug(struct record_opts *opts) | ||
712 | { | 628 | { |
713 | static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" }; | 629 | static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" }; |
714 | 630 | ||
715 | pr_debug("callchain: type %s\n", str[opts->call_graph]); | 631 | pr_debug("callchain: type %s\n", str[callchain_param.record_mode]); |
716 | 632 | ||
717 | if (opts->call_graph == CALLCHAIN_DWARF) | 633 | if (callchain_param.record_mode == CALLCHAIN_DWARF) |
718 | pr_debug("callchain: stack dump size %d\n", | 634 | pr_debug("callchain: stack dump size %d\n", |
719 | opts->stack_dump_size); | 635 | callchain_param.dump_size); |
720 | } | 636 | } |
721 | 637 | ||
722 | int record_parse_callchain_opt(const struct option *opt, | 638 | int record_parse_callchain_opt(const struct option *opt __maybe_unused, |
723 | const char *arg, | 639 | const char *arg, |
724 | int unset) | 640 | int unset) |
725 | { | 641 | { |
726 | struct record_opts *opts = opt->value; | ||
727 | int ret; | 642 | int ret; |
728 | 643 | ||
729 | opts->call_graph_enabled = !unset; | 644 | callchain_param.enabled = !unset; |
730 | 645 | ||
731 | /* --no-call-graph */ | 646 | /* --no-call-graph */ |
732 | if (unset) { | 647 | if (unset) { |
733 | opts->call_graph = CALLCHAIN_NONE; | 648 | callchain_param.record_mode = CALLCHAIN_NONE; |
734 | pr_debug("callchain: disabled\n"); | 649 | pr_debug("callchain: disabled\n"); |
735 | return 0; | 650 | return 0; |
736 | } | 651 | } |
737 | 652 | ||
738 | ret = record_parse_callchain(arg, opts); | 653 | ret = parse_callchain_record_opt(arg); |
739 | if (!ret) | 654 | if (!ret) |
740 | callchain_debug(opts); | 655 | callchain_debug(); |
741 | 656 | ||
742 | return ret; | 657 | return ret; |
743 | } | 658 | } |
744 | 659 | ||
745 | int record_callchain_opt(const struct option *opt, | 660 | int record_callchain_opt(const struct option *opt __maybe_unused, |
746 | const char *arg __maybe_unused, | 661 | const char *arg __maybe_unused, |
747 | int unset __maybe_unused) | 662 | int unset __maybe_unused) |
748 | { | 663 | { |
749 | struct record_opts *opts = opt->value; | 664 | callchain_param.enabled = true; |
750 | 665 | ||
751 | opts->call_graph_enabled = !unset; | 666 | if (callchain_param.record_mode == CALLCHAIN_NONE) |
667 | callchain_param.record_mode = CALLCHAIN_FP; | ||
752 | 668 | ||
753 | if (opts->call_graph == CALLCHAIN_NONE) | 669 | callchain_debug(); |
754 | opts->call_graph = CALLCHAIN_FP; | ||
755 | |||
756 | callchain_debug(opts); | ||
757 | return 0; | 670 | return 0; |
758 | } | 671 | } |
759 | 672 | ||
760 | static int perf_record_config(const char *var, const char *value, void *cb) | 673 | static int perf_record_config(const char *var, const char *value, void *cb) |
761 | { | 674 | { |
762 | struct record *rec = cb; | ||
763 | |||
764 | if (!strcmp(var, "record.call-graph")) | 675 | if (!strcmp(var, "record.call-graph")) |
765 | return record_parse_callchain(value, &rec->opts); | 676 | var = "call-graph.record-mode"; /* fall-through */ |
766 | 677 | ||
767 | return perf_default_config(var, value, cb); | 678 | return perf_default_config(var, value, cb); |
768 | } | 679 | } |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 8c0b3f22412a..ac145fae0521 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -720,7 +720,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
720 | repeat: | 720 | repeat: |
721 | session = perf_session__new(&file, false, &report.tool); | 721 | session = perf_session__new(&file, false, &report.tool); |
722 | if (session == NULL) | 722 | if (session == NULL) |
723 | return -ENOMEM; | 723 | return -1; |
724 | 724 | ||
725 | if (report.queue_size) { | 725 | if (report.queue_size) { |
726 | ordered_events__set_alloc_size(&session->ordered_events, | 726 | ordered_events__set_alloc_size(&session->ordered_events, |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 02dce9295e2c..b9b9e58a6c39 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -1744,7 +1744,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1744 | 1744 | ||
1745 | session = perf_session__new(&file, false, &script.tool); | 1745 | session = perf_session__new(&file, false, &script.tool); |
1746 | if (session == NULL) | 1746 | if (session == NULL) |
1747 | return -ENOMEM; | 1747 | return -1; |
1748 | 1748 | ||
1749 | if (header || header_only) { | 1749 | if (header || header_only) { |
1750 | perf_session__fprintf_info(session, stdout, show_full_info); | 1750 | perf_session__fprintf_info(session, stdout, show_full_info); |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 5fe0edb1de5d..b22c62f80078 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -732,7 +732,7 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr) | |||
732 | } | 732 | } |
733 | } | 733 | } |
734 | 734 | ||
735 | static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) | 735 | static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg) |
736 | { | 736 | { |
737 | double msecs = avg / 1e6; | 737 | double msecs = avg / 1e6; |
738 | const char *fmt_v, *fmt_n; | 738 | const char *fmt_v, *fmt_n; |
@@ -741,7 +741,7 @@ static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) | |||
741 | fmt_v = csv_output ? "%.6f%s" : "%18.6f%s"; | 741 | fmt_v = csv_output ? "%.6f%s" : "%18.6f%s"; |
742 | fmt_n = csv_output ? "%s" : "%-25s"; | 742 | fmt_n = csv_output ? "%s" : "%-25s"; |
743 | 743 | ||
744 | aggr_printout(evsel, cpu, nr); | 744 | aggr_printout(evsel, id, nr); |
745 | 745 | ||
746 | scnprintf(name, sizeof(name), "%s%s", | 746 | scnprintf(name, sizeof(name), "%s%s", |
747 | perf_evsel__name(evsel), csv_output ? "" : " (msec)"); | 747 | perf_evsel__name(evsel), csv_output ? "" : " (msec)"); |
@@ -947,11 +947,12 @@ static void print_ll_cache_misses(int cpu, | |||
947 | fprintf(output, " of all LL-cache hits "); | 947 | fprintf(output, " of all LL-cache hits "); |
948 | } | 948 | } |
949 | 949 | ||
950 | static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) | 950 | static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) |
951 | { | 951 | { |
952 | double total, ratio = 0.0, total2; | 952 | double total, ratio = 0.0, total2; |
953 | double sc = evsel->scale; | 953 | double sc = evsel->scale; |
954 | const char *fmt; | 954 | const char *fmt; |
955 | int cpu = cpu_map__id_to_cpu(id); | ||
955 | 956 | ||
956 | if (csv_output) { | 957 | if (csv_output) { |
957 | fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s"; | 958 | fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s"; |
@@ -962,7 +963,7 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) | |||
962 | fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s"; | 963 | fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s"; |
963 | } | 964 | } |
964 | 965 | ||
965 | aggr_printout(evsel, cpu, nr); | 966 | aggr_printout(evsel, id, nr); |
966 | 967 | ||
967 | if (aggr_mode == AGGR_GLOBAL) | 968 | if (aggr_mode == AGGR_GLOBAL) |
968 | cpu = 0; | 969 | cpu = 0; |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 48eea6cd2f5b..35b425b6293f 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
@@ -1605,7 +1605,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) | |||
1605 | int ret = -EINVAL; | 1605 | int ret = -EINVAL; |
1606 | 1606 | ||
1607 | if (session == NULL) | 1607 | if (session == NULL) |
1608 | return -ENOMEM; | 1608 | return -1; |
1609 | 1609 | ||
1610 | symbol__init(&session->header.env); | 1610 | symbol__init(&session->header.env); |
1611 | 1611 | ||
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 832fb527ed90..fc3d55f832ac 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -929,7 +929,7 @@ static int __cmd_top(struct perf_top *top) | |||
929 | 929 | ||
930 | top->session = perf_session__new(NULL, false, NULL); | 930 | top->session = perf_session__new(NULL, false, NULL); |
931 | if (top->session == NULL) | 931 | if (top->session == NULL) |
932 | return -ENOMEM; | 932 | return -1; |
933 | 933 | ||
934 | machines__set_symbol_filter(&top->session->machines, symbol_filter); | 934 | machines__set_symbol_filter(&top->session->machines, symbol_filter); |
935 | 935 | ||
@@ -1020,10 +1020,8 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) | |||
1020 | 1020 | ||
1021 | static int perf_top_config(const char *var, const char *value, void *cb) | 1021 | static int perf_top_config(const char *var, const char *value, void *cb) |
1022 | { | 1022 | { |
1023 | struct perf_top *top = cb; | ||
1024 | |||
1025 | if (!strcmp(var, "top.call-graph")) | 1023 | if (!strcmp(var, "top.call-graph")) |
1026 | return record_parse_callchain(value, &top->record_opts); | 1024 | var = "call-graph.record-mode"; /* fall-through */ |
1027 | if (!strcmp(var, "top.children")) { | 1025 | if (!strcmp(var, "top.children")) { |
1028 | symbol_conf.cumulate_callchain = perf_config_bool(var, value); | 1026 | symbol_conf.cumulate_callchain = perf_config_bool(var, value); |
1029 | return 0; | 1027 | return 0; |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fe39dc620179..c70e69ea1c5d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -2250,7 +2250,7 @@ static int trace__replay(struct trace *trace) | |||
2250 | 2250 | ||
2251 | session = perf_session__new(&file, false, &trace->tool); | 2251 | session = perf_session__new(&file, false, &trace->tool); |
2252 | if (session == NULL) | 2252 | if (session == NULL) |
2253 | return -ENOMEM; | 2253 | return -1; |
2254 | 2254 | ||
2255 | if (symbol__init(&session->header.env) < 0) | 2255 | if (symbol__init(&session->header.env) < 0) |
2256 | goto out; | 2256 | goto out; |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 510c65f72858..220d44e44c1b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -41,8 +41,6 @@ void pthread__unblock_sigwinch(void); | |||
41 | 41 | ||
42 | struct record_opts { | 42 | struct record_opts { |
43 | struct target target; | 43 | struct target target; |
44 | int call_graph; | ||
45 | bool call_graph_enabled; | ||
46 | bool group; | 44 | bool group; |
47 | bool inherit_stat; | 45 | bool inherit_stat; |
48 | bool no_buffering; | 46 | bool no_buffering; |
@@ -60,7 +58,6 @@ struct record_opts { | |||
60 | u64 branch_stack; | 58 | u64 branch_stack; |
61 | u64 default_interval; | 59 | u64 default_interval; |
62 | u64 user_interval; | 60 | u64 user_interval; |
63 | u16 stack_dump_size; | ||
64 | bool sample_transaction; | 61 | bool sample_transaction; |
65 | unsigned initial_delay; | 62 | unsigned initial_delay; |
66 | }; | 63 | }; |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index d4cef68176da..8f60a970404f 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -804,9 +804,6 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
804 | .is_current_entry = current_entry, | 804 | .is_current_entry = current_entry, |
805 | }; | 805 | }; |
806 | 806 | ||
807 | if (symbol_conf.cumulate_callchain) | ||
808 | total = entry->stat_acc->period; | ||
809 | |||
810 | printed += hist_browser__show_callchain(browser, | 807 | printed += hist_browser__show_callchain(browser, |
811 | &entry->sorted_chain, 1, row, total, | 808 | &entry->sorted_chain, 1, row, total, |
812 | hist_browser__show_callchain_entry, &arg, | 809 | hist_browser__show_callchain_entry, &arg, |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 08f0fbf5527c..c84d3f8dcb75 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -25,6 +25,133 @@ | |||
25 | 25 | ||
26 | __thread struct callchain_cursor callchain_cursor; | 26 | __thread struct callchain_cursor callchain_cursor; |
27 | 27 | ||
28 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
29 | static int get_stack_size(const char *str, unsigned long *_size) | ||
30 | { | ||
31 | char *endptr; | ||
32 | unsigned long size; | ||
33 | unsigned long max_size = round_down(USHRT_MAX, sizeof(u64)); | ||
34 | |||
35 | size = strtoul(str, &endptr, 0); | ||
36 | |||
37 | do { | ||
38 | if (*endptr) | ||
39 | break; | ||
40 | |||
41 | size = round_up(size, sizeof(u64)); | ||
42 | if (!size || size > max_size) | ||
43 | break; | ||
44 | |||
45 | *_size = size; | ||
46 | return 0; | ||
47 | |||
48 | } while (0); | ||
49 | |||
50 | pr_err("callchain: Incorrect stack dump size (max %ld): %s\n", | ||
51 | max_size, str); | ||
52 | return -1; | ||
53 | } | ||
54 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ | ||
55 | |||
56 | int parse_callchain_record_opt(const char *arg) | ||
57 | { | ||
58 | char *tok, *name, *saveptr = NULL; | ||
59 | char *buf; | ||
60 | int ret = -1; | ||
61 | |||
62 | /* We need buffer that we know we can write to. */ | ||
63 | buf = malloc(strlen(arg) + 1); | ||
64 | if (!buf) | ||
65 | return -ENOMEM; | ||
66 | |||
67 | strcpy(buf, arg); | ||
68 | |||
69 | tok = strtok_r((char *)buf, ",", &saveptr); | ||
70 | name = tok ? : (char *)buf; | ||
71 | |||
72 | do { | ||
73 | /* Framepointer style */ | ||
74 | if (!strncmp(name, "fp", sizeof("fp"))) { | ||
75 | if (!strtok_r(NULL, ",", &saveptr)) { | ||
76 | callchain_param.record_mode = CALLCHAIN_FP; | ||
77 | ret = 0; | ||
78 | } else | ||
79 | pr_err("callchain: No more arguments " | ||
80 | "needed for -g fp\n"); | ||
81 | break; | ||
82 | |||
83 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
84 | /* Dwarf style */ | ||
85 | } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) { | ||
86 | const unsigned long default_stack_dump_size = 8192; | ||
87 | |||
88 | ret = 0; | ||
89 | callchain_param.record_mode = CALLCHAIN_DWARF; | ||
90 | callchain_param.dump_size = default_stack_dump_size; | ||
91 | |||
92 | tok = strtok_r(NULL, ",", &saveptr); | ||
93 | if (tok) { | ||
94 | unsigned long size = 0; | ||
95 | |||
96 | ret = get_stack_size(tok, &size); | ||
97 | callchain_param.dump_size = size; | ||
98 | } | ||
99 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ | ||
100 | } else { | ||
101 | pr_err("callchain: Unknown --call-graph option " | ||
102 | "value: %s\n", arg); | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | } while (0); | ||
107 | |||
108 | free(buf); | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static int parse_callchain_mode(const char *value) | ||
113 | { | ||
114 | if (!strncmp(value, "graph", strlen(value))) { | ||
115 | callchain_param.mode = CHAIN_GRAPH_ABS; | ||
116 | return 0; | ||
117 | } | ||
118 | if (!strncmp(value, "flat", strlen(value))) { | ||
119 | callchain_param.mode = CHAIN_FLAT; | ||
120 | return 0; | ||
121 | } | ||
122 | if (!strncmp(value, "fractal", strlen(value))) { | ||
123 | callchain_param.mode = CHAIN_GRAPH_REL; | ||
124 | return 0; | ||
125 | } | ||
126 | return -1; | ||
127 | } | ||
128 | |||
129 | static int parse_callchain_order(const char *value) | ||
130 | { | ||
131 | if (!strncmp(value, "caller", strlen(value))) { | ||
132 | callchain_param.order = ORDER_CALLER; | ||
133 | return 0; | ||
134 | } | ||
135 | if (!strncmp(value, "callee", strlen(value))) { | ||
136 | callchain_param.order = ORDER_CALLEE; | ||
137 | return 0; | ||
138 | } | ||
139 | return -1; | ||
140 | } | ||
141 | |||
142 | static int parse_callchain_sort_key(const char *value) | ||
143 | { | ||
144 | if (!strncmp(value, "function", strlen(value))) { | ||
145 | callchain_param.key = CCKEY_FUNCTION; | ||
146 | return 0; | ||
147 | } | ||
148 | if (!strncmp(value, "address", strlen(value))) { | ||
149 | callchain_param.key = CCKEY_ADDRESS; | ||
150 | return 0; | ||
151 | } | ||
152 | return -1; | ||
153 | } | ||
154 | |||
28 | int | 155 | int |
29 | parse_callchain_report_opt(const char *arg) | 156 | parse_callchain_report_opt(const char *arg) |
30 | { | 157 | { |
@@ -44,25 +171,12 @@ parse_callchain_report_opt(const char *arg) | |||
44 | return 0; | 171 | return 0; |
45 | } | 172 | } |
46 | 173 | ||
47 | /* try to get the output mode */ | 174 | if (!parse_callchain_mode(tok) || |
48 | if (!strncmp(tok, "graph", strlen(tok))) | 175 | !parse_callchain_order(tok) || |
49 | callchain_param.mode = CHAIN_GRAPH_ABS; | 176 | !parse_callchain_sort_key(tok)) { |
50 | else if (!strncmp(tok, "flat", strlen(tok))) | 177 | /* parsing ok - move on to the next */ |
51 | callchain_param.mode = CHAIN_FLAT; | 178 | } else if (!minpcnt_set) { |
52 | else if (!strncmp(tok, "fractal", strlen(tok))) | 179 | /* try to get the min percent */ |
53 | callchain_param.mode = CHAIN_GRAPH_REL; | ||
54 | /* try to get the call chain order */ | ||
55 | else if (!strncmp(tok, "caller", strlen(tok))) | ||
56 | callchain_param.order = ORDER_CALLER; | ||
57 | else if (!strncmp(tok, "callee", strlen(tok))) | ||
58 | callchain_param.order = ORDER_CALLEE; | ||
59 | /* try to get the sort key */ | ||
60 | else if (!strncmp(tok, "function", strlen(tok))) | ||
61 | callchain_param.key = CCKEY_FUNCTION; | ||
62 | else if (!strncmp(tok, "address", strlen(tok))) | ||
63 | callchain_param.key = CCKEY_ADDRESS; | ||
64 | /* try to get the min percent */ | ||
65 | else if (!minpcnt_set) { | ||
66 | callchain_param.min_percent = strtod(tok, &endptr); | 180 | callchain_param.min_percent = strtod(tok, &endptr); |
67 | if (tok == endptr) | 181 | if (tok == endptr) |
68 | return -1; | 182 | return -1; |
@@ -84,6 +198,47 @@ parse_callchain_report_opt(const char *arg) | |||
84 | return 0; | 198 | return 0; |
85 | } | 199 | } |
86 | 200 | ||
201 | int perf_callchain_config(const char *var, const char *value) | ||
202 | { | ||
203 | char *endptr; | ||
204 | |||
205 | if (prefixcmp(var, "call-graph.")) | ||
206 | return 0; | ||
207 | var += sizeof("call-graph.") - 1; | ||
208 | |||
209 | if (!strcmp(var, "record-mode")) | ||
210 | return parse_callchain_record_opt(value); | ||
211 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
212 | if (!strcmp(var, "dump-size")) { | ||
213 | unsigned long size = 0; | ||
214 | int ret; | ||
215 | |||
216 | ret = get_stack_size(value, &size); | ||
217 | callchain_param.dump_size = size; | ||
218 | |||
219 | return ret; | ||
220 | } | ||
221 | #endif | ||
222 | if (!strcmp(var, "print-type")) | ||
223 | return parse_callchain_mode(value); | ||
224 | if (!strcmp(var, "order")) | ||
225 | return parse_callchain_order(value); | ||
226 | if (!strcmp(var, "sort-key")) | ||
227 | return parse_callchain_sort_key(value); | ||
228 | if (!strcmp(var, "threshold")) { | ||
229 | callchain_param.min_percent = strtod(value, &endptr); | ||
230 | if (value == endptr) | ||
231 | return -1; | ||
232 | } | ||
233 | if (!strcmp(var, "print-limit")) { | ||
234 | callchain_param.print_limit = strtod(value, &endptr); | ||
235 | if (value == endptr) | ||
236 | return -1; | ||
237 | } | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
87 | static void | 242 | static void |
88 | rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | 243 | rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, |
89 | enum chain_mode mode) | 244 | enum chain_mode mode) |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index da43619d6173..2a1f5a46543a 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -54,6 +54,9 @@ enum chain_key { | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct callchain_param { | 56 | struct callchain_param { |
57 | bool enabled; | ||
58 | enum perf_call_graph_mode record_mode; | ||
59 | u32 dump_size; | ||
57 | enum chain_mode mode; | 60 | enum chain_mode mode; |
58 | u32 print_limit; | 61 | u32 print_limit; |
59 | double min_percent; | 62 | double min_percent; |
@@ -154,7 +157,6 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor) | |||
154 | struct option; | 157 | struct option; |
155 | struct hist_entry; | 158 | struct hist_entry; |
156 | 159 | ||
157 | int record_parse_callchain(const char *arg, struct record_opts *opts); | ||
158 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); | 160 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); |
159 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); | 161 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); |
160 | 162 | ||
@@ -166,7 +168,9 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * | |||
166 | bool hide_unresolved); | 168 | bool hide_unresolved); |
167 | 169 | ||
168 | extern const char record_callchain_help[]; | 170 | extern const char record_callchain_help[]; |
171 | int parse_callchain_record_opt(const char *arg); | ||
169 | int parse_callchain_report_opt(const char *arg); | 172 | int parse_callchain_report_opt(const char *arg); |
173 | int perf_callchain_config(const char *var, const char *value); | ||
170 | 174 | ||
171 | static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, | 175 | static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, |
172 | struct callchain_cursor *src) | 176 | struct callchain_cursor *src) |
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 9970b8b0190b..57ff826f150b 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
@@ -222,7 +222,8 @@ static int perf_parse_file(config_fn_t fn, void *data) | |||
222 | const unsigned char *bomptr = utf8_bom; | 222 | const unsigned char *bomptr = utf8_bom; |
223 | 223 | ||
224 | for (;;) { | 224 | for (;;) { |
225 | int c = get_next_char(); | 225 | int line, c = get_next_char(); |
226 | |||
226 | if (bomptr && *bomptr) { | 227 | if (bomptr && *bomptr) { |
227 | /* We are at the file beginning; skip UTF8-encoded BOM | 228 | /* We are at the file beginning; skip UTF8-encoded BOM |
228 | * if present. Sane editors won't put this in on their | 229 | * if present. Sane editors won't put this in on their |
@@ -261,8 +262,16 @@ static int perf_parse_file(config_fn_t fn, void *data) | |||
261 | if (!isalpha(c)) | 262 | if (!isalpha(c)) |
262 | break; | 263 | break; |
263 | var[baselen] = tolower(c); | 264 | var[baselen] = tolower(c); |
264 | if (get_value(fn, data, var, baselen+1) < 0) | 265 | |
266 | /* | ||
267 | * The get_value function might or might not reach the '\n', | ||
268 | * so saving the current line number for error reporting. | ||
269 | */ | ||
270 | line = config_linenr; | ||
271 | if (get_value(fn, data, var, baselen+1) < 0) { | ||
272 | config_linenr = line; | ||
265 | break; | 273 | break; |
274 | } | ||
266 | } | 275 | } |
267 | die("bad config file line %d in %s", config_linenr, config_file_name); | 276 | die("bad config file line %d in %s", config_linenr, config_file_name); |
268 | } | 277 | } |
@@ -396,6 +405,9 @@ int perf_default_config(const char *var, const char *value, | |||
396 | if (!prefixcmp(var, "ui.")) | 405 | if (!prefixcmp(var, "ui.")) |
397 | return perf_ui_config(var, value); | 406 | return perf_ui_config(var, value); |
398 | 407 | ||
408 | if (!prefixcmp(var, "call-graph.")) | ||
409 | return perf_callchain_config(var, value); | ||
410 | |||
399 | /* Add other config variables here. */ | 411 | /* Add other config variables here. */ |
400 | return 0; | 412 | return 0; |
401 | } | 413 | } |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index ed558191c0b3..4af6b279e34a 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -558,13 +558,17 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, | |||
558 | struct map *map; | 558 | struct map *map; |
559 | struct kmap *kmap; | 559 | struct kmap *kmap; |
560 | int err; | 560 | int err; |
561 | union perf_event *event; | ||
562 | |||
563 | if (machine->vmlinux_maps[0] == NULL) | ||
564 | return -1; | ||
565 | |||
561 | /* | 566 | /* |
562 | * We should get this from /sys/kernel/sections/.text, but till that is | 567 | * We should get this from /sys/kernel/sections/.text, but till that is |
563 | * available use this, and after it is use this as a fallback for older | 568 | * available use this, and after it is use this as a fallback for older |
564 | * kernels. | 569 | * kernels. |
565 | */ | 570 | */ |
566 | union perf_event *event = zalloc((sizeof(event->mmap) + | 571 | event = zalloc((sizeof(event->mmap) + machine->id_hdr_size)); |
567 | machine->id_hdr_size)); | ||
568 | if (event == NULL) { | 572 | if (event == NULL) { |
569 | pr_debug("Not enough memory synthesizing mmap event " | 573 | pr_debug("Not enough memory synthesizing mmap event " |
570 | "for kernel modules\n"); | 574 | "for kernel modules\n"); |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b38de5819323..e0868a901c4a 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -503,20 +503,19 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size) | |||
503 | } | 503 | } |
504 | 504 | ||
505 | static void | 505 | static void |
506 | perf_evsel__config_callgraph(struct perf_evsel *evsel, | 506 | perf_evsel__config_callgraph(struct perf_evsel *evsel) |
507 | struct record_opts *opts) | ||
508 | { | 507 | { |
509 | bool function = perf_evsel__is_function_event(evsel); | 508 | bool function = perf_evsel__is_function_event(evsel); |
510 | struct perf_event_attr *attr = &evsel->attr; | 509 | struct perf_event_attr *attr = &evsel->attr; |
511 | 510 | ||
512 | perf_evsel__set_sample_bit(evsel, CALLCHAIN); | 511 | perf_evsel__set_sample_bit(evsel, CALLCHAIN); |
513 | 512 | ||
514 | if (opts->call_graph == CALLCHAIN_DWARF) { | 513 | if (callchain_param.record_mode == CALLCHAIN_DWARF) { |
515 | if (!function) { | 514 | if (!function) { |
516 | perf_evsel__set_sample_bit(evsel, REGS_USER); | 515 | perf_evsel__set_sample_bit(evsel, REGS_USER); |
517 | perf_evsel__set_sample_bit(evsel, STACK_USER); | 516 | perf_evsel__set_sample_bit(evsel, STACK_USER); |
518 | attr->sample_regs_user = PERF_REGS_MASK; | 517 | attr->sample_regs_user = PERF_REGS_MASK; |
519 | attr->sample_stack_user = opts->stack_dump_size; | 518 | attr->sample_stack_user = callchain_param.dump_size; |
520 | attr->exclude_callchain_user = 1; | 519 | attr->exclude_callchain_user = 1; |
521 | } else { | 520 | } else { |
522 | pr_info("Cannot use DWARF unwind for function trace event," | 521 | pr_info("Cannot use DWARF unwind for function trace event," |
@@ -625,8 +624,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) | |||
625 | attr->mmap_data = track; | 624 | attr->mmap_data = track; |
626 | } | 625 | } |
627 | 626 | ||
628 | if (opts->call_graph_enabled && !evsel->no_aux_samples) | 627 | if (callchain_param.enabled && !evsel->no_aux_samples) |
629 | perf_evsel__config_callgraph(evsel, opts); | 628 | perf_evsel__config_callgraph(evsel); |
630 | 629 | ||
631 | if (target__has_cpu(&opts->target)) | 630 | if (target__has_cpu(&opts->target)) |
632 | perf_evsel__set_sample_bit(evsel, CPU); | 631 | perf_evsel__set_sample_bit(evsel, CPU); |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 6d2d50dea1d8..883406f4b381 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -119,7 +119,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
119 | * kernel MMAP event, in perf_event__process_mmap(). | 119 | * kernel MMAP event, in perf_event__process_mmap(). |
120 | */ | 120 | */ |
121 | if (perf_session__create_kernel_maps(session) < 0) | 121 | if (perf_session__create_kernel_maps(session) < 0) |
122 | goto out_delete; | 122 | pr_warning("Cannot read kernel map\n"); |
123 | } | 123 | } |
124 | 124 | ||
125 | if (tool && tool->ordering_requires_timestamps && | 125 | if (tool && tool->ordering_requires_timestamps && |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 8dd41cad2d59..ffb440462008 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -126,5 +126,5 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session, | |||
126 | 126 | ||
127 | extern volatile int session_done; | 127 | extern volatile int session_done; |
128 | 128 | ||
129 | #define session_done() (*(volatile int *)(&session_done)) | 129 | #define session_done() ACCESS_ONCE(session_done) |
130 | #endif /* __PERF_SESSION_H */ | 130 | #endif /* __PERF_SESSION_H */ |