* [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events
@ 2024-07-27 5:29 Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 1/8] libperf: Move 'open_flags' from tools/perf to evsel::open_flags Charlie Jenkins
` (7 more replies)
0 siblings, 8 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
I was going to send a similar series but after looking through the
mailing list found this approach which fits my use-case exactly. I have
rebased the series and applied the suggestions from Namhyung. The
original cover letter with minor changes follows.
This patch series adds interface for overflow check of sampling events
to libperf.
First patch move 'open_flags' from tools/perf to evsel::open_flags.
Second patch extracts out the opts used by BPF into a common header to
be used by perf.
Third patch introduce perf_{evsel, evlist}__open_opt() with extensible
structure opts.
Fourth patch adds support for overflow handling of sampling events.
Fifth patch adds a interface to check overflowed events.
Sixth patch adds a interface to perform IOC_REFRESH and IOC_PERIOD.
Seventh and eighth patch adds tests.
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
Previous version at:
https://lore.kernel.org/lkml/20220422093833.340873-1-nakamura.shun@fujitsu.com/
Changes in v2:
- Rebase onto v6.10
- Add a patch to move BPF opts helpers into a global include
- Renamed flags to fcntl_flags
- Changed signal type to int
- Add comment to owner_type member
- Add _cpu to perf_evsel__run_fcntl
- Rename sig to sigact
- Remove "!" from owner.type check
- Removed _GNU_SOURCE addition
- Removed null check for perf_evsel__attr()
- Make timeouts consistent between test-evlist.c and test-evsel.c
Changes in v1:
- Move initialization/reference of evsel->open_flags from the first
patch to the second patch
- Move signal-related handling and related fields of the opts
structure from the second patch to the third patch
- Move _GNU_SOURCE from test-evlist.c to Makefile
- Delete *_cpu() function
- Refactor the fourth patch
- Fix test to use real-time signals instead of standard signals
Changes in RFC v2:
- Delete perf_evsel__set_close_on_exec() function
- Introduce perf_{evsel, evlist}__open_opt() with extensible structure
opts
- Fix perf_evsel__set_signal() to a internal function
- Add bool type argument to perf_evsel__check_{fd, fd_cpu}() to indicate
overflow results
---
Charlie Jenkins (1):
libbpf: Move opts code into dedicated header
Shunsuke Nakamura (7):
libperf: Move 'open_flags' from tools/perf to evsel::open_flags
libperf: Introduce perf_{evsel, evlist}__open_opt with extensible struct opts
libperf: Add support for overflow handling of sampling events
libperf: Add perf_evsel__has_fd() functions
libperf: Add perf_evsel__{refresh, period}() functions
libperf test: Add test_stat_overflow()
libperf test: Add test_stat_overflow_event()
tools/include/tools/opts.h | 68 +++++++++++++
tools/lib/bpf/bpf.c | 1 +
tools/lib/bpf/btf.c | 1 +
tools/lib/bpf/btf_dump.c | 1 +
tools/lib/bpf/libbpf.c | 3 +-
tools/lib/bpf/libbpf_internal.h | 48 ---------
tools/lib/bpf/linker.c | 1 +
tools/lib/bpf/netlink.c | 1 +
tools/lib/bpf/ringbuf.c | 1 +
tools/lib/perf/Documentation/libperf.txt | 17 ++++
tools/lib/perf/Makefile | 1 +
tools/lib/perf/evlist.c | 20 ++++
tools/lib/perf/evsel.c | 169 +++++++++++++++++++++++++++++--
tools/lib/perf/include/internal/evsel.h | 2 +
tools/lib/perf/include/perf/evlist.h | 3 +
tools/lib/perf/include/perf/evsel.h | 30 ++++++
tools/lib/perf/libperf.map | 5 +
tools/lib/perf/tests/test-evlist.c | 112 +++++++++++++++++++-
tools/lib/perf/tests/test-evsel.c | 107 +++++++++++++++++++
tools/perf/util/evsel.c | 16 +--
tools/perf/util/evsel.h | 1 -
21 files changed, 541 insertions(+), 67 deletions(-)
---
base-commit: 0c3836482481200ead7b416ca80c68a29cfdaabd
change-id: 20240726-overflow_check_libperf-88ad144d4dca
--
- Charlie
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/8] libperf: Move 'open_flags' from tools/perf to evsel::open_flags
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 2/8] libbpf: Move opts code into dedicated header Charlie Jenkins
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
From: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Move evsel::open_flags to perf_evsel::open_flags, so we can move
the open_flags interface to libperf.
Signed-off-by: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/lib/perf/include/internal/evsel.h | 2 ++
tools/perf/util/evsel.c | 16 +++++++++-------
tools/perf/util/evsel.h | 1 -
3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/tools/lib/perf/include/internal/evsel.h b/tools/lib/perf/include/internal/evsel.h
index 5cd220a61962..1d0d0406793a 100644
--- a/tools/lib/perf/include/internal/evsel.h
+++ b/tools/lib/perf/include/internal/evsel.h
@@ -75,6 +75,8 @@ struct perf_evsel {
/** Is the PMU for the event a core one? Effects the handling of own_cpus. */
bool is_pmu_core;
int idx;
+
+ unsigned long open_flags;
};
void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 4f818ab6b662..65f0f83ada6d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1829,9 +1829,9 @@ static int __evsel__prepare_open(struct evsel *evsel, struct perf_cpu_map *cpus,
perf_evsel__alloc_fd(&evsel->core, perf_cpu_map__nr(cpus), nthreads) < 0)
return -ENOMEM;
- evsel->open_flags = PERF_FLAG_FD_CLOEXEC;
+ evsel->core.open_flags = PERF_FLAG_FD_CLOEXEC;
if (evsel->cgrp)
- evsel->open_flags |= PERF_FLAG_PID_CGROUP;
+ evsel->core.open_flags |= PERF_FLAG_PID_CGROUP;
return 0;
}
@@ -1853,7 +1853,7 @@ static void evsel__disable_missing_features(struct evsel *evsel)
evsel->core.attr.clockid = 0;
}
if (perf_missing_features.cloexec)
- evsel->open_flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC;
+ evsel->core.open_flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC;
if (perf_missing_features.mmap2)
evsel->core.attr.mmap2 = 0;
if (evsel->pmu && evsel->pmu->missing_features.exclude_guest)
@@ -1951,7 +1951,8 @@ bool evsel__detect_missing_features(struct evsel *evsel)
perf_missing_features.clockid = true;
pr_debug2_peo("switching off use_clockid\n");
return true;
- } else if (!perf_missing_features.cloexec && (evsel->open_flags & PERF_FLAG_FD_CLOEXEC)) {
+ } else if (!perf_missing_features.cloexec &&
+ (evsel->core.open_flags & PERF_FLAG_FD_CLOEXEC)) {
perf_missing_features.cloexec = true;
pr_debug2_peo("switching off cloexec flag\n");
return true;
@@ -2055,11 +2056,12 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
/* Debug message used by test scripts */
pr_debug2_peo("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx",
- pid, perf_cpu_map__cpu(cpus, idx).cpu, group_fd, evsel->open_flags);
+ pid, perf_cpu_map__cpu(cpus, idx).cpu, group_fd,
+ evsel->core.open_flags);
fd = sys_perf_event_open(&evsel->core.attr, pid,
perf_cpu_map__cpu(cpus, idx).cpu,
- group_fd, evsel->open_flags);
+ group_fd, evsel->core.open_flags);
FD(evsel, idx, thread) = fd;
@@ -2076,7 +2078,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
if (unlikely(test_attr__enabled)) {
test_attr__open(&evsel->core.attr, pid,
perf_cpu_map__cpu(cpus, idx),
- fd, group_fd, evsel->open_flags);
+ fd, group_fd, evsel->core.open_flags);
}
/* Debug message used by test scripts */
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 375a38e15cd9..2efda7ad8f96 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -165,7 +165,6 @@ struct evsel {
struct bperf_follower_bpf *follower_skel;
void *bpf_skel;
};
- unsigned long open_flags;
int precise_ip_original;
/* for missing_features */
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/8] libbpf: Move opts code into dedicated header
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 1/8] libperf: Move 'open_flags' from tools/perf to evsel::open_flags Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
2024-07-29 17:01 ` Andrii Nakryiko
2024-07-27 5:29 ` [PATCH v2 3/8] libperf: Introduce perf_{evsel, evlist}__open_opt with extensible struct opts Charlie Jenkins
` (5 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/include/tools/opts.h | 68 +++++++++++++++++++++++++++++++++++++++++
tools/lib/bpf/bpf.c | 1 +
tools/lib/bpf/btf.c | 1 +
tools/lib/bpf/btf_dump.c | 1 +
tools/lib/bpf/libbpf.c | 3 +-
tools/lib/bpf/libbpf_internal.h | 48 -----------------------------
tools/lib/bpf/linker.c | 1 +
tools/lib/bpf/netlink.c | 1 +
tools/lib/bpf/ringbuf.c | 1 +
9 files changed, 76 insertions(+), 49 deletions(-)
diff --git a/tools/include/tools/opts.h b/tools/include/tools/opts.h
new file mode 100644
index 000000000000..42b4c1a66cad
--- /dev/null
+++ b/tools/include/tools/opts.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
+
+/*
+ * Options helpers.
+ *
+ * Originally in tools/lib/bpf/libbpf_internal.h
+ */
+
+#ifndef __TOOLS_OPTS_H
+#define __TOOLS_OPTS_H
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifndef offsetofend
+#define offsetofend(TYPE, MEMBER) \
+ (offsetof(TYPE, MEMBER) + sizeof((((TYPE *)0)->MEMBER)))
+#endif
+
+static inline bool lib_is_mem_zeroed(const char *p, ssize_t len)
+{
+ while (len > 0) {
+ if (*p)
+ return false;
+ p++;
+ len--;
+ }
+ return true;
+}
+
+static inline bool lib_validate_opts(const char *opts,
+ size_t opts_sz, size_t user_sz,
+ const char *type_name)
+{
+ if (user_sz < sizeof(size_t)) {
+ fprintf(stderr, "%s size (%zu) is too small\n", type_name, user_sz);
+ return false;
+ }
+ if (!lib_is_mem_zeroed(opts + opts_sz, (ssize_t)user_sz - opts_sz)) {
+ fprintf(stderr, "%s has non-zero extra bytes\n", type_name);
+ return false;
+ }
+ return true;
+}
+
+#define OPTS_VALID(opts, type) \
+ (!(opts) || lib_validate_opts((const char *)opts, \
+ offsetofend(struct type, \
+ type##__last_field), \
+ (opts)->sz, #type))
+#define OPTS_HAS(opts, field) \
+ ((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
+#define OPTS_GET(opts, field, fallback_value) \
+ (OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
+#define OPTS_SET(opts, field, value) \
+ do { \
+ if (OPTS_HAS(opts, field)) \
+ (opts)->field = value; \
+ } while (0)
+
+#define OPTS_ZEROED(opts, last_nonzero_field) \
+({ \
+ ssize_t __off = offsetofend(typeof(*(opts)), last_nonzero_field); \
+ !(opts) || lib_is_mem_zeroed((const void *)opts + __off, \
+ (opts)->sz - __off); \
+})
+
+#endif /* __TOOLS_OPTS_H */
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 2a4c71501a17..089f0e0be3a2 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <limits.h>
#include <sys/resource.h>
+#include <tools/opts.h>
#include "bpf.h"
#include "libbpf.h"
#include "libbpf_internal.h"
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 2d0840ef599a..e03974de2f02 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/btf.h>
#include <gelf.h>
+#include <tools/opts.h>
#include "btf.h"
#include "bpf.h"
#include "libbpf.h"
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
index 5dbca76b953f..877479228954 100644
--- a/tools/lib/bpf/btf_dump.c
+++ b/tools/lib/bpf/btf_dump.c
@@ -17,6 +17,7 @@
#include <linux/err.h>
#include <linux/btf.h>
#include <linux/kernel.h>
+#include <tools/opts.h>
#include "btf.h"
#include "hashmap.h"
#include "libbpf.h"
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 5401f2df463d..97a47a3d4e51 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -43,6 +43,7 @@
#include <sys/vfs.h>
#include <sys/utsname.h>
#include <sys/resource.h>
+#include <tools/opts.h>
#include <libelf.h>
#include <gelf.h>
#include <zlib.h>
@@ -1146,7 +1147,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
kern_member = find_member_by_name(kern_btf, kern_type, mname);
if (!kern_member) {
- if (!libbpf_is_mem_zeroed(mdata, msize)) {
+ if (!lib_is_mem_zeroed(mdata, msize)) {
pr_warn("struct_ops init_kern %s: Cannot find member %s in kernel BTF\n",
map->name, mname);
return -ENOTSUP;
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index a0dcfb82e455..033b852ed9a7 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -283,54 +283,6 @@ void *libbpf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
size_t cur_cnt, size_t max_cnt, size_t add_cnt);
int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt);
-static inline bool libbpf_is_mem_zeroed(const char *p, ssize_t len)
-{
- while (len > 0) {
- if (*p)
- return false;
- p++;
- len--;
- }
- return true;
-}
-
-static inline bool libbpf_validate_opts(const char *opts,
- size_t opts_sz, size_t user_sz,
- const char *type_name)
-{
- if (user_sz < sizeof(size_t)) {
- pr_warn("%s size (%zu) is too small\n", type_name, user_sz);
- return false;
- }
- if (!libbpf_is_mem_zeroed(opts + opts_sz, (ssize_t)user_sz - opts_sz)) {
- pr_warn("%s has non-zero extra bytes\n", type_name);
- return false;
- }
- return true;
-}
-
-#define OPTS_VALID(opts, type) \
- (!(opts) || libbpf_validate_opts((const char *)opts, \
- offsetofend(struct type, \
- type##__last_field), \
- (opts)->sz, #type))
-#define OPTS_HAS(opts, field) \
- ((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
-#define OPTS_GET(opts, field, fallback_value) \
- (OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
-#define OPTS_SET(opts, field, value) \
- do { \
- if (OPTS_HAS(opts, field)) \
- (opts)->field = value; \
- } while (0)
-
-#define OPTS_ZEROED(opts, last_nonzero_field) \
-({ \
- ssize_t __off = offsetofend(typeof(*(opts)), last_nonzero_field); \
- !(opts) || libbpf_is_mem_zeroed((const void *)opts + __off, \
- (opts)->sz - __off); \
-})
-
enum kern_feature_id {
/* v4.14: kernel support for program & map names. */
FEAT_PROG_NAME,
diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
index 0d4be829551b..e6fb12ba396c 100644
--- a/tools/lib/bpf/linker.c
+++ b/tools/lib/bpf/linker.c
@@ -16,6 +16,7 @@
#include <elf.h>
#include <libelf.h>
#include <fcntl.h>
+#include <tools/opts.h>
#include "libbpf.h"
#include "btf.h"
#include "libbpf_internal.h"
diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index 68a2def17175..786a4f6dc3ab 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -11,6 +11,7 @@
#include <linux/rtnetlink.h>
#include <linux/netdev.h>
#include <sys/socket.h>
+#include <tools/opts.h>
#include <errno.h>
#include <time.h>
diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c
index bfd8dac4c0cc..547781cde26d 100644
--- a/tools/lib/bpf/ringbuf.c
+++ b/tools/lib/bpf/ringbuf.c
@@ -16,6 +16,7 @@
#include <asm/barrier.h>
#include <sys/mman.h>
#include <sys/epoll.h>
+#include <tools/opts.h>
#include <time.h>
#include "libbpf.h"
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 3/8] libperf: Introduce perf_{evsel, evlist}__open_opt with extensible struct opts
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 1/8] libperf: Move 'open_flags' from tools/perf to evsel::open_flags Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 2/8] libbpf: Move opts code into dedicated header Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 4/8] libperf: Add support for overflow handling of sampling events Charlie Jenkins
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
From: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Introduce perf_{evsel, evlist}__open_opt with extensible structure opts.
The mechanism of the extensible structure opts imitates
tools/lib/bpf/libbpf.h. Currently, only open_flags is supported for the
opts structure.
Signed-off-by: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/lib/perf/Documentation/libperf.txt | 10 ++++++++++
tools/lib/perf/evlist.c | 20 ++++++++++++++++++++
tools/lib/perf/evsel.c | 26 +++++++++++++++++++++++++-
tools/lib/perf/include/perf/evlist.h | 3 +++
tools/lib/perf/include/perf/evsel.h | 23 +++++++++++++++++++++++
tools/lib/perf/libperf.map | 2 ++
6 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt
index fcfb9499ef9c..83827b94617a 100644
--- a/tools/lib/perf/Documentation/libperf.txt
+++ b/tools/lib/perf/Documentation/libperf.txt
@@ -132,6 +132,16 @@ SYNOPSIS
};
};
+ struct perf_evsel_open_opts {
+ /* size of this struct, for forward/backward compatibility */
+ size_t sz;
+
+ unsigned long open_flags; /* perf_event_open flags */
+ };
+ #define perf_evsel_open_opts__last_field open_flags
+
+ #define LIBPERF_OPTS(TYPE, NAME, ...)
+
struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr);
void perf_evsel__delete(struct perf_evsel *evsel);
int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c
index c6d67fc9e57e..7aa62f90f13b 100644
--- a/tools/lib/perf/evlist.c
+++ b/tools/lib/perf/evlist.c
@@ -753,3 +753,23 @@ void perf_evlist__go_system_wide(struct perf_evlist *evlist, struct perf_evsel *
__perf_evlist__propagate_maps(evlist, evsel);
}
}
+
+int perf_evlist__open_opts(struct perf_evlist *evlist,
+ struct perf_evsel_open_opts *opts)
+{
+ struct perf_evsel *evsel;
+ int err;
+
+ perf_evlist__for_each_entry(evlist, evsel) {
+ err = perf_evsel__open_opts(evsel, evsel->cpus,
+ evsel->threads, opts);
+ if (err < 0)
+ goto out_err;
+ }
+
+ return 0;
+
+out_err:
+ perf_evlist__close(evlist);
+ return err;
+}
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index c07160953224..96ecf3e5c8b4 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -16,8 +16,13 @@
#include <internal/lib.h>
#include <linux/string.h>
#include <sys/ioctl.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/types.h>
#include <sys/mman.h>
#include <asm/bug.h>
+#include <tools/opts.h>
+#include "internal.h"
void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr,
int idx)
@@ -26,6 +31,7 @@ void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr,
evsel->attr = *attr;
evsel->idx = idx;
evsel->leader = evsel;
+ evsel->open_flags = 0;
}
struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr)
@@ -160,7 +166,7 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
fd = sys_perf_event_open(&evsel->attr,
threads->map[thread].pid,
- cpu, group_fd, 0);
+ cpu, group_fd, evsel->open_flags);
if (fd < 0) {
err = -errno;
@@ -555,3 +561,21 @@ void perf_counts_values__scale(struct perf_counts_values *count,
if (pscaled)
*pscaled = scaled;
}
+
+int perf_evsel__open_opts(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
+ struct perf_thread_map *threads,
+ struct perf_evsel_open_opts *opts)
+{
+ int err = 0;
+
+ if (!OPTS_VALID(opts, perf_evsel_open_opts)) {
+ err = -EINVAL;
+ return err;
+ }
+
+ evsel->open_flags = OPTS_GET(opts, open_flags, 0);
+
+ err = perf_evsel__open(evsel, cpus, threads);
+
+ return err;
+}
diff --git a/tools/lib/perf/include/perf/evlist.h b/tools/lib/perf/include/perf/evlist.h
index e894b770779e..37ac44364d22 100644
--- a/tools/lib/perf/include/perf/evlist.h
+++ b/tools/lib/perf/include/perf/evlist.h
@@ -9,6 +9,7 @@ struct perf_evlist;
struct perf_evsel;
struct perf_cpu_map;
struct perf_thread_map;
+struct perf_evsel_open_opts;
LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist,
struct perf_evsel *evsel);
@@ -48,4 +49,6 @@ LIBPERF_API struct perf_mmap *perf_evlist__next_mmap(struct perf_evlist *evlist,
LIBPERF_API void perf_evlist__set_leader(struct perf_evlist *evlist);
LIBPERF_API int perf_evlist__nr_groups(struct perf_evlist *evlist);
+LIBPERF_API int perf_evlist__open_opts(struct perf_evlist *evlist,
+ struct perf_evsel_open_opts *opts);
#endif /* __LIBPERF_EVLIST_H */
diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h
index 6f92204075c2..8eb3927f3cd0 100644
--- a/tools/lib/perf/include/perf/evsel.h
+++ b/tools/lib/perf/include/perf/evsel.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <perf/core.h>
#include <stdbool.h>
+#include <signal.h>
#include <linux/types.h>
struct perf_evsel;
@@ -25,6 +26,24 @@ struct perf_counts_values {
};
};
+struct perf_evsel_open_opts {
+ /* size of this struct, for forward/backward compatibility */
+ size_t sz;
+
+ unsigned long open_flags; /* perf_event_open flags */
+};
+
+#define perf_evsel_open_opts__last_field open_flags
+
+#define LIBPERF_OPTS(TYPE, NAME, ...) \
+ struct TYPE NAME = ({ \
+ memset(&NAME, 0, sizeof(struct TYPE)); \
+ (struct TYPE) { \
+ .sz = sizeof(struct TYPE), \
+ __VA_ARGS__ \
+ }; \
+ })
+
LIBPERF_API struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr);
LIBPERF_API void perf_evsel__delete(struct perf_evsel *evsel);
LIBPERF_API int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
@@ -46,5 +65,9 @@ LIBPERF_API struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel
LIBPERF_API struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
LIBPERF_API void perf_counts_values__scale(struct perf_counts_values *count,
bool scale, __s8 *pscaled);
+LIBPERF_API int perf_evsel__open_opts(struct perf_evsel *evsel,
+ struct perf_cpu_map *cpus,
+ struct perf_thread_map *threads,
+ struct perf_evsel_open_opts *opts);
#endif /* __LIBPERF_EVSEL_H */
diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map
index 2aa79b696032..84fed76621cb 100644
--- a/tools/lib/perf/libperf.map
+++ b/tools/lib/perf/libperf.map
@@ -29,6 +29,7 @@ LIBPERF_0.0.1 {
perf_evsel__enable;
perf_evsel__disable;
perf_evsel__open;
+ perf_evsel__open_opts;
perf_evsel__close;
perf_evsel__mmap;
perf_evsel__munmap;
@@ -40,6 +41,7 @@ LIBPERF_0.0.1 {
perf_evlist__new;
perf_evlist__delete;
perf_evlist__open;
+ perf_evlist__open_opts;
perf_evlist__close;
perf_evlist__enable;
perf_evlist__disable;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 4/8] libperf: Add support for overflow handling of sampling events
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
` (2 preceding siblings ...)
2024-07-27 5:29 ` [PATCH v2 3/8] libperf: Introduce perf_{evsel, evlist}__open_opt with extensible struct opts Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 5/8] libperf: Add perf_evsel__has_fd() functions Charlie Jenkins
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
From: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Extend the fields of the opts structure to set up overflow handling
for sampling events. Also, add processing to set signal handlers in
perf_evsel__open_opts.
Signed-off-by: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/lib/perf/Documentation/libperf.txt | 6 ++-
tools/lib/perf/Makefile | 1 +
tools/lib/perf/evsel.c | 79 ++++++++++++++++++++++++++++++++
tools/lib/perf/include/perf/evsel.h | 6 ++-
tools/lib/perf/tests/test-evlist.c | 1 -
5 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt
index 83827b94617a..bb99534d5855 100644
--- a/tools/lib/perf/Documentation/libperf.txt
+++ b/tools/lib/perf/Documentation/libperf.txt
@@ -137,8 +137,12 @@ SYNOPSIS
size_t sz;
unsigned long open_flags; /* perf_event_open flags */
+ int fcntl_flags;
+ unsigned int signal;
+ int owner_type; /* value for F_SETOWN_EX */
+ struct sigaction *sigact;
};
- #define perf_evsel_open_opts__last_field open_flags
+ #define perf_evsel_open_opts__last_field sigact
#define LIBPERF_OPTS(TYPE, NAME, ...)
diff --git a/tools/lib/perf/Makefile b/tools/lib/perf/Makefile
index 3a9b2140aa04..9dade2ad91bd 100644
--- a/tools/lib/perf/Makefile
+++ b/tools/lib/perf/Makefile
@@ -75,6 +75,7 @@ override CFLAGS += -Werror -Wall
override CFLAGS += -fPIC
override CFLAGS += $(INCLUDES)
override CFLAGS += -fvisibility=hidden
+override CFLAGS += -D_GNU_SOURCE
all:
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index 96ecf3e5c8b4..17d3d9a88c23 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -562,6 +562,79 @@ void perf_counts_values__scale(struct perf_counts_values *count,
*pscaled = scaled;
}
+static int perf_evsel__run_fcntl(struct perf_evsel *evsel,
+ unsigned int cmd, unsigned long arg,
+ int cpu_map_idx)
+{
+ int thread;
+
+ for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
+ int err;
+ int *fd = FD(evsel, cpu_map_idx, thread);
+
+ if (!fd || *fd < 0)
+ return -1;
+
+ err = fcntl(*fd, cmd, arg);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int perf_evsel__set_signal_handler(struct perf_evsel *evsel,
+ struct perf_evsel_open_opts *opts)
+{
+ unsigned int fcntl_flags;
+ unsigned int signal;
+ struct f_owner_ex owner;
+ struct sigaction *sigact;
+ int cpu_map_idx;
+ int err = 0;
+
+ fcntl_flags = OPTS_GET(opts, fcntl_flags, (O_RDWR | O_NONBLOCK | O_ASYNC));
+ signal = OPTS_GET(opts, signal, SIGIO);
+ owner.type = OPTS_GET(opts, owner_type, F_OWNER_PID);
+ sigact = OPTS_GET(opts, sigact, NULL);
+
+ if (fcntl_flags == 0 && signal == 0 && !owner.type == 0 && sigact == 0)
+ return err;
+
+ err = sigaction(signal, sigact, NULL);
+ if (err)
+ return err;
+
+ switch (owner.type) {
+ case F_OWNER_PID:
+ owner.pid = getpid();
+ break;
+ case F_OWNER_TID:
+ owner.pid = syscall(SYS_gettid);
+ break;
+ case F_OWNER_PGRP:
+ default:
+ return -1;
+ }
+
+ for (cpu_map_idx = 0; cpu_map_idx < xyarray__max_x(evsel->fd); cpu_map_idx++) {
+ err = perf_evsel__run_fcntl(evsel, F_SETFL, fcntl_flags, cpu_map_idx);
+ if (err)
+ return err;
+
+ err = perf_evsel__run_fcntl(evsel, F_SETSIG, signal, cpu_map_idx);
+ if (err)
+ return err;
+
+ err = perf_evsel__run_fcntl(evsel, F_SETOWN_EX,
+ (unsigned long)&owner, cpu_map_idx);
+ if (err)
+ return err;
+ }
+
+ return err;
+}
+
int perf_evsel__open_opts(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
struct perf_thread_map *threads,
struct perf_evsel_open_opts *opts)
@@ -576,6 +649,12 @@ int perf_evsel__open_opts(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
evsel->open_flags = OPTS_GET(opts, open_flags, 0);
err = perf_evsel__open(evsel, cpus, threads);
+ if (err)
+ return err;
+
+ err = perf_evsel__set_signal_handler(evsel, opts);
+ if (err)
+ return err;
return err;
}
diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h
index 8eb3927f3cd0..344808f23371 100644
--- a/tools/lib/perf/include/perf/evsel.h
+++ b/tools/lib/perf/include/perf/evsel.h
@@ -31,9 +31,13 @@ struct perf_evsel_open_opts {
size_t sz;
unsigned long open_flags; /* perf_event_open flags */
+ int fcntl_flags;
+ int signal;
+ int owner_type; /* value for F_SETOWN_EX */
+ struct sigaction *sigact;
};
-#define perf_evsel_open_opts__last_field open_flags
+#define perf_evsel_open_opts__last_field sigact
#define LIBPERF_OPTS(TYPE, NAME, ...) \
struct TYPE NAME = ({ \
diff --git a/tools/lib/perf/tests/test-evlist.c b/tools/lib/perf/tests/test-evlist.c
index 10f70cb41ff1..3a833f0349d3 100644
--- a/tools/lib/perf/tests/test-evlist.c
+++ b/tools/lib/perf/tests/test-evlist.c
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-#define _GNU_SOURCE // needed for sched.h to get sched_[gs]etaffinity and CPU_(ZERO,SET)
#include <inttypes.h>
#include <sched.h>
#include <stdio.h>
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 5/8] libperf: Add perf_evsel__has_fd() functions
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
` (3 preceding siblings ...)
2024-07-27 5:29 ` [PATCH v2 4/8] libperf: Add support for overflow handling of sampling events Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 6/8] libperf: Add perf_evsel__{refresh, period}() functions Charlie Jenkins
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
From: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Add the following functions:
perf_evsel__has_fd
to check for perf events with the file descriptor specified in the
argument.
This function can be used in signal handlers to check overflow.
Signed-off-by: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/lib/perf/Documentation/libperf.txt | 1 +
tools/lib/perf/evsel.c | 18 ++++++++++++++++++
tools/lib/perf/include/perf/evsel.h | 1 +
tools/lib/perf/libperf.map | 1 +
4 files changed, 21 insertions(+)
diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt
index bb99534d5855..f1bfe6b6e78a 100644
--- a/tools/lib/perf/Documentation/libperf.txt
+++ b/tools/lib/perf/Documentation/libperf.txt
@@ -161,6 +161,7 @@ SYNOPSIS
int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx);
int perf_evsel__disable(struct perf_evsel *evsel);
int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx);
+ bool perf_evsel__has_fd(struct perf_evsel *evsel, int fd);
struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel);
struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index 17d3d9a88c23..6b98cba6eb4f 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -658,3 +658,21 @@ int perf_evsel__open_opts(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
return err;
}
+
+bool perf_evsel__has_fd(struct perf_evsel *evsel, int fd)
+{
+ int cpu_map_idx;
+ int thread;
+ int *evsel_fd;
+
+ for (cpu_map_idx = 0; cpu_map_idx < xyarray__max_x(evsel->fd); ++cpu_map_idx) {
+ for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
+ evsel_fd = FD(evsel, cpu_map_idx, thread);
+
+ if (fd == *evsel_fd)
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h
index 344808f23371..77816a35c383 100644
--- a/tools/lib/perf/include/perf/evsel.h
+++ b/tools/lib/perf/include/perf/evsel.h
@@ -73,5 +73,6 @@ LIBPERF_API int perf_evsel__open_opts(struct perf_evsel *evsel,
struct perf_cpu_map *cpus,
struct perf_thread_map *threads,
struct perf_evsel_open_opts *opts);
+LIBPERF_API bool perf_evsel__has_fd(struct perf_evsel *evsel, int fd);
#endif /* __LIBPERF_EVSEL_H */
diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map
index 84fed76621cb..f68519e17885 100644
--- a/tools/lib/perf/libperf.map
+++ b/tools/lib/perf/libperf.map
@@ -38,6 +38,7 @@ LIBPERF_0.0.1 {
perf_evsel__cpus;
perf_evsel__threads;
perf_evsel__attr;
+ perf_evsel__has_fd;
perf_evlist__new;
perf_evlist__delete;
perf_evlist__open;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 6/8] libperf: Add perf_evsel__{refresh, period}() functions
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
` (4 preceding siblings ...)
2024-07-27 5:29 ` [PATCH v2 5/8] libperf: Add perf_evsel__has_fd() functions Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 7/8] libperf test: Add test_stat_overflow() Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 8/8] libperf test: Add test_stat_overflow_event() Charlie Jenkins
7 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
From: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Add the following functions:
perf_evsel__refresh()
perf_evsel__period()
to set the over flow limit and period.
Signed-off-by: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/lib/perf/Documentation/libperf.txt | 2 ++
tools/lib/perf/evsel.c | 46 ++++++++++++++++++++++++++------
tools/lib/perf/include/perf/evsel.h | 2 ++
tools/lib/perf/libperf.map | 2 ++
4 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt
index f1bfe6b6e78a..aac764e63db6 100644
--- a/tools/lib/perf/Documentation/libperf.txt
+++ b/tools/lib/perf/Documentation/libperf.txt
@@ -162,6 +162,8 @@ SYNOPSIS
int perf_evsel__disable(struct perf_evsel *evsel);
int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx);
bool perf_evsel__has_fd(struct perf_evsel *evsel, int fd);
+ int perf_evsel__refresh(struct perf_evsel *evsel, int refresh);
+ int perf_evsel__period(struct perf_evsel *evsel, int period);
struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel);
struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index 6b98cba6eb4f..063498fc52f2 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -418,7 +418,7 @@ 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,
+static int perf_evsel__ioctl(struct perf_evsel *evsel, int ioc, unsigned long arg,
int cpu_map_idx, int thread)
{
int *fd = FD(evsel, cpu_map_idx, thread);
@@ -430,7 +430,7 @@ static int perf_evsel__ioctl(struct perf_evsel *evsel, int ioc, void *arg,
}
static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
- int ioc, void *arg,
+ int ioc, unsigned long arg,
int cpu_map_idx)
{
int thread;
@@ -447,7 +447,7 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
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);
+ return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0, cpu_map_idx);
}
int perf_evsel__enable_thread(struct perf_evsel *evsel, int thread)
@@ -457,7 +457,7 @@ int perf_evsel__enable_thread(struct perf_evsel *evsel, int thread)
int err;
perf_cpu_map__for_each_cpu(cpu, idx, evsel->cpus) {
- err = perf_evsel__ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, idx, thread);
+ err = perf_evsel__ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0, idx, thread);
if (err)
return err;
}
@@ -471,13 +471,13 @@ int perf_evsel__enable(struct perf_evsel *evsel)
int err = 0;
for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++)
- err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, i);
+ err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0, i);
return err;
}
int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx)
{
- return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, cpu_map_idx);
+ return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0, cpu_map_idx);
}
int perf_evsel__disable(struct perf_evsel *evsel)
@@ -486,7 +486,37 @@ int perf_evsel__disable(struct perf_evsel *evsel)
int err = 0;
for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++)
- err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, i);
+ err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0, i);
+ return err;
+}
+
+int perf_evsel__refresh(struct perf_evsel *evsel, int refresh)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++)
+ err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_REFRESH, refresh, i);
+ return err;
+}
+
+int perf_evsel__period(struct perf_evsel *evsel, __u64 period)
+{
+ struct perf_event_attr *attr;
+ int i;
+ int err = 0;
+
+ attr = perf_evsel__attr(evsel);
+
+ for (i = 0; i < xyarray__max_x(evsel->fd); i++) {
+ err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_PERIOD,
+ (unsigned long)&period, i);
+ if (err)
+ return err;
+ }
+
+ attr->sample_period = period;
+
return err;
}
@@ -497,7 +527,7 @@ int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter)
for (i = 0; i < perf_cpu_map__nr(evsel->cpus) && !err; i++)
err = perf_evsel__run_ioctl(evsel,
PERF_EVENT_IOC_SET_FILTER,
- (void *)filter, i);
+ (unsigned long)filter, i);
return err;
}
diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h
index 77816a35c383..613a63790346 100644
--- a/tools/lib/perf/include/perf/evsel.h
+++ b/tools/lib/perf/include/perf/evsel.h
@@ -63,6 +63,8 @@ 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__refresh(struct perf_evsel *evsel, int refresh);
+LIBPERF_API int perf_evsel__period(struct perf_evsel *evsel, __u64 period);
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);
LIBPERF_API struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map
index f68519e17885..12bdf2f43993 100644
--- a/tools/lib/perf/libperf.map
+++ b/tools/lib/perf/libperf.map
@@ -35,6 +35,8 @@ LIBPERF_0.0.1 {
perf_evsel__munmap;
perf_evsel__mmap_base;
perf_evsel__read;
+ perf_evsel__refresh;
+ perf_evsel__period;
perf_evsel__cpus;
perf_evsel__threads;
perf_evsel__attr;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 7/8] libperf test: Add test_stat_overflow()
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
` (5 preceding siblings ...)
2024-07-27 5:29 ` [PATCH v2 6/8] libperf: Add perf_evsel__{refresh, period}() functions Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 8/8] libperf test: Add test_stat_overflow_event() Charlie Jenkins
7 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
From: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Added overflow test using refresh and period.
Confirmation
- That the overflow occurs the number of times specified by
perf_evse__refresh()
- That the period can be updated by perf_evsel__period()
Committer testing:
$ sudo make tests -C ./tools/lib/perf V=1
make: Entering directory '/home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/lib/perf'
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=. obj=libperf
make -C /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/lib/api/ O= libapi.a
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=./fd obj=libapi
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=./fs obj=libapi
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=. obj=tests
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=./tests obj=tests
running static:
- running tests/test-cpumap.c...OK
- running tests/test-threadmap.c...OK
- running tests/test-evlist.c...
<SNIP>
OK
- running tests/test-evsel.c...
<SNIP>
period = 1000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
period = 2000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
period = 1000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
period = 2000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
OK
running dynamic:
- running tests/test-cpumap.c...OK
- running tests/test-threadmap.c...OK
- running tests/test-evlist.c...
<SNIP>
OK
- running tests/test-evsel.c...
<SNIP>
period = 1000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
period = 2000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
period = 1000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
period = 2000000
overflow limit = 3, overflow count = 3, POLL_IN = 2, POLL_HUP = 1, other signal event = 0
OK
make: Leaving directory '/home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/lib/perf'
Signed-off-by: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/lib/perf/tests/test-evsel.c | 107 ++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/tools/lib/perf/tests/test-evsel.c b/tools/lib/perf/tests/test-evsel.c
index 545ec3150546..b27dd65f2ec9 100644
--- a/tools/lib/perf/tests/test-evsel.c
+++ b/tools/lib/perf/tests/test-evsel.c
@@ -1,7 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
+#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <linux/perf_event.h>
#include <linux/kernel.h>
#include <perf/cpumap.h>
@@ -11,6 +15,15 @@
#include <internal/tests.h>
#include "tests.h"
+#define WAIT_COUNT 10000000UL
+static struct signal_counts {
+ int in;
+ int hup;
+ int others;
+ int overflow;
+} sig_count;
+static struct perf_evsel *s_evsel;
+
static int libperf_print(enum libperf_print_level level,
const char *fmt, va_list ap)
{
@@ -349,6 +362,98 @@ static int test_stat_read_format(void)
return 0;
}
+static void sig_handler(int signo, siginfo_t *info, void *uc)
+{
+ switch (info->si_code) {
+ case POLL_IN:
+ sig_count.in++;
+ break;
+ case POLL_HUP:
+ sig_count.hup++;
+ break;
+ default:
+ sig_count.others++;
+ }
+
+ sig_count.overflow++;
+}
+
+static int test_stat_overflow(int owner)
+{
+ static struct sigaction sig;
+ u64 period = 1000000;
+ int overflow_limit = 3;
+
+ struct perf_thread_map *threads;
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_SOFTWARE,
+ .config = PERF_COUNT_SW_TASK_CLOCK,
+ .sample_type = PERF_SAMPLE_PERIOD,
+ .sample_period = period,
+ .disabled = 1,
+ };
+ struct perf_event_attr *tmp_attr;
+ int err = 0, i;
+
+ LIBPERF_OPTS(perf_evsel_open_opts, opts,
+ .open_flags = PERF_FLAG_FD_CLOEXEC,
+ .flags = (O_RDWR | O_NONBLOCK | O_ASYNC),
+ .signal = SIGRTMIN + 1,
+ .owner_type = owner,
+ .sig = &sig);
+
+ /* setup signal handler */
+ memset(&sig, 0, sizeof(struct sigaction));
+ sig.sa_sigaction = (void *)sig_handler;
+ sig.sa_flags = SA_SIGINFO;
+
+ threads = perf_thread_map__new_dummy();
+ __T("failed to create threads", threads);
+
+ perf_thread_map__set_pid(threads, 0, 0);
+
+ s_evsel = perf_evsel__new(&attr);
+ __T("failed to create evsel", s_evsel);
+
+ err = perf_evsel__open_opts(s_evsel, NULL, threads, &opts);
+ __T("failed to open evsel", err == 0);
+
+ for (i = 0; i < 2; i++) {
+ volatile unsigned int wait_count = WAIT_COUNT;
+
+ sig_count.in = 0;
+ sig_count.hup = 0;
+ sig_count.others = 0;
+ sig_count.overflow = 0;
+
+ period = period << i;
+ err = perf_evsel__period(s_evsel, period);
+ __T("failed to period evsel", err == 0);
+
+ tmp_attr = perf_evsel__attr(s_evsel);
+ __T_VERBOSE("\tperiod = %llu\n", tmp_attr->sample_period);
+
+ err = perf_evsel__refresh(s_evsel, overflow_limit);
+ __T("failed to refresh evsel", err == 0);
+
+ while (wait_count--)
+ ;
+
+ __T_VERBOSE("\toverflow limit = %d, overflow count = %d, ",
+ overflow_limit, sig_count.overflow);
+ __T_VERBOSE("POLL_IN = %d, POLL_HUP = %d, other signal event = %d\n",
+ sig_count.in, sig_count.hup, sig_count.others);
+
+ __T("failed to overflow count", overflow_limit == sig_count.overflow);
+ }
+
+ perf_evsel__close(s_evsel);
+ perf_evsel__delete(s_evsel);
+ perf_thread_map__put(threads);
+
+ return 0;
+}
+
int test_evsel(int argc, char **argv)
{
__T_START;
@@ -361,6 +466,8 @@ int test_evsel(int argc, char **argv)
test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
test_stat_read_format();
+ test_stat_overflow(F_OWNER_PID);
+ test_stat_overflow(F_OWNER_TID);
__T_END;
return tests_failed == 0 ? 0 : -1;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 8/8] libperf test: Add test_stat_overflow_event()
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
` (6 preceding siblings ...)
2024-07-27 5:29 ` [PATCH v2 7/8] libperf test: Add test_stat_overflow() Charlie Jenkins
@ 2024-07-27 5:29 ` Charlie Jenkins
7 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-27 5:29 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo
Cc: linux-perf-users, linux-kernel, bpf, Charlie Jenkins,
Shunsuke Nakamura
From: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Add a test to check overflowed events.
Committer testing:
$ sudo make tests -C ./tools/lib/perf V=1
make: Entering directory '/home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/lib/perf'
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=. obj=libperf
make -C /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/lib/api/ O= libapi.a
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=./fd obj=libapi
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=./fs obj=libapi
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=. obj=tests
make -f /home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/build/Makefile.build dir=./tests obj=tests
running static:
- running tests/test-cpumap.c...OK
- running tests/test-threadmap.c...OK
- running tests/test-evlist.c...
<SNIP>
Event 0 -- overflow flag = 0x1, POLL_HUP = 1, other signal event = 0
Event 1 -- overflow flag = 0x2, POLL_HUP = 1, other signal event = 0
Event 2 -- overflow flag = 0x4, POLL_HUP = 1, other signal event = 0
Event 3 -- overflow flag = 0x8, POLL_HUP = 1, other signal event = 0
OK
- running tests/test-evsel.c...
<SNIP>
OK
running dynamic:
- running tests/test-cpumap.c...OK
- running tests/test-threadmap.c...OK
- running tests/test-evlist.c...
<SNIP>
Event 0 -- overflow flag = 0x1, POLL_HUP = 1, other signal event = 0
Event 1 -- overflow flag = 0x2, POLL_HUP = 1, other signal event = 0
Event 2 -- overflow flag = 0x4, POLL_HUP = 1, other signal event = 0
Event 3 -- overflow flag = 0x8, POLL_HUP = 1, other signal event = 0
OK
- running tests/test-evsel.c...
<SNIP>
OK
make: Leaving directory '/home/nakamura/build_work/build_kernel/linux-kernel/linux/tools/lib/perf'
Signed-off-by: Shunsuke Nakamura <nakamura.shun@fujitsu.com>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
tools/lib/perf/tests/test-evlist.c | 111 +++++++++++++++++++++++++++++++++++++
tools/lib/perf/tests/test-evsel.c | 20 +++----
2 files changed, 121 insertions(+), 10 deletions(-)
diff --git a/tools/lib/perf/tests/test-evlist.c b/tools/lib/perf/tests/test-evlist.c
index 3a833f0349d3..7bfceb8e0c66 100644
--- a/tools/lib/perf/tests/test-evlist.c
+++ b/tools/lib/perf/tests/test-evlist.c
@@ -5,6 +5,8 @@
#include <stdarg.h>
#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
#include <linux/perf_event.h>
#include <linux/limits.h>
#include <sys/types.h>
@@ -24,6 +26,13 @@
#define EVENT_NUM 15
#define WAIT_COUNT 100000000UL
+static unsigned int overflow_flag;
+static struct signal_counts {
+ int hup;
+ int others;
+} sig_count;
+static struct perf_evlist *s_evlist;
+
static int libperf_print(enum libperf_print_level level,
const char *fmt, va_list ap)
{
@@ -570,6 +579,107 @@ static int test_stat_multiplexing(void)
return 0;
}
+static void sig_handler(int signo, siginfo_t *info, void *uc)
+{
+ struct perf_evsel *evsel;
+ int i = 0;
+
+ perf_evlist__for_each_evsel(s_evlist, evsel) {
+ if (perf_evsel__has_fd(evsel, info->si_fd)) {
+ if (info->si_code == POLL_HUP)
+ sig_count.hup++;
+ else
+ sig_count.others++;
+
+ overflow_flag = (1U << i);
+ return;
+ }
+ i++;
+ }
+
+ __T_VERBOSE("Failed to get fd of overflowed event");
+}
+
+static int test_stat_overflow_event(void)
+{
+ static struct sigaction sigact;
+
+ struct perf_thread_map *threads;
+ struct perf_evsel *evsel;
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_SOFTWARE,
+ .config = PERF_COUNT_SW_CPU_CLOCK,
+ .sample_type = PERF_SAMPLE_PERIOD,
+ .sample_period = 100000,
+ .disabled = 1,
+ };
+ int err, i, event_num = 4;
+
+ LIBPERF_OPTS(perf_evsel_open_opts, opts,
+ .open_flags = PERF_FLAG_FD_CLOEXEC,
+ .fcntl_flags = (O_RDWR | O_NONBLOCK | O_ASYNC),
+ .signal = SIGRTMIN + 1,
+ .owner_type = F_OWNER_PID,
+ .sigact = &sigact);
+
+ /* setup signal handler */
+ memset(&sigact, 0, sizeof(struct sigaction));
+ sigact.sa_sigaction = (void *)sig_handler;
+ sigact.sa_flags = SA_SIGINFO;
+
+ threads = perf_thread_map__new_dummy();
+ __T("failed to create threads", threads);
+
+ perf_thread_map__set_pid(threads, 0, 0);
+
+ s_evlist = perf_evlist__new();
+ __T("failed to create evlist", s_evlist);
+
+ for (i = 0; i < event_num; i++) {
+ evsel = perf_evsel__new(&attr);
+ __T("failed to create evsel", evsel);
+
+ perf_evlist__add(s_evlist, evsel);
+ }
+
+ perf_evlist__set_maps(s_evlist, NULL, threads);
+
+ err = perf_evlist__open_opts(s_evlist, &opts);
+ __T("failed to open evlist", err == 0);
+
+ i = 0;
+ perf_evlist__for_each_evsel(s_evlist, evsel) {
+ volatile unsigned int wait_count = WAIT_COUNT;
+
+ overflow_flag = 0;
+ sig_count.hup = 0;
+ sig_count.others = 0;
+
+ err = perf_evsel__refresh(evsel, 1);
+ __T("failed to refresh evsel", err == 0);
+
+ while (wait_count--)
+ ;
+
+ __T_VERBOSE("Event %2d -- overflow flag = %#x, ",
+ i, overflow_flag);
+ __T_VERBOSE("POLL_HUP = %d, other signal event = %d\n",
+ sig_count.hup, sig_count.others);
+
+ __T("unexpected event overflow detected", overflow_flag && (1U << i));
+ __T("unexpected signal event detected",
+ sig_count.hup == 1 && sig_count.others == 0);
+
+ i++;
+ }
+
+ perf_evlist__close(s_evlist);
+ perf_evlist__delete(s_evlist);
+ perf_thread_map__put(threads);
+
+ return 0;
+}
+
int test_evlist(int argc, char **argv)
{
__T_START;
@@ -582,6 +692,7 @@ int test_evlist(int argc, char **argv)
test_mmap_thread();
test_mmap_cpus();
test_stat_multiplexing();
+ test_stat_overflow_event();
__T_END;
return tests_failed == 0 ? 0 : -1;
diff --git a/tools/lib/perf/tests/test-evsel.c b/tools/lib/perf/tests/test-evsel.c
index b27dd65f2ec9..56f4ae20e922 100644
--- a/tools/lib/perf/tests/test-evsel.c
+++ b/tools/lib/perf/tests/test-evsel.c
@@ -15,7 +15,7 @@
#include <internal/tests.h>
#include "tests.h"
-#define WAIT_COUNT 10000000UL
+#define WAIT_COUNT 100000000UL
static struct signal_counts {
int in;
int hup;
@@ -380,7 +380,7 @@ static void sig_handler(int signo, siginfo_t *info, void *uc)
static int test_stat_overflow(int owner)
{
- static struct sigaction sig;
+ static struct sigaction sigact;
u64 period = 1000000;
int overflow_limit = 3;
@@ -396,16 +396,16 @@ static int test_stat_overflow(int owner)
int err = 0, i;
LIBPERF_OPTS(perf_evsel_open_opts, opts,
- .open_flags = PERF_FLAG_FD_CLOEXEC,
- .flags = (O_RDWR | O_NONBLOCK | O_ASYNC),
- .signal = SIGRTMIN + 1,
- .owner_type = owner,
- .sig = &sig);
+ .open_flags = PERF_FLAG_FD_CLOEXEC,
+ .fcntl_flags = (O_RDWR | O_NONBLOCK | O_ASYNC),
+ .signal = SIGRTMIN + 1,
+ .owner_type = owner,
+ .sigact = &sigact);
/* setup signal handler */
- memset(&sig, 0, sizeof(struct sigaction));
- sig.sa_sigaction = (void *)sig_handler;
- sig.sa_flags = SA_SIGINFO;
+ memset(&sigact, 0, sizeof(struct sigaction));
+ sigact.sa_sigaction = (void *)sig_handler;
+ sigact.sa_flags = SA_SIGINFO;
threads = perf_thread_map__new_dummy();
__T("failed to create threads", threads);
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/8] libbpf: Move opts code into dedicated header
2024-07-27 5:29 ` [PATCH v2 2/8] libbpf: Move opts code into dedicated header Charlie Jenkins
@ 2024-07-29 17:01 ` Andrii Nakryiko
2024-07-29 17:55 ` Charlie Jenkins
0 siblings, 1 reply; 13+ messages in thread
From: Andrii Nakryiko @ 2024-07-29 17:01 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, linux-perf-users, linux-kernel, bpf
On Mon, Jul 29, 2024 at 9:46 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
>
> Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
> ---
> tools/include/tools/opts.h | 68 +++++++++++++++++++++++++++++++++++++++++
> tools/lib/bpf/bpf.c | 1 +
> tools/lib/bpf/btf.c | 1 +
> tools/lib/bpf/btf_dump.c | 1 +
> tools/lib/bpf/libbpf.c | 3 +-
> tools/lib/bpf/libbpf_internal.h | 48 -----------------------------
> tools/lib/bpf/linker.c | 1 +
> tools/lib/bpf/netlink.c | 1 +
> tools/lib/bpf/ringbuf.c | 1 +
> 9 files changed, 76 insertions(+), 49 deletions(-)
>
Nope, sorry, I don't think I want to do this for libbpf. This will
just make Github synchronization trickier, and I don't really see a
point.
I'm totally fine with libperf making a copy of these helpers, though
(this is not complicated or tricky code). I also don't think it will
change much, so there is little risk of any sort of divergence.
[...]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/8] libbpf: Move opts code into dedicated header
2024-07-29 17:01 ` Andrii Nakryiko
@ 2024-07-29 17:55 ` Charlie Jenkins
2024-07-29 18:59 ` Andrii Nakryiko
0 siblings, 1 reply; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-29 17:55 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, linux-perf-users, linux-kernel, bpf
On Mon, Jul 29, 2024 at 10:01:05AM -0700, Andrii Nakryiko wrote:
> On Mon, Jul 29, 2024 at 9:46 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> >
> > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
> > ---
> > tools/include/tools/opts.h | 68 +++++++++++++++++++++++++++++++++++++++++
> > tools/lib/bpf/bpf.c | 1 +
> > tools/lib/bpf/btf.c | 1 +
> > tools/lib/bpf/btf_dump.c | 1 +
> > tools/lib/bpf/libbpf.c | 3 +-
> > tools/lib/bpf/libbpf_internal.h | 48 -----------------------------
> > tools/lib/bpf/linker.c | 1 +
> > tools/lib/bpf/netlink.c | 1 +
> > tools/lib/bpf/ringbuf.c | 1 +
> > 9 files changed, 76 insertions(+), 49 deletions(-)
> >
>
> Nope, sorry, I don't think I want to do this for libbpf. This will
> just make Github synchronization trickier, and I don't really see a
> point.
>
> I'm totally fine with libperf making a copy of these helpers, though
> (this is not complicated or tricky code). I also don't think it will
> change much, so there is little risk of any sort of divergence.
I did this because there were two comments on the previous version of
this patch that asked to change the functions that were copied over. I
had a couple of choices, have the implementations diverge, not change
the implementation in perf to keep it the same as bpf, update both perf
and bpf, or share the implementations. I figured the last option was the
best to avoid immediate divergence. However, both of the comments can be
safely ignored, and also perhaps divergence doesn't matter.
- Charlie
>
> [...]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/8] libbpf: Move opts code into dedicated header
2024-07-29 17:55 ` Charlie Jenkins
@ 2024-07-29 18:59 ` Andrii Nakryiko
2024-07-29 19:46 ` Charlie Jenkins
0 siblings, 1 reply; 13+ messages in thread
From: Andrii Nakryiko @ 2024-07-29 18:59 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, linux-perf-users, linux-kernel, bpf
On Mon, Jul 29, 2024 at 10:55 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
>
> On Mon, Jul 29, 2024 at 10:01:05AM -0700, Andrii Nakryiko wrote:
> > On Mon, Jul 29, 2024 at 9:46 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > >
> > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
> > > ---
> > > tools/include/tools/opts.h | 68 +++++++++++++++++++++++++++++++++++++++++
> > > tools/lib/bpf/bpf.c | 1 +
> > > tools/lib/bpf/btf.c | 1 +
> > > tools/lib/bpf/btf_dump.c | 1 +
> > > tools/lib/bpf/libbpf.c | 3 +-
> > > tools/lib/bpf/libbpf_internal.h | 48 -----------------------------
> > > tools/lib/bpf/linker.c | 1 +
> > > tools/lib/bpf/netlink.c | 1 +
> > > tools/lib/bpf/ringbuf.c | 1 +
> > > 9 files changed, 76 insertions(+), 49 deletions(-)
> > >
> >
> > Nope, sorry, I don't think I want to do this for libbpf. This will
> > just make Github synchronization trickier, and I don't really see a
> > point.
> >
> > I'm totally fine with libperf making a copy of these helpers, though
> > (this is not complicated or tricky code). I also don't think it will
> > change much, so there is little risk of any sort of divergence.
>
> I did this because there were two comments on the previous version of
> this patch that asked to change the functions that were copied over. I
> had a couple of choices, have the implementations diverge, not change
> the implementation in perf to keep it the same as bpf, update both perf
> and bpf, or share the implementations. I figured the last option was the
> best to avoid immediate divergence. However, both of the comments can be
> safely ignored, and also perhaps divergence doesn't matter.
>
I mean, feel free to diverge. First and foremost the code has to make
sense to specific library and specific use case. If libperf has some
extra things that it needs to enforce or check, by all means. I just
want to avoid unnecessary code sharing, given the code isn't tricky or
complicated, but will complicate libbpf's sync story to Github (libbpf
kind of lives in two places, kernel repo and Github repo).
> - Charlie
>
> >
> > [...]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/8] libbpf: Move opts code into dedicated header
2024-07-29 18:59 ` Andrii Nakryiko
@ 2024-07-29 19:46 ` Charlie Jenkins
0 siblings, 0 replies; 13+ messages in thread
From: Charlie Jenkins @ 2024-07-29 19:46 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, linux-perf-users, linux-kernel, bpf
On Mon, Jul 29, 2024 at 11:59:47AM -0700, Andrii Nakryiko wrote:
> On Mon, Jul 29, 2024 at 10:55 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> >
> > On Mon, Jul 29, 2024 at 10:01:05AM -0700, Andrii Nakryiko wrote:
> > > On Mon, Jul 29, 2024 at 9:46 AM Charlie Jenkins <charlie@rivosinc.com> wrote:
> > > >
> > > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
> > > > ---
> > > > tools/include/tools/opts.h | 68 +++++++++++++++++++++++++++++++++++++++++
> > > > tools/lib/bpf/bpf.c | 1 +
> > > > tools/lib/bpf/btf.c | 1 +
> > > > tools/lib/bpf/btf_dump.c | 1 +
> > > > tools/lib/bpf/libbpf.c | 3 +-
> > > > tools/lib/bpf/libbpf_internal.h | 48 -----------------------------
> > > > tools/lib/bpf/linker.c | 1 +
> > > > tools/lib/bpf/netlink.c | 1 +
> > > > tools/lib/bpf/ringbuf.c | 1 +
> > > > 9 files changed, 76 insertions(+), 49 deletions(-)
> > > >
> > >
> > > Nope, sorry, I don't think I want to do this for libbpf. This will
> > > just make Github synchronization trickier, and I don't really see a
> > > point.
> > >
> > > I'm totally fine with libperf making a copy of these helpers, though
> > > (this is not complicated or tricky code). I also don't think it will
> > > change much, so there is little risk of any sort of divergence.
> >
> > I did this because there were two comments on the previous version of
> > this patch that asked to change the functions that were copied over. I
> > had a couple of choices, have the implementations diverge, not change
> > the implementation in perf to keep it the same as bpf, update both perf
> > and bpf, or share the implementations. I figured the last option was the
> > best to avoid immediate divergence. However, both of the comments can be
> > safely ignored, and also perhaps divergence doesn't matter.
> >
>
> I mean, feel free to diverge. First and foremost the code has to make
> sense to specific library and specific use case. If libperf has some
> extra things that it needs to enforce or check, by all means. I just
> want to avoid unnecessary code sharing, given the code isn't tricky or
> complicated, but will complicate libbpf's sync story to Github (libbpf
> kind of lives in two places, kernel repo and Github repo).
Alright, I like to avoid copy-pasting code but if that's what is
required I will do that.
>
> > - Charlie
> >
> > >
> > > [...]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-07-29 19:46 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-27 5:29 [PATCH v2 0/8] libperf: Add interface for overflow check of sampling events Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 1/8] libperf: Move 'open_flags' from tools/perf to evsel::open_flags Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 2/8] libbpf: Move opts code into dedicated header Charlie Jenkins
2024-07-29 17:01 ` Andrii Nakryiko
2024-07-29 17:55 ` Charlie Jenkins
2024-07-29 18:59 ` Andrii Nakryiko
2024-07-29 19:46 ` Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 3/8] libperf: Introduce perf_{evsel, evlist}__open_opt with extensible struct opts Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 4/8] libperf: Add support for overflow handling of sampling events Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 5/8] libperf: Add perf_evsel__has_fd() functions Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 6/8] libperf: Add perf_evsel__{refresh, period}() functions Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 7/8] libperf test: Add test_stat_overflow() Charlie Jenkins
2024-07-27 5:29 ` [PATCH v2 8/8] libperf test: Add test_stat_overflow_event() Charlie Jenkins
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).