From 2b00bb627f62ed1c6180f49f7883789bc5e1b33f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 17 Oct 2019 16:37:18 -0300 Subject: [PATCH] perf trace: Introduce 'struct evsel__trace' for evsel->priv needs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For syscalls we need to cache the 'syscall_id' and 'ret' field offsets but as well have a pointer to the syscall_fmt_arg array for the fields, so that we can expand strings in filter expressions, so introduce a 'struct evsel_trace' to have in evsel->priv that allows for that. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-hx8ukasuws5sz6rsar73cocv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 54 +++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 1d2ed2823202..5792278065f6 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -285,21 +285,47 @@ struct syscall_tp { }; }; +/* + * The evsel->priv as used by 'perf trace' + * sc: for raw_syscalls:sys_{enter,exit} and syscalls:sys_{enter,exit}_SYSCALLNAME + * fmt: for all the other tracepoints + */ +struct evsel_trace { + struct syscall_tp sc; + struct syscall_arg_fmt *fmt; +}; + +static struct evsel_trace *evsel_trace__new(void) +{ + return zalloc(sizeof(struct evsel_trace)); +} + +static void evsel_trace__delete(struct evsel_trace *et) +{ + if (et == NULL) + return; + + zfree(&et->fmt); + free(et); +} + /* * Used with raw_syscalls:sys_{enter,exit} and with the * syscalls:sys_{enter,exit}_SYSCALL tracepoints */ static inline struct syscall_tp *__evsel__syscall_tp(struct evsel *evsel) { - struct syscall_tp *sc = evsel->priv; + struct evsel_trace *et = evsel->priv; - return sc; + return &et->sc; } static struct syscall_tp *evsel__syscall_tp(struct evsel *evsel) { if (evsel->priv == NULL) { - evsel->priv = zalloc(sizeof(struct syscall_tp)); + evsel->priv = evsel_trace__new(); + if (evsel->priv == NULL) + return NULL; } return __evsel__syscall_tp(evsel); @@ -310,18 +336,34 @@ static struct syscall_tp *evsel__syscall_tp(struct evsel *evsel) */ static inline struct syscall_arg_fmt *__evsel__syscall_arg_fmt(struct evsel *evsel) { - struct syscall_arg_fmt *fmt = evsel->priv; + struct evsel_trace *et = evsel->priv; - return fmt; + return et->fmt; } static struct syscall_arg_fmt *evsel__syscall_arg_fmt(struct evsel *evsel) { + struct evsel_trace *et = evsel->priv; + if (evsel->priv == NULL) { - evsel->priv = calloc(evsel->tp_format->format.nr_fields, sizeof(struct syscall_arg_fmt)); + et = evsel->priv = evsel_trace__new(); + + if (et == NULL) + return NULL; + } + + if (et->fmt == NULL) { + et->fmt = calloc(evsel->tp_format->format.nr_fields, sizeof(struct syscall_arg_fmt)); + if (et->fmt == NULL) + goto out_delete; } return __evsel__syscall_arg_fmt(evsel); + +out_delete: + evsel_trace__delete(evsel->priv); + evsel->priv = NULL; + return NULL; } static int perf_evsel__init_tp_uint_field(struct evsel *evsel, -- 2.45.2