perf evsel: Probe for precise_ip with simple attr
authorJiri Olsa <jolsa@kernel.org>
Tue, 5 Mar 2019 15:25:34 +0000 (16:25 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 6 Mar 2019 21:19:45 +0000 (18:19 -0300)
Currently we probe for precise_ip with user specified perf_event_attr,
which might fail because of unsupported kernel features, which would get
disabled during the open time anyway.

Switching the probe to take place on simple hw cycles, so the following
record sets proper precise_ip:

  # perf record -e cycles:P ls
  # perf evlist -v
  cycles:P: size: 112, ... precise_ip: 3, ...

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jonas Rabenstein <jonas.rabenstein@studium.uni-erlangen.de>
Cc: Nageswara R Sastry <nasastry@in.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Link: http://lkml.kernel.org/r/20190305152536.21035-7-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/evlist.c
tools/perf/util/evsel.c

index 08cedb643ea6ec3d7ec8255895bdc45ec9880f68..ed20f4379956594a908299f08c9d2ef4ac140dc2 100644 (file)
@@ -230,18 +230,33 @@ void perf_evlist__set_leader(struct perf_evlist *evlist)
        }
 }
 
-void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr)
+void perf_event_attr__set_max_precise_ip(struct perf_event_attr *pattr)
 {
-       attr->precise_ip = 3;
+       struct perf_event_attr attr = {
+               .type           = PERF_TYPE_HARDWARE,
+               .config         = PERF_COUNT_HW_CPU_CYCLES,
+               .exclude_kernel = 1,
+               .precise_ip     = 3,
+       };
 
-       while (attr->precise_ip != 0) {
-               int fd = sys_perf_event_open(attr, 0, -1, -1, 0);
+       event_attr_init(&attr);
+
+       /*
+        * Unnamed union member, not supported as struct member named
+        * initializer in older compilers such as gcc 4.4.7
+        */
+       attr.sample_period = 1;
+
+       while (attr.precise_ip != 0) {
+               int fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
                if (fd != -1) {
                        close(fd);
                        break;
                }
-               --attr->precise_ip;
+               --attr.precise_ip;
        }
+
+       pattr->precise_ip = attr.precise_ip;
 }
 
 int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise)
index dfe2958e628762c1f089e65b1653fe4dd3c97abe..3bbf73e979c00aa4f9c363e9d224440190425457 100644 (file)
@@ -294,20 +294,12 @@ struct perf_evsel *perf_evsel__new_cycles(bool precise)
 
        if (!precise)
                goto new_event;
-       /*
-        * Unnamed union member, not supported as struct member named
-        * initializer in older compilers such as gcc 4.4.7
-        *
-        * Just for probing the precise_ip:
-        */
-       attr.sample_period = 1;
 
        perf_event_attr__set_max_precise_ip(&attr);
        /*
         * Now let the usual logic to set up the perf_event_attr defaults
         * to kick in when we return and before perf_evsel__open() is called.
         */
-       attr.sample_period = 0;
 new_event:
        evsel = perf_evsel__new(&attr);
        if (evsel == NULL)