perf evsel: Mark a evsel as disabled when asking the kernel do disable it
authorArnaldo Carvalho de Melo <acme@redhat.com>
Sat, 20 Oct 2018 12:04:41 +0000 (09:04 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 22 Oct 2018 15:37:45 +0000 (12:37 -0300)
Because there may be more such events in the ring buffer that should be
discarded when an app decides to stop considering them.

At some point we'll do this with eBPF, this way we stop them at origin,
before they are placed in the ring buffer.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-uzufuxws4hufigx07ue1dpv6@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/evlist.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h

index be440df296150450b4e99e2ab2c5ab83175d29aa..e88e6f9b1463f0674a0eaf12423b35978e58d8da 100644 (file)
@@ -358,7 +358,7 @@ void perf_evlist__disable(struct perf_evlist *evlist)
        struct perf_evsel *pos;
 
        evlist__for_each_entry(evlist, pos) {
-               if (!perf_evsel__is_group_leader(pos) || !pos->fd)
+               if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->fd)
                        continue;
                perf_evsel__disable(pos);
        }
index 7e95ec1c19a828cfdce2a7755f11bcb7b89e4f55..6d187059a37360ae669220c913c535b1278d6514 100644 (file)
@@ -1207,16 +1207,27 @@ int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter)
 
 int perf_evsel__enable(struct perf_evsel *evsel)
 {
-       return perf_evsel__run_ioctl(evsel,
-                                    PERF_EVENT_IOC_ENABLE,
-                                    0);
+       int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0);
+
+       if (!err)
+               evsel->disabled = false;
+
+       return err;
 }
 
 int perf_evsel__disable(struct perf_evsel *evsel)
 {
-       return perf_evsel__run_ioctl(evsel,
-                                    PERF_EVENT_IOC_DISABLE,
-                                    0);
+       int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0);
+       /*
+        * We mark it disabled here so that tools that disable a event can
+        * ignore events after they disable it. I.e. the ring buffer may have
+        * already a few more events queued up before the kernel got the stop
+        * request.
+        */
+       if (!err)
+               evsel->disabled = true;
+
+       return err;
 }
 
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
index ad5d615c6db6494dc499e77fe1a71aecb0e49b64..4ef50f157b50bdb623b87446210d3113df928e6b 100644 (file)
@@ -122,6 +122,7 @@ struct perf_evsel {
        bool                    snapshot;
        bool                    supported;
        bool                    needs_swap;
+       bool                    disabled;
        bool                    no_aux_samples;
        bool                    immediate;
        bool                    system_wide;