]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
perf unwind: Do not look just at the global callchain_param.record_mode
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 15 Jan 2018 19:48:46 +0000 (16:48 -0300)
committerKhalid Elmously <khalid.elmously@canonical.com>
Wed, 6 Jun 2018 17:44:25 +0000 (13:44 -0400)
BugLink: http://bugs.launchpad.net/bugs/1774063
[ Upstream commit eabad8c6856f185f876b54c426c2cc69fe0f0a7d ]

When setting up DWARF callchains on specific events, without using
'record' or 'trace' --call-graph, but instead doing it like:

perf trace -e cycles/call-graph=dwarf/

The unwind__prepare_access() call in thread__insert_map() when we
process PERF_RECORD_MMAP(2) metadata events were not being performed,
precluding us from using per-event DWARF callchains, handling them just
when we asked for all events to be DWARF, using "--call-graph dwarf".

We do it in the PERF_RECORD_MMAP because we have to look at one of the
executable maps to figure out the executable type (64-bit, 32-bit) of
the DSO laid out in that mmap. Also to look at the architecture where
the perf.data file was recorded.

All this probably should be deferred to when we process a sample for
some thread that has callchains, so that we do this processing only for
the threads with samples, not for all of them.

For now, fix using DWARF on specific events.

Before:

  # perf trace --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
  PING ::1(::1) 56 data bytes
  64 bytes from ::1: icmp_seq=1 ttl=64 time=0.048 ms

  --- ::1 ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 0.048/0.048/0.048/0.000 ms
     0.000 probe_libc:inet_pton:(7fe9597bb350))
  Problem processing probe_libc:inet_pton callchain, skipping...
  #

After:

  # perf trace --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
  PING ::1(::1) 56 data bytes
  64 bytes from ::1: icmp_seq=1 ttl=64 time=0.060 ms

  --- ::1 ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 0.060/0.060/0.060/0.000 ms
       0.000 probe_libc:inet_pton:(7fd4aa930350))
                                         __inet_pton (inlined)
                                         gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
                                         __GI_getaddrinfo (inlined)
                                         [0xffffaa804e51af3f] (/usr/bin/ping)
                                         __libc_start_main (/usr/lib64/libc-2.26.so)
                                         [0xffffaa804e51b379] (/usr/bin/ping)
  #
  # perf trace --call-graph=dwarf --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
  PING ::1(::1) 56 data bytes
  64 bytes from ::1: icmp_seq=1 ttl=64 time=0.057 ms

  --- ::1 ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 0.057/0.057/0.057/0.000 ms
       0.000 probe_libc:inet_pton:(7f9363b9e350))
                                         __inet_pton (inlined)
                                         gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
                                         __GI_getaddrinfo (inlined)
                                         [0xffffa9e8a14e0f3f] (/usr/bin/ping)
                                         __libc_start_main (/usr/lib64/libc-2.26.so)
                                         [0xffffa9e8a14e1379] (/usr/bin/ping)
  #
  # perf trace --call-graph=fp --no-syscalls -e probe_libc:inet_pton/call-graph=dwarf/ ping -6 -c 1 ::1
  PING ::1(::1) 56 data bytes
  64 bytes from ::1: icmp_seq=1 ttl=64 time=0.077 ms

  --- ::1 ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 0.077/0.077/0.077/0.000 ms
       0.000 probe_libc:inet_pton:(7f4947e1c350))
                                         __inet_pton (inlined)
                                         gaih_inet.constprop.7 (/usr/lib64/libc-2.26.so)
                                         __GI_getaddrinfo (inlined)
                                         [0xffffaa716d88ef3f] (/usr/bin/ping)
                                         __libc_start_main (/usr/lib64/libc-2.26.so)
                                         [0xffffaa716d88f379] (/usr/bin/ping)
  #
  # perf trace --no-syscalls -e probe_libc:inet_pton/call-graph=fp/ ping -6 -c 1 ::1
  PING ::1(::1) 56 data bytes
  64 bytes from ::1: icmp_seq=1 ttl=64 time=0.078 ms

  --- ::1 ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 0.078/0.078/0.078/0.000 ms
       0.000 probe_libc:inet_pton:(7fa157696350))
                                         __GI___inet_pton (/usr/lib64/libc-2.26.so)
                                         getaddrinfo (/usr/lib64/libc-2.26.so)
                                         [0xffffa9ba39c74f40] (/usr/bin/ping)
  #

Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hendrick Brueckner <brueckner@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Thomas Richter <tmricht@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/r/20180116182650.GE16107@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
tools/perf/builtin-c2c.c
tools/perf/builtin-report.c
tools/perf/builtin-script.c
tools/perf/tests/dwarf-unwind.c
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/unwind-libunwind-local.c

