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@xxxxxxxxxx> > --- > 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 -- - Arnaldo