]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
perf evsel: Add/use accessor for tp_format
authorIan Rogers <irogers@google.com>
Mon, 18 Nov 2024 22:53:43 +0000 (14:53 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 9 Dec 2024 20:52:42 +0000 (17:52 -0300)
Add an accessor function for tp_format. Rather than search+replace
uses try to use a variable and reuse it. Add additional NULL checks
when accessing/using the value. Make sure the PTR_ERR is nulled out on
error path in evsel__newtp_idx.

Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ben Gainey <ben.gainey@arm.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Dominique Martinet <asmadeus@codewreck.org>
Cc: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: Paran Lee <p4ranlee@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steinar H. Gunderson <sesse@google.com>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Yang Jihong <yangjihong@bytedance.com>
Cc: Yang Li <yang.lee@linux.alibaba.com>
Cc: Ze Gao <zegao2021@gmail.com>
Cc: Zixian Cai <fzczx123@gmail.com>
Cc: zhaimingbing <zhaimingbing@cmss.chinamobile.com>
Link: https://lore.kernel.org/r/20241118225345.889810-6-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
13 files changed:
tools/perf/builtin-kmem.c
tools/perf/builtin-kwork.c
tools/perf/builtin-script.c
tools/perf/builtin-trace.c
tools/perf/util/data-convert-bt.c
tools/perf/util/data-convert-json.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/evsel_fprintf.c
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/sort.c
tools/perf/util/trace-event-scripting.c

index 4d8d94146f8dd7deca9afde9ae84b583463918c7..67fb1946ef1376a59494ac27298d4161cd91a473 100644 (file)
@@ -761,6 +761,7 @@ static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample,
        };
        struct trace_seq seq;
        char *str, *pos = NULL;