index 17855c4626a08b7d4add1b5c9922653a5be39ad4..c8a5faaca47f4a24680fe20aefb2b4b239809fc7 100644 (file)
@@ -2393,9 +2393,10 @@ static int setup_callchain(struct perf_evlist *evlist)
        enum perf_call_graph_mode mode = CALLCHAIN_NONE;
 
        if ((sample_type & PERF_SAMPLE_REGS_USER) &&
-           (sample_type & PERF_SAMPLE_STACK_USER))
+           (sample_type & PERF_SAMPLE_STACK_USER)) {
                mode = CALLCHAIN_DWARF;
-       else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
+               dwarf_callchain_users = true;
+       } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
                mode = CALLCHAIN_LBR;
        else if (sample_type & PERF_SAMPLE_CALLCHAIN)
                mode = CALLCHAIN_FP;
index 0551a69bd4a5b8b7e76595e936b30f65ee0a987d..d000c0526fc9c4365a2b74fa3cfc37fa793b3310 100644 (file)
@@ -328,9 +328,10 @@ static int report__setup_sample_type(struct report *rep)
 
        if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
                if ((sample_type & PERF_SAMPLE_REGS_USER) &&
-                   (sample_type & PERF_SAMPLE_STACK_USER))
+                   (sample_type & PERF_SAMPLE_STACK_USER)) {
                        callchain_param.record_mode = CALLCHAIN_DWARF;
-               else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
+                       dwarf_callchain_users = true;
+               } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
                        callchain_param.record_mode = CALLCHAIN_LBR;
                else
                        callchain_param.record_mode = CALLCHAIN_FP;
index 9b43bda45a415649a06c7b9743796bff7b760dbe..fc3974b1d8fdbfd7d9ebd977e53660f7b337ef16 100644 (file)
@@ -2758,9 +2758,10 @@ static void script__setup_sample_type(struct perf_script *script)
 
        if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
                if ((sample_type & PERF_SAMPLE_REGS_USER) &&
-                   (sample_type & PERF_SAMPLE_STACK_USER))
+                   (sample_type & PERF_SAMPLE_STACK_USER)) {
                        callchain_param.record_mode = CALLCHAIN_DWARF;
-               else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
+                       dwarf_callchain_users = true;
+               } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
                        callchain_param.record_mode = CALLCHAIN_LBR;
                else
                        callchain_param.record_mode = CALLCHAIN_FP;
index ac40e05bcab4292d52f971ad02c1c2857d049d6f..260418969120fd2c4d2eff6ab3742539589c8d9c 100644 (file)
@@ -173,6 +173,7 @@ int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unu
        }
 
        callchain_param.record_mode = CALLCHAIN_DWARF;
+       dwarf_callchain_users = true;
 
        if (init_live_machine(machine)) {
                pr_err("Could not init machine\n");
index 082505d08d720b18cae0051591b087bb86e6e456..32ef7bdca1cf8cbf6e29cb6e5bbe8220230bf569 100644 (file)
@@ -37,6 +37,15 @@ struct callchain_param callchain_param = {
        CALLCHAIN_PARAM_DEFAULT
 };
 
+/*
+ * Are there any events usind DWARF callchains?
+ *
+ * I.e.
+ *
+ * -e cycles/call-graph=dwarf/
+ */
+bool dwarf_callchain_users;
+
 struct callchain_param callchain_param_default = {
        CALLCHAIN_PARAM_DEFAULT
 };
@@ -265,6 +274,7 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
                        ret = 0;
                        param->record_mode = CALLCHAIN_DWARF;
                        param->dump_size = default_stack_dump_size;
+                       dwarf_callchain_users = true;
 
                        tok = strtok_r(NULL, ",", &saveptr);
                        if (tok) {
index b79ef2478a575fd206e52cf4860f49230ae64930..154560b1eb653c42f722b291308313b6c675cc7f 100644 (file)
@@ -89,6 +89,8 @@ enum chain_value {
        CCVAL_COUNT,
 };
 
+extern bool dwarf_callchain_users;
+
 struct callchain_param {
        bool                    enabled;
        enum perf_call_graph_mode record_mode;
index 7a42f703e858b7830bcfde8dd69d0bbe71764dd3..af873044d33a234e3f4237cda3d8f90943534a9b 100644 (file)
@@ -631,9 +631,8 @@ static unw_accessors_t accessors = {
 
 static int _unwind__prepare_access(struct thread *thread)
 {
-       if (callchain_param.record_mode != CALLCHAIN_DWARF)
+       if (!dwarf_callchain_users)
                return 0;
-
        thread->addr_space = unw_create_addr_space(&accessors, 0);
        if (!thread->addr_space) {
                pr_err("unwind: Can't create unwind address space.\n");
@@ -646,17 +645,15 @@ static int _unwind__prepare_access(struct thread *thread)
 
 static void _unwind__flush_access(struct thread *thread)
 {
-       if (callchain_param.record_mode != CALLCHAIN_DWARF)
+       if (!dwarf_callchain_users)
                return;
-
        unw_flush_cache(thread->addr_space, 0, 0);
 }
 
 static void _unwind__finish_access(struct thread *thread)
 {
-       if (callchain_param.record_mode != CALLCHAIN_DWARF)
+       if (!dwarf_callchain_users)
                return;
-
        unw_destroy_addr_space(thread->addr_space);
 }