diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-10-17 16:37:18 -0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-10-17 17:27:43 -0300 |
commit | 2b00bb627f62ed1c6180f49f7883789bc5e1b33f (patch) | |
tree | f56e4417628d220ba4e72f30eb0c5b4409bee200 | |
parent | 8b913df50f56a26b9e336becdd0af9d5ce3831cd (diff) |
perf trace: Introduce 'struct evsel__trace' for evsel->priv needs
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 <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Luis Cláudio Gonçalves <lclaudio@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/n/tip-hx8ukasuws5sz6rsar73cocv@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-trace.c | 54 |
1 files 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 @@ -286,20 +286,46 @@ 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, |