From 4bbac9a1f58fb74b436fbef43ec16017a580019a Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 22 Apr 2022 19:23:42 +0300 Subject: libperf evsel: Factor out perf_evsel__ioctl() Factor out perf_evsel__ioctl() so it can be reused. Signed-off-by: Adrian Hunter Cc: Alexey Bayduraev Cc: Ian Rogers Cc: Jiri Olsa Cc: Leo Yan Cc: Namhyung Kim Link: http://lore.kernel.org/lkml/20220422162402.147958-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/evsel.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'tools/lib') diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c index 210ea7c06ce8..20ae9f5f8b30 100644 --- a/tools/lib/perf/evsel.c +++ b/tools/lib/perf/evsel.c @@ -328,6 +328,17 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu_map_idx, int thread, return 0; } +static int perf_evsel__ioctl(struct perf_evsel *evsel, int ioc, void *arg, + int cpu_map_idx, int thread) +{ + int *fd = FD(evsel, cpu_map_idx, thread); + + if (fd == NULL || *fd < 0) + return -1; + + return ioctl(*fd, ioc, arg); +} + static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ioc, void *arg, int cpu_map_idx) @@ -335,13 +346,7 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int thread; for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { - int err; - int *fd = FD(evsel, cpu_map_idx, thread); - - if (fd == NULL || *fd < 0) - return -1; - - err = ioctl(*fd, ioc, arg); + int err = perf_evsel__ioctl(evsel, ioc, arg, cpu_map_idx, thread); if (err) return err; -- cgit v1.2.3 From 33cd6928039c6bf18cf0baec936924d908e6c89b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 2 May 2022 21:17:53 -0700 Subject: perf evlist: Clear all_cpus before propagating all_cpus is merged into during propagation. Initially all_cpus is set from PMU sysfs. perf_evlist__set_maps() will recompute it and change evsel->cpus to user_requested_cpus if they are given. If all_cpus isn't cleared then the union of the user_requested_cpus and PMU sysfs values is set to all_cpus, whereas just user_requested_cpus is necessary. To avoid this make all_cpus empty prior to propagation. Reviewed-by: Adrian Hunter Signed-off-by: Ian Rogers Cc: Alexander Antonov Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: German Gomez Cc: James Clark Cc: Jiri Olsa Cc: John Fastabend Cc: John Garry Cc: KP Singh Cc: Kajol Jain Cc: Leo Yan Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Stephane Eranian Cc: Suzuki Poulouse Cc: Will Deacon Cc: Yonghong Song Link: http://lore.kernel.org/lkml/20220503041757.2365696-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/evlist.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/lib') diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index a09315538a30..974b4585f93e 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -59,6 +59,10 @@ static void perf_evlist__propagate_maps(struct perf_evlist *evlist) { struct perf_evsel *evsel; + /* Recomputing all_cpus, so start with a blank slate. */ + perf_cpu_map__put(evlist->all_cpus); + evlist->all_cpus = NULL; + perf_evlist__for_each_evsel(evlist, evsel) __perf_evlist__propagate_maps(evlist, evsel); } -- cgit v1.2.3 From 00632610c2f0b732ae87b8c7e7e1375abaeb01a0 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 6 May 2022 15:25:40 +0300 Subject: libperf evsel: Add perf_evsel__enable_thread() Add perf_evsel__enable_thread() as a counterpart to perf_evsel__enable_cpu(), to enable all events for a thread. Signed-off-by: Adrian Hunter Acked-by: Ian Rogers Cc: Alexey Bayduraev Cc: Jiri Olsa Cc: Leo Yan Cc: Namhyung Kim Link: http://lore.kernel.org/lkml/20220506122601.367589-3-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/evsel.c | 15 +++++++++++++++ tools/lib/perf/include/perf/evsel.h | 1 + 2 files changed, 16 insertions(+) (limited to 'tools/lib') diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c index 20ae9f5f8b30..c1d58673f6ef 100644 --- a/tools/lib/perf/evsel.c +++ b/tools/lib/perf/evsel.c @@ -360,6 +360,21 @@ int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx) return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, cpu_map_idx); } +int perf_evsel__enable_thread(struct perf_evsel *evsel, int thread) +{ + struct perf_cpu cpu __maybe_unused; + int idx; + int err; + + perf_cpu_map__for_each_cpu(cpu, idx, evsel->cpus) { + err = perf_evsel__ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, idx, thread); + if (err) + return err; + } + + return 0; +} + int perf_evsel__enable(struct perf_evsel *evsel) { int i; diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h index 2a9516b42d15..699c0ed97d34 100644 --- a/tools/lib/perf/include/perf/evsel.h +++ b/tools/lib/perf/include/perf/evsel.h @@ -36,6 +36,7 @@ LIBPERF_API int perf_evsel__read(struct perf_evsel *evsel, int cpu_map_idx, int struct perf_counts_values *count); LIBPERF_API int perf_evsel__enable(struct perf_evsel *evsel); LIBPERF_API int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx); +LIBPERF_API int perf_evsel__enable_thread(struct perf_evsel *evsel, int thread); LIBPERF_API int perf_evsel__disable(struct perf_evsel *evsel); LIBPERF_API int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx); LIBPERF_API struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel); -- cgit v1.2.3 From 6a7b8a5a30e60e27cd2489af3d0a441280b441e6 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 6 May 2022 15:25:44 +0300 Subject: libperf evlist: Remove ->idx() per_cpu parameter Remove ->idx() per_cpu parameter because it isn't needed. Signed-off-by: Adrian Hunter Acked-by: Ian Rogers Cc: Alexey Bayduraev Cc: Jiri Olsa Cc: Leo Yan Cc: Namhyung Kim Link: http://lore.kernel.org/lkml/20220506122601.367589-7-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/evlist.c | 4 ++-- tools/lib/perf/include/internal/evlist.h | 2 +- tools/perf/util/evlist.c | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'tools/lib') diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index 974b4585f93e..5e8ad854fa8a 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -521,7 +521,7 @@ mmap_per_thread(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, int output_overwrite = -1; if (ops->idx) - ops->idx(evlist, mp, thread, false); + ops->idx(evlist, mp, thread); if (mmap_per_evsel(evlist, ops, thread, mp, 0, thread, &output, &output_overwrite)) @@ -548,7 +548,7 @@ mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, int output_overwrite = -1; if (ops->idx) - ops->idx(evlist, mp, cpu, true); + ops->idx(evlist, mp, cpu); for (thread = 0; thread < nr_threads; thread++) { if (mmap_per_evsel(evlist, ops, cpu, mp, cpu, diff --git a/tools/lib/perf/include/internal/evlist.h b/tools/lib/perf/include/internal/evlist.h index e3e64f37db7b..0d5c830431a7 100644 --- a/tools/lib/perf/include/internal/evlist.h +++ b/tools/lib/perf/include/internal/evlist.h @@ -38,7 +38,7 @@ struct perf_evlist { }; typedef void -(*perf_evlist_mmap__cb_idx_t)(struct perf_evlist*, struct perf_mmap_param*, int, bool); +(*perf_evlist_mmap__cb_idx_t)(struct perf_evlist*, struct perf_mmap_param*, int); typedef struct perf_mmap* (*perf_evlist_mmap__cb_get_t)(struct perf_evlist*, bool, int); typedef int diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f1309b39afe4..09a1d3400fd9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -748,10 +748,11 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, static void perf_evlist__mmap_cb_idx(struct perf_evlist *_evlist, struct perf_mmap_param *_mp, - int idx, bool per_cpu) + int idx) { struct evlist *evlist = container_of(_evlist, struct evlist, core); struct mmap_params *mp = container_of(_mp, struct mmap_params, core); + bool per_cpu = !perf_cpu_map__empty(_evlist->user_requested_cpus); auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, idx, per_cpu); } -- cgit v1.2.3 From d8fe2efb65acdc213eb180b7853fc1121c1bff37 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 6 May 2022 15:25:45 +0300 Subject: libperf evlist: Move ->idx() into mmap_per_evsel() Move ->idx() into mmap_per_evsel() in preparation for adding evsel as a parameter. Signed-off-by: Adrian Hunter Acked-by: Ian Rogers Cc: Alexey Bayduraev Cc: Jiri Olsa Cc: Leo Yan Cc: Namhyung Kim Link: http://lore.kernel.org/lkml/20220506122601.367589-8-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/evlist.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'tools/lib') diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index 5e8ad854fa8a..4fce417432aa 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -478,6 +478,9 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, */ refcount_set(&map->refcnt, 2); + if (ops->idx) + ops->idx(evlist, mp, idx); + if (ops->mmap(map, mp, *output, evlist_cpu) < 0) return -1; @@ -520,9 +523,6 @@ mmap_per_thread(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, int output = -1; int output_overwrite = -1; - if (ops->idx) - ops->idx(evlist, mp, thread); - if (mmap_per_evsel(evlist, ops, thread, mp, 0, thread, &output, &output_overwrite)) goto out_unmap; @@ -547,9 +547,6 @@ mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, int output = -1; int output_overwrite = -1; - if (ops->idx) - ops->idx(evlist, mp, cpu); - for (thread = 0; thread < nr_threads; thread++) { if (mmap_per_evsel(evlist, ops, cpu, mp, cpu, thread, &output, &output_overwrite)) -- cgit v1.2.3 From 8f111be6434de90c9743ea522c32b384d203a8de Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 6 May 2022 15:25:46 +0300 Subject: libperf evlist: Add evsel as a parameter to ->idx() Add evsel as a parameter to ->idx() in preparation for correctly determining whether an auxtrace mmap is needed. Signed-off-by: Adrian Hunter Acked-by: Ian Rogers Cc: Alexey Bayduraev Cc: Jiri Olsa Cc: Leo Yan Cc: Namhyung Kim Link: http://lore.kernel.org/lkml/20220506122601.367589-9-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/evlist.c | 2 +- tools/lib/perf/include/internal/evlist.h | 3 ++- tools/perf/util/evlist.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/lib') diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index 4fce417432aa..ed66f2e38464 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -479,7 +479,7 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, refcount_set(&map->refcnt, 2); if (ops->idx) - ops->idx(evlist, mp, idx); + ops->idx(evlist, evsel, mp, idx); if (ops->mmap(map, mp, *output, evlist_cpu) < 0) return -1; diff --git a/tools/lib/perf/include/internal/evlist.h b/tools/lib/perf/include/internal/evlist.h index 0d5c830431a7..6f89aec3e608 100644 --- a/tools/lib/perf/include/internal/evlist.h +++ b/tools/lib/perf/include/internal/evlist.h @@ -38,7 +38,8 @@ struct perf_evlist { }; typedef void -(*perf_evlist_mmap__cb_idx_t)(struct perf_evlist*, struct perf_mmap_param*, int); +(*perf_evlist_mmap__cb_idx_t)(struct perf_evlist*, struct perf_evsel*, + struct perf_mmap_param*, int); typedef struct perf_mmap* (*perf_evlist_mmap__cb_get_t)(struct perf_evlist*, bool, int); typedef int diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 09a1d3400fd9..7ae56b062f44 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -747,6 +747,7 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, static void perf_evlist__mmap_cb_idx(struct perf_evlist *_evlist, + struct perf_evsel *_evsel __maybe_unused, struct perf_mmap_param *_mp, int idx) { -- cgit v1.2.3 From e696f6dbbf9d5c88922a4e2c9ee2ed9b495285ca Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 18 May 2022 20:20:03 -0700 Subject: perf cpumap: Add perf_cpu_map__for_each_idx() A variant of perf_cpu_map__for_each_cpu() that just iterates index values without the corresponding load of the CPU. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Dave Marchevsky Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Kan Liang Cc: Lv Ruyi Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Quentin Monnet Cc: Song Liu Cc: Stephane Eranian Cc: Xing Zhengjun Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20220519032005.1273691-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/include/perf/cpumap.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/lib') diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h index 4a2edbdb5e2b..24de795b09bb 100644 --- a/tools/lib/perf/include/perf/cpumap.h +++ b/tools/lib/perf/include/perf/cpumap.h @@ -31,4 +31,7 @@ LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_c (idx) < perf_cpu_map__nr(cpus); \ (idx)++, (cpu) = perf_cpu_map__cpu(cpus, idx)) +#define perf_cpu_map__for_each_idx(idx, cpus) \ + for ((idx) = 0; (idx) < perf_cpu_map__nr(cpus); (idx)++) + #endif /* __LIBPERF_CPUMAP_H */ -- cgit v1.2.3 From 618ee7838e409513635320ca9c4c8d52c44f2dd0 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 20 May 2022 18:56:04 +0300 Subject: libperf: Add preadn() Add preadn() to provide pread() and readn() semantics. Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Cc: Namhyung Kim Link: https://lore.kernel.org/r/ab8918a4-7ac8-a37e-2e2c-28438c422d87@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/include/internal/lib.h | 2 ++ tools/lib/perf/lib.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'tools/lib') diff --git a/tools/lib/perf/include/internal/lib.h b/tools/lib/perf/include/internal/lib.h index 5175d491b2d4..85471a4b900f 100644 --- a/tools/lib/perf/include/internal/lib.h +++ b/tools/lib/perf/include/internal/lib.h @@ -9,4 +9,6 @@ extern unsigned int page_size; ssize_t readn(int fd, void *buf, size_t n); ssize_t writen(int fd, const void *buf, size_t n); +ssize_t preadn(int fd, void *buf, size_t n, off_t offs); + #endif /* __LIBPERF_INTERNAL_CPUMAP_H */ diff --git a/tools/lib/perf/lib.c b/tools/lib/perf/lib.c index 18658931fc71..696fb0ea67c6 100644 --- a/tools/lib/perf/lib.c +++ b/tools/lib/perf/lib.c @@ -38,6 +38,26 @@ ssize_t readn(int fd, void *buf, size_t n) return ion(true, fd, buf, n); } +ssize_t preadn(int fd, void *buf, size_t n, off_t offs) +{ + size_t left = n; + + while (left) { + ssize_t ret = pread(fd, buf, left, offs); + + if (ret < 0 && errno == EINTR) + continue; + if (ret <= 0) + return ret; + + left -= ret; + buf += ret; + offs += ret; + } + + return n; +} + /* * Write exactly 'n' bytes or return an error. */ -- cgit v1.2.3