Message ID | 20220624231313.367909-3-namhyung@kernel.org (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | BPF |
Headers | show |
Series | perf tools: A couple of fixes for perf record --off-cpu (v1) | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
Em Fri, Jun 24, 2022 at 04:13:09PM -0700, Namhyung Kim escreveu: > As offcpu-time event is synthesized at the end, it could not get the > all the sample info. Define OFFCPU_SAMPLE_TYPES for allowed ones and > mask out others in evsel__config() to prevent parse errors. > > Because perf sample parsing assumes a specific ordering with the > sample types, setting unsupported one would make it fail to read > data like perf record -d/--data. > Fixes: edc41a1099c2 ("perf record: Enable off-cpu analysis with BPF") Thanks, applied. - Arnaldo > Signed-off-by: Namhyung Kim <namhyung@kernel.org> > --- > tools/perf/util/bpf_off_cpu.c | 7 ++++++- > tools/perf/util/evsel.c | 9 +++++++++ > tools/perf/util/off_cpu.h | 9 +++++++++ > 3 files changed, 24 insertions(+), 1 deletion(-) > > diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c > index b73e84a02264..f289b7713598 100644 > --- a/tools/perf/util/bpf_off_cpu.c > +++ b/tools/perf/util/bpf_off_cpu.c > @@ -265,6 +265,12 @@ int off_cpu_write(struct perf_session *session) > > sample_type = evsel->core.attr.sample_type; > > + if (sample_type & ~OFFCPU_SAMPLE_TYPES) { > + pr_err("not supported sample type: %llx\n", > + (unsigned long long)sample_type); > + return -1; > + } > + > if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) { > if (evsel->core.id) > sid = evsel->core.id[0]; > @@ -319,7 +325,6 @@ int off_cpu_write(struct perf_session *session) > } > if (sample_type & PERF_SAMPLE_CGROUP) > data.array[n++] = key.cgroup_id; > - /* TODO: handle more sample types */ > > size = n * sizeof(u64); > data.hdr.size = size; > diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c > index ce499c5da8d7..094b0a9c0bc0 100644 > --- a/tools/perf/util/evsel.c > +++ b/tools/perf/util/evsel.c > @@ -48,6 +48,7 @@ > #include "util.h" > #include "hashmap.h" > #include "pmu-hybrid.h" > +#include "off_cpu.h" > #include "../perf-sys.h" > #include "util/parse-branch-options.h" > #include <internal/xyarray.h> > @@ -1102,6 +1103,11 @@ static void evsel__set_default_freq_period(struct record_opts *opts, > } > } > > +static bool evsel__is_offcpu_event(struct evsel *evsel) > +{ > + return evsel__is_bpf_output(evsel) && !strcmp(evsel->name, OFFCPU_EVENT); > +} > + > /* > * The enable_on_exec/disabled value strategy: > * > @@ -1366,6 +1372,9 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts, > */ > if (evsel__is_dummy_event(evsel)) > evsel__reset_sample_bit(evsel, BRANCH_STACK); > + > + if (evsel__is_offcpu_event(evsel)) > + evsel->core.attr.sample_type &= OFFCPU_SAMPLE_TYPES; > } > > int evsel__set_filter(struct evsel *evsel, const char *filter) > diff --git a/tools/perf/util/off_cpu.h b/tools/perf/util/off_cpu.h > index 548008f74d42..2dd67c60f211 100644 > --- a/tools/perf/util/off_cpu.h > +++ b/tools/perf/util/off_cpu.h > @@ -1,6 +1,8 @@ > #ifndef PERF_UTIL_OFF_CPU_H > #define PERF_UTIL_OFF_CPU_H > > +#include <linux/perf_event.h> > + > struct evlist; > struct target; > struct perf_session; > @@ -8,6 +10,13 @@ struct record_opts; > > #define OFFCPU_EVENT "offcpu-time" > > +#define OFFCPU_SAMPLE_TYPES (PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP | \ > + PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \ > + PERF_SAMPLE_ID | PERF_SAMPLE_CPU | \ > + PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN | \ > + PERF_SAMPLE_CGROUP) > + > + > #ifdef HAVE_BPF_SKEL > int off_cpu_prepare(struct evlist *evlist, struct target *target, > struct record_opts *opts); > -- > 2.37.0.rc0.161.g10f37bed90-goog
diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c index b73e84a02264..f289b7713598 100644 --- a/tools/perf/util/bpf_off_cpu.c +++ b/tools/perf/util/bpf_off_cpu.c @@ -265,6 +265,12 @@ int off_cpu_write(struct perf_session *session) sample_type = evsel->core.attr.sample_type; + if (sample_type & ~OFFCPU_SAMPLE_TYPES) { + pr_err("not supported sample type: %llx\n", + (unsigned long long)sample_type); + return -1; + } + if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) { if (evsel->core.id) sid = evsel->core.id[0]; @@ -319,7 +325,6 @@ int off_cpu_write(struct perf_session *session) } if (sample_type & PERF_SAMPLE_CGROUP) data.array[n++] = key.cgroup_id; - /* TODO: handle more sample types */ size = n * sizeof(u64); data.hdr.size = size; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ce499c5da8d7..094b0a9c0bc0 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -48,6 +48,7 @@ #include "util.h" #include "hashmap.h" #include "pmu-hybrid.h" +#include "off_cpu.h" #include "../perf-sys.h" #include "util/parse-branch-options.h" #include <internal/xyarray.h> @@ -1102,6 +1103,11 @@ static void evsel__set_default_freq_period(struct record_opts *opts, } } +static bool evsel__is_offcpu_event(struct evsel *evsel) +{ + return evsel__is_bpf_output(evsel) && !strcmp(evsel->name, OFFCPU_EVENT); +} + /* * The enable_on_exec/disabled value strategy: * @@ -1366,6 +1372,9 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts, */ if (evsel__is_dummy_event(evsel)) evsel__reset_sample_bit(evsel, BRANCH_STACK); + + if (evsel__is_offcpu_event(evsel)) + evsel->core.attr.sample_type &= OFFCPU_SAMPLE_TYPES; } int evsel__set_filter(struct evsel *evsel, const char *filter) diff --git a/tools/perf/util/off_cpu.h b/tools/perf/util/off_cpu.h index 548008f74d42..2dd67c60f211 100644 --- a/tools/perf/util/off_cpu.h +++ b/tools/perf/util/off_cpu.h @@ -1,6 +1,8 @@ #ifndef PERF_UTIL_OFF_CPU_H #define PERF_UTIL_OFF_CPU_H +#include <linux/perf_event.h> + struct evlist; struct target; struct perf_session; @@ -8,6 +10,13 @@ struct record_opts; #define OFFCPU_EVENT "offcpu-time" +#define OFFCPU_SAMPLE_TYPES (PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP | \ + PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_ID | PERF_SAMPLE_CPU | \ + PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN | \ + PERF_SAMPLE_CGROUP) + + #ifdef HAVE_BPF_SKEL int off_cpu_prepare(struct evlist *evlist, struct target *target, struct record_opts *opts);
As offcpu-time event is synthesized at the end, it could not get the all the sample info. Define OFFCPU_SAMPLE_TYPES for allowed ones and mask out others in evsel__config() to prevent parse errors. Because perf sample parsing assumes a specific ordering with the sample types, setting unsupported one would make it fail to read data like perf record -d/--data. Fixes: edc41a1099c2 ("perf record: Enable off-cpu analysis with BPF") Signed-off-by: Namhyung Kim <namhyung@kernel.org> --- tools/perf/util/bpf_off_cpu.c | 7 ++++++- tools/perf/util/evsel.c | 9 +++++++++ tools/perf/util/off_cpu.h | 9 +++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)