+       const struct tep_event *tp_format;
 
        if (nr_gfps) {
                struct gfp_flag key = {
@@ -772,8 +773,9 @@ static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample,
        }
 
        trace_seq_init(&seq);
-       tep_print_event(evsel->tp_format->tep,
-                       &seq, &record, "%s", TEP_PRINT_INFO);
+       tp_format = evsel__tp_format(evsel);
+       if (tp_format)
+               tep_print_event(tp_format->tep, &seq, &record, "%s", TEP_PRINT_INFO);
 
        str = strtok_r(seq.buffer, " ", &pos);
        while (str) {
@@ -2012,13 +2014,13 @@ int cmd_kmem(int argc, const char **argv)
 
        if (kmem_page) {
                struct evsel *evsel = evlist__find_tracepoint_by_name(session->evlist, "kmem:mm_page_alloc");
+               const struct tep_event *tp_format = evsel ? evsel__tp_format(evsel) : NULL;
 
-               if (evsel == NULL) {
+               if (tp_format == NULL) {
                        pr_err(errmsg, "page", "page");
                        goto out_delete;
                }
-
-               kmem_page_size = tep_get_page_size(evsel->tp_format->tep);
+               kmem_page_size = tep_get_page_size(tp_format->tep);
                symbol_conf.use_callchain = true;
        }
 
index 233ca3c3895c8b7d2858e31c4288dddfbd0296d8..878c93c026b1d79eba9963b4993296dfbff6fd30 100644 (file)
@@ -1104,7 +1104,8 @@ static char *evsel__softirq_name(struct evsel *evsel, u64 num)
        char *name = NULL;
        bool found = false;
        struct tep_print_flag_sym *sym = NULL;
-       struct tep_print_arg *args = evsel->tp_format->print_fmt.args;
+       const struct tep_event *tp_format = evsel__tp_format(evsel);
+       struct tep_print_arg *args = tp_format ? tp_format->print_fmt.args : NULL;
 
        if ((args == NULL) || (args->next == NULL))
                return NULL;
index 9e47905f75a6b8d393253b3610fd8fb8e3ba96f0..aad607b8918f1477f30dfee81df86dc26e1aa247 100644 (file)
@@ -2289,8 +2289,13 @@ static void process_event(struct perf_script *script,
        }
 #ifdef HAVE_LIBTRACEEVENT
        if (PRINT_FIELD(TRACE) && sample->raw_data) {
-               event_format__fprintf(evsel->tp_format, sample->cpu,
-                                     sample->raw_data, sample->raw_size, fp);
+               const struct tep_event *tp_format = evsel__tp_format(evsel);
+
+               if (tp_format) {
+                       event_format__fprintf(tp_format, sample->cpu,
+                                             sample->raw_data, sample->raw_size,
+                                             fp);
+               }
        }
 #endif
        if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
index 6a1a128fe645014d0347ad4ec3e0c9e77ec59aee..3c46de1a8d79bfe64ad6661929f2bdc98ebba55e 100644 (file)
@@ -389,7 +389,12 @@ static struct syscall_arg_fmt *evsel__syscall_arg_fmt(struct evsel *evsel)
        }
 
        if (et->fmt == NULL) {
-               et->fmt = calloc(evsel->tp_format->format.nr_fields, sizeof(struct syscall_arg_fmt));
+               const struct tep_event *tp_format = evsel__tp_format(evsel);
+
+               if (tp_format == NULL)
+                       goto out_delete;
+
+               et->fmt = calloc(tp_format->format.nr_fields, sizeof(struct syscall_arg_fmt));
                if (et->fmt == NULL)
                        goto out_delete;
        }
@@ -2154,8 +2159,12 @@ static int evsel__init_tp_arg_scnprintf(struct evsel *evsel, bool *use_btf)
        struct syscall_arg_fmt *fmt = evsel__syscall_arg_fmt(evsel);
 
        if (fmt != NULL) {
-               syscall_arg_fmt__init_array(fmt, evsel->tp_format->format.fields, use_btf);
-               return 0;
+               const struct tep_event *tp_format = evsel__tp_format(evsel);
+
+               if (tp_format) {
+                       syscall_arg_fmt__init_array(fmt, tp_format->format.fields, use_btf);
+                       return 0;
+               }
        }
 
        return -ENOMEM;
@@ -3027,7 +3036,8 @@ static size_t trace__fprintf_tp_fields(struct trace *trace, struct evsel *evsel,
 {
        char bf[2048];
        size_t size = sizeof(bf);
-       struct tep_format_field *field = evsel->tp_format->format.fields;
+       const struct tep_event *tp_format = evsel__tp_format(evsel);
+       struct tep_format_field *field = tp_format ? tp_format->format.fields : NULL;
        struct syscall_arg_fmt *arg = __evsel__syscall_arg_fmt(evsel);
        size_t printed = 0, btf_printed;
        unsigned long val;
@@ -3145,11 +3155,13 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
 
        if (evsel__is_bpf_output(evsel)) {
                bpf_output__fprintf(trace, sample);
-       } else if (evsel->tp_format) {
-               if (strncmp(evsel->tp_format->name, "sys_enter_", 10) ||
-                   trace__fprintf_sys_enter(trace, evsel, sample)) {
+       } else {
+               const struct tep_event *tp_format = evsel__tp_format(evsel);
+
+               if (tp_format && (strncmp(tp_format->name, "sys_enter_", 10) ||
+                                 trace__fprintf_sys_enter(trace, evsel, sample))) {
                        if (trace->libtraceevent_print) {
-                               event_format__fprintf(evsel->tp_format, sample->cpu,
+                               event_format__fprintf(tp_format, sample->cpu,
                                                      sample->raw_data, sample->raw_size,
                                                      trace->output);
                        } else {
@@ -4077,17 +4089,23 @@ static int ordered_events__deliver_event(struct ordered_events *oe,
 static struct syscall_arg_fmt *evsel__find_syscall_arg_fmt_by_name(struct evsel *evsel, char *arg,
                                                                   char **type)
 {
-       struct tep_format_field *field;
        struct syscall_arg_fmt *fmt = __evsel__syscall_arg_fmt(evsel);
+       const struct tep_event *tp_format;
+
+       if (!fmt)
+               return NULL;
 
-       if (evsel->tp_format == NULL || fmt == NULL)
+       tp_format = evsel__tp_format(evsel);
+       if (!tp_format)
                return NULL;
 
-       for (field = evsel->tp_format->format.fields; field; field = field->next, ++fmt)
+       for (const struct tep_format_field *field = tp_format->format.fields; field;
+            field = field->next, ++fmt) {
                if (strcmp(field->name, arg) == 0) {
                        *type = field->type;
                        return fmt;
                }
+       }
 
        return NULL;
 }
@@ -4843,13 +4861,18 @@ static void evsel__set_syscall_arg_fmt(struct evsel *evsel, const char *name)
                const struct syscall_fmt *scfmt = syscall_fmt__find(name);
 
                if (scfmt) {
-                       int skip = 0;
+                       const struct tep_event *tp_format = evsel__tp_format(evsel);
+
+                       if (tp_format) {
+                               int skip = 0;
 
-                       if (strcmp(evsel->tp_format->format.fields->name, "__syscall_nr") == 0 ||
-                           strcmp(evsel->tp_format->format.fields->name, "nr") == 0)
-                               ++skip;
+                               if (strcmp(tp_format->format.fields->name, "__syscall_nr") == 0 ||
+                                   strcmp(tp_format->format.fields->name, "nr") == 0)
+                                       ++skip;
 
-                       memcpy(fmt + skip, scfmt->arg, (evsel->tp_format->format.nr_fields - skip) * sizeof(*fmt));
+                               memcpy(fmt + skip, scfmt->arg,
+                                      (tp_format->format.nr_fields - skip) * sizeof(*fmt));
+                       }
                }
        }
 }
@@ -4859,10 +4882,16 @@ static int evlist__set_syscall_tp_fields(struct evlist *evlist, bool *use_btf)
        struct evsel *evsel;
 
        evlist__for_each_entry(evlist, evsel) {
-               if (evsel->priv || !evsel->tp_format)
+               const struct tep_event *tp_format;
+
+               if (evsel->priv)
+                       continue;
+
+               tp_format = evsel__tp_format(evsel);
+               if (!tp_format)
                        continue;
 
-               if (strcmp(evsel->tp_format->system, "syscalls")) {
+               if (strcmp(tp_format->system, "syscalls")) {
                        evsel__init_tp_arg_scnprintf(evsel, use_btf);
                        continue;
                }
@@ -4870,20 +4899,24 @@ static int evlist__set_syscall_tp_fields(struct evlist *evlist, bool *use_btf)
                if (evsel__init_syscall_tp(evsel))
                        return -1;
 
-               if (!strncmp(evsel->tp_format->name, "sys_enter_", 10)) {
+               if (!strncmp(tp_format->name, "sys_enter_", 10)) {
                        struct syscall_tp *sc = __evsel__syscall_tp(evsel);
 
                        if (__tp_field__init_ptr(&sc->args, sc->id.offset + sizeof(u64)))
                                return -1;
 
-                       evsel__set_syscall_arg_fmt(evsel, evsel->tp_format->name + sizeof("sys_enter_") - 1);
-               } else if (!strncmp(evsel->tp_format->name, "sys_exit_", 9)) {
+                       evsel__set_syscall_arg_fmt(evsel,
+                                                  tp_format->name + sizeof("sys_enter_") - 1);
+               } else if (!strncmp(tp_format->name, "sys_exit_", 9)) {
                        struct syscall_tp *sc = __evsel__syscall_tp(evsel);
 
-                       if (__tp_field__init_uint(&sc->ret, sizeof(u64), sc->id.offset + sizeof(u64), evsel->needs_swap))
+                       if (__tp_field__init_uint(&sc->ret, sizeof(u64),
+                                                 sc->id.offset + sizeof(u64),
+                                                 evsel->needs_swap))
                                return -1;
 
-                       evsel__set_syscall_arg_fmt(evsel, evsel->tp_format->name + sizeof("sys_exit_") - 1);
+                       evsel__set_syscall_arg_fmt(evsel,
+                                                  tp_format->name + sizeof("sys_exit_") - 1);
                }
        }
 
index f0599c61fab47df518bb7e4fb562cc551208c99c..5e7ff09fbc95da33a2a8a147f9a71d14a7154026 100644 (file)
@@ -426,8 +426,9 @@ static int add_tracepoint_values(struct ctf_writer *cw,
                                 struct evsel *evsel,
                                 struct perf_sample *sample)
 {
-       struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
-       struct tep_format_field *fields        = evsel->tp_format->format.fields;
+       const struct tep_event *tp_format = evsel__tp_format(evsel);
+       struct tep_format_field *common_fields = tp_format->format.common_fields;
+       struct tep_format_field *fields        = tp_format->format.fields;
        int ret;
 
        ret = add_tracepoint_fields_values(cw, event_class, event,
@@ -1064,8 +1065,9 @@ static int add_tracepoint_types(struct ctf_writer *cw,
                                struct evsel *evsel,
                                struct bt_ctf_event_class *class)
 {
-       struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
-       struct tep_format_field *fields        = evsel->tp_format->format.fields;
+       const struct tep_event *tp_format = evsel__tp_format(evsel);
+       struct tep_format_field *common_fields = tp_format ? tp_format->format.common_fields : NULL;
+       struct tep_format_field *fields        = tp_format ? tp_format->format.fields : NULL;
        int ret;
 
        ret = add_tracepoint_fields_types(cw, common_fields, class);
index 8304cd2d4a9ceb26629b27caad0201ddd61505d2..d9f805bf6fb0b89b2eb9226dc21eaa9c3357145c 100644 (file)
@@ -230,12 +230,12 @@ static int process_sample_event(const struct perf_tool *tool,
 
 #ifdef HAVE_LIBTRACEEVENT
        if (sample->raw_data) {
-               int i;
-               struct tep_format_field **fields;
+               struct tep_event *tp_format = evsel__tp_format(evsel);
+               struct tep_format_field **fields = tp_format ? tep_event_fields(tp_format) : NULL;
 
-               fields = tep_event_fields(evsel->tp_format);
                if (fields) {
-                       i = 0;
+                       int i = 0;
+
                        while (fields[i]) {
                                struct trace_seq s;
 
index f745723d486ba962a621a04301323e254803f4e0..4759d644a5aa2fad2be83399f2bcf20d6731402e 100644 (file)
@@ -571,6 +571,7 @@ struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool
                        evsel->tp_format = trace_event__tp_format(sys, name);
                        if (IS_ERR(evsel->tp_format)) {
                                err = PTR_ERR(evsel->tp_format);
+                               evsel->tp_format = NULL;
                                goto out_free;
                        }
                        attr.config = evsel->tp_format->id;
@@ -3218,12 +3219,16 @@ u16 evsel__id_hdr_size(const struct evsel *evsel)
 #ifdef HAVE_LIBTRACEEVENT
 struct tep_format_field *evsel__field(struct evsel *evsel, const char *name)
 {
-       return tep_find_field(evsel->tp_format, name);
+       struct tep_event *tp_format = evsel__tp_format(evsel);
+
+       return tp_format ? tep_find_field(tp_format, name) : NULL;
 }
 
 struct tep_format_field *evsel__common_field(struct evsel *evsel, const char *name)
 {
-       return tep_find_common_field(evsel->tp_format, name);
+       struct tep_event *tp_format = evsel__tp_format(evsel);
+
+       return tp_format ? tep_find_common_field(tp_format, name) : NULL;
 }
 
 void *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name)
index 04934a7af174524ebf35f4ad868522b23617ad6a..c3e53d320bf53f43b4b480ad2c0f92e37c3ef634 100644 (file)
@@ -257,6 +257,11 @@ static inline struct evsel *evsel__newtp(const char *sys, const char *name)
 {
        return evsel__newtp_idx(sys, name, 0, true);
 }
+
+static inline struct tep_event *evsel__tp_format(struct evsel *evsel)
+{
+       return evsel->tp_format;
+}
 #endif
 
 #ifdef HAVE_LIBTRACEEVENT
index 86b7f46f9e2a9d15b2192f642dd88866d75d3dda..103984b29b1e10ae2f87c2ba855e67af023506a5 100644 (file)
@@ -81,13 +81,15 @@ int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE
 #ifdef HAVE_LIBTRACEEVENT
        if (details->trace_fields) {
                struct tep_format_field *field;
+               const struct tep_event *tp_format;
 
                if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
                        printed += comma_fprintf(fp, &first, " (not a tracepoint)");
                        goto out;
                }
 
-               field = evsel->tp_format->format.fields;
+               tp_format = evsel__tp_format(evsel);
+               field = tp_format ? tp_format->format.fields : NULL;
                if (field == NULL) {
                        printed += comma_fprintf(fp, &first, " (no trace field)");
                        goto out;
index 85b7f188f729943bffb9e89ab9f0cc457107f846..e261a57b87d4fd64e36db85d9bbfe966f79e3ddd 100644 (file)
@@ -344,7 +344,7 @@ static void perl_process_tracepoint(struct perf_sample *sample,
                                    struct addr_location *al)
 {
        struct thread *thread = al->thread;
-       struct tep_event *event = evsel->tp_format;
+       struct tep_event *event;
        struct tep_format_field *field;
        static char handler[256];
        unsigned long long val;
@@ -362,6 +362,7 @@ static void perl_process_tracepoint(struct perf_sample *sample,
        if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
                return;
 
+       event = evsel__tp_format(evsel);
        if (!event) {
                pr_debug("ug! no event found for type %" PRIu64, (u64)evsel->core.attr.config);
                return;
index 8bdae066e83972a1de1615d676388af0d4b596a7..231233639b5dc09c83430c9127ff9e8aa5f31b03 100644 (file)
@@ -949,7 +949,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
                                      struct addr_location *al,
                                      struct addr_location *addr_al)
 {
-       struct tep_event *event = evsel->tp_format;
+       struct tep_event *event;
        PyObject *handler, *context, *t, *obj = NULL, *callchain;
        PyObject *dict = NULL, *all_entries_dict = NULL;
        static char handler_name[256];
@@ -966,6 +966,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
 
        bitmap_zero(events_defined, TRACE_EVENT_TYPE_MAX);
 
+       event = evsel__tp_format(evsel);
        if (!event) {
                snprintf(handler_name, sizeof(handler_name),
                         "ug! no event found for type %" PRIu64, (u64)evsel->core.attr.config);
index 9dd60c7869a28dae1a24ff3042422fe36a151af4..3dd33721823f365deaaafafbe87c5388391d5eab 100644 (file)
@@ -1038,17 +1038,19 @@ static char *get_trace_output(struct hist_entry *he)
                .data = he->raw_data,
                .size = he->raw_size,
        };
+       struct tep_event *tp_format;
 
        evsel = hists_to_evsel(he->hists);
 
        trace_seq_init(&seq);
-       if (symbol_conf.raw_trace) {
-               tep_print_fields(&seq, he->raw_data, he->raw_size,
-                                evsel->tp_format);
-       } else {
-               tep_print_event(evsel->tp_format->tep,
-                               &seq, &rec, "%s", TEP_PRINT_INFO);
+       tp_format = evsel__tp_format(evsel);
+       if (tp_format) {
+               if (symbol_conf.raw_trace)
+                       tep_print_fields(&seq, he->raw_data, he->raw_size, tp_format);
+               else
+                       tep_print_event(tp_format->tep, &seq, &rec, "%s", TEP_PRINT_INFO);
        }
+
        /*
         * Trim the buffer, it starts at 4KB and we're not going to
         * add anything more to this buffer.
@@ -3293,9 +3295,8 @@ static int __dynamic_dimension__add(struct evsel *evsel,
 static int add_evsel_fields(struct evsel *evsel, bool raw_trace, int level)
 {
        int ret;
-       struct tep_format_field *field;
-
-       field = evsel->tp_format->format.fields;
+       struct tep_event *tp_format = evsel__tp_format(evsel);
+       struct tep_format_field *field = tp_format ? tp_format->format.fields : NULL;
        while (field) {
                ret = __dynamic_dimension__add(evsel, field, raw_trace, level);
                if (ret < 0)
@@ -3328,13 +3329,19 @@ static int add_all_matching_fields(struct evlist *evlist,
 {
        int ret = -ESRCH;
        struct evsel *evsel;
-       struct tep_format_field *field;
 
        evlist__for_each_entry(evlist, evsel) {
+               struct tep_event *tp_format;
+               struct tep_format_field *field;
+
                if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
                        continue;
 
-               field = tep_find_any_field(evsel->tp_format, field_name);
+               tp_format = evsel__tp_format(evsel);
+               if (tp_format == NULL)
+                       continue;
+
+               field = tep_find_any_field(tp_format, field_name);
                if (field == NULL)
                        continue;
 
@@ -3416,7 +3423,9 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok,
        if (!strcmp(field_name, "*")) {
                ret = add_evsel_fields(evsel, raw_trace, level);
        } else {
-               struct tep_format_field *field = tep_find_any_field(evsel->tp_format, field_name);
+               struct tep_event *tp_format = evsel__tp_format(evsel);
+               struct tep_format_field *field =
+                       tp_format ? tep_find_any_field(tp_format, field_name) : NULL;
 
                if (field == NULL) {
                        pr_debug("Cannot find event field for %s.%s\n",
index 5596fcda2c1083b3dfcf001f9810c99af64a16a3..edfde7056c99aae8f575e22f0fa0d98768bca1d7 100644 (file)
@@ -28,12 +28,14 @@ void scripting_context__update(struct scripting_context *c,
                               struct addr_location *al,
                               struct addr_location *addr_al)
 {
-       c->event_data = sample->raw_data;
-       c->pevent = NULL;
 #ifdef HAVE_LIBTRACEEVENT
-       if (evsel->tp_format)
-               c->pevent = evsel->tp_format->tep;
+       const struct tep_event *tp_format = evsel__tp_format(evsel);
+
+       c->pevent = tp_format ? tp_format->tep : NULL;
+#else
+       c->pevent = NULL;
 #endif
+       c->event_data = sample->raw_data;
        c->event = event;
        c->sample = sample;
        c->evsel = evsel;