aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/perf/lib
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2019-09-03 11:19:56 +0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-09-25 09:51:48 -0300
commitd5a99483dece17dbde01968a7ffc03b7f575dc11 (patch)
treecf5fa8010b6088a8a3182f2d41eda07483d1871c /tools/perf/lib
parentlibperf: Add perf_evlist__id_add() function (diff)
downloadwireguard-linux-d5a99483dece17dbde01968a7ffc03b7f575dc11.tar.xz
wireguard-linux-d5a99483dece17dbde01968a7ffc03b7f575dc11.zip
libperf: Add perf_evlist__id_add_fd() function
Add the perf_evlist__id_add_fd() function to libperf as an internal function. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lore.kernel.org/lkml/20190913132355.21634-32-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/lib')
-rw-r--r--tools/perf/lib/evlist.c44
-rw-r--r--tools/perf/lib/include/internal/evlist.h4
2 files changed, 48 insertions, 0 deletions
diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c
index a29ee8a746d9..3a16dd0c044f 100644
--- a/tools/perf/lib/evlist.c
+++ b/tools/perf/lib/evlist.c
@@ -4,11 +4,14 @@
#include <linux/bitops.h>
#include <linux/list.h>
#include <linux/hash.h>
+#include <sys/ioctl.h>
#include <internal/evlist.h>
#include <internal/evsel.h>
#include <internal/xyarray.h>
#include <linux/zalloc.h>
#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
#include <perf/cpumap.h>
#include <perf/threadmap.h>
@@ -194,3 +197,44 @@ void perf_evlist__id_add(struct perf_evlist *evlist,
perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
evsel->id[evsel->ids++] = id;
}
+
+int perf_evlist__id_add_fd(struct perf_evlist *evlist,
+ struct perf_evsel *evsel,
+ int cpu, int thread, int fd)
+{
+ u64 read_data[4] = { 0, };
+ int id_idx = 1; /* The first entry is the counter value */
+ u64 id;
+ int ret;
+
+ ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
+ if (!ret)
+ goto add;
+
+ if (errno != ENOTTY)
+ return -1;
+
+ /* Legacy way to get event id.. All hail to old kernels! */
+
+ /*
+ * This way does not work with group format read, so bail
+ * out in that case.
+ */
+ if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
+ return -1;
+
+ if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
+ read(fd, &read_data, sizeof(read_data)) == -1)
+ return -1;
+
+ if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+ ++id_idx;
+ if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+ ++id_idx;
+
+ id = read_data[id_idx];
+
+add:
+ perf_evlist__id_add(evlist, evsel, cpu, thread, id);
+ return 0;
+}
diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h
index 649406f717bc..7d64185cfabd 100644
--- a/tools/perf/lib/include/internal/evlist.h
+++ b/tools/perf/lib/include/internal/evlist.h
@@ -72,4 +72,8 @@ void perf_evlist__id_add(struct perf_evlist *evlist,
struct perf_evsel *evsel,
int cpu, int thread, u64 id);
+int perf_evlist__id_add_fd(struct perf_evlist *evlist,
+ struct perf_evsel *evsel,
+ int cpu, int thread, int fd);
+
#endif /* __LIBPERF_INTERNAL_EVLIST_H */