Commit 8b913df5 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

perf trace: Hide evsel->access further, simplify code

Next step will be to have a 'struct evsel_trace' to allow for handling
the syscalls tracepoints via the strace-like code while reusing parts of
that code with the other tracepoints, where we don't have things like
the 'syscall_nr' or 'ret' ((raw_)?syscalls:sys_{enter,exit}(_SYSCALL)?)
args that we want to cache offsets and have been using evsel->priv for
that, while for the other tracepoints we'll have just an array of
'struct syscall_arg_fmt' (i.e. ->scnprint() for number->string and
->strtoul() string->number conversions and other state those functions
need).

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-fre21jbyoqxmmquxcho7oa0x@git.kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent fecd9907
Loading
Loading
Loading
Loading
+31 −26
Original line number Diff line number Diff line
@@ -296,6 +296,15 @@ static inline struct syscall_tp *__evsel__syscall_tp(struct evsel *evsel)
	return sc;
}

static struct syscall_tp *evsel__syscall_tp(struct evsel *evsel)
{
	if (evsel->priv == NULL) {
		evsel->priv = zalloc(sizeof(struct syscall_tp));
	}

	return __evsel__syscall_tp(evsel);
}

/*
 * Used with all the other tracepoints.
 */
@@ -306,6 +315,15 @@ static inline struct syscall_arg_fmt *__evsel__syscall_arg_fmt(struct evsel *evs
	return fmt;
}

static struct syscall_arg_fmt *evsel__syscall_arg_fmt(struct evsel *evsel)
{
	if (evsel->priv == NULL) {
		evsel->priv = calloc(evsel->tp_format->format.nr_fields, sizeof(struct syscall_arg_fmt));
	}

	return __evsel__syscall_arg_fmt(evsel);
}

static int perf_evsel__init_tp_uint_field(struct evsel *evsel,
					  struct tp_field *field,
					  const char *name)
@@ -346,41 +364,34 @@ static void evsel__delete_priv(struct evsel *evsel)

static int perf_evsel__init_syscall_tp(struct evsel *evsel)
{
	struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp));
	struct syscall_tp *sc = evsel__syscall_tp(evsel);

	if (evsel->priv != NULL) {
	if (sc != NULL) {
		if (perf_evsel__init_tp_uint_field(evsel, &sc->id, "__syscall_nr") &&
		    perf_evsel__init_tp_uint_field(evsel, &sc->id, "nr"))
			goto out_delete;
			return -ENOENT;
		return 0;
	}

	return -ENOMEM;
out_delete:
	zfree(&evsel->priv);
	return -ENOENT;
}

static int perf_evsel__init_augmented_syscall_tp(struct evsel *evsel, struct evsel *tp)
{
	struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp));
	struct syscall_tp *sc = evsel__syscall_tp(evsel);

	if (evsel->priv != NULL) {
	if (sc != NULL) {
		struct tep_format_field *syscall_id = perf_evsel__field(tp, "id");
		if (syscall_id == NULL)
			syscall_id = perf_evsel__field(tp, "__syscall_nr");
		if (syscall_id == NULL)
			goto out_delete;
		if (__tp_field__init_uint(&sc->id, syscall_id->size, syscall_id->offset, evsel->needs_swap))
			goto out_delete;
		if (syscall_id == NULL ||
		    __tp_field__init_uint(&sc->id, syscall_id->size, syscall_id->offset, evsel->needs_swap))
			return -EINVAL;

		return 0;
	}

	return -ENOMEM;
out_delete:
	zfree(&evsel->priv);
	return -EINVAL;
}

static int perf_evsel__init_augmented_syscall_tp_args(struct evsel *evsel)
@@ -399,20 +410,15 @@ static int perf_evsel__init_augmented_syscall_tp_ret(struct evsel *evsel)

static int perf_evsel__init_raw_syscall_tp(struct evsel *evsel, void *handler)
{
	evsel->priv = malloc(sizeof(struct syscall_tp));
	if (evsel->priv != NULL) {
	if (evsel__syscall_tp(evsel) != NULL) {
		if (perf_evsel__init_sc_tp_uint_field(evsel, id))
			goto out_delete;
			return -ENOENT;

		evsel->handler = handler;
		return 0;
	}

	return -ENOMEM;

out_delete:
	zfree(&evsel->priv);
	return -ENOENT;
}

static struct evsel *perf_evsel__raw_syscall_newtp(const char *direction, void *handler)
@@ -1690,11 +1696,10 @@ static int trace__read_syscall_info(struct trace *trace, int id)

static int perf_evsel__init_tp_arg_scnprintf(struct evsel *evsel)
{
	int nr_args = evsel->tp_format->format.nr_fields;
	struct syscall_arg_fmt *fmt = evsel__syscall_arg_fmt(evsel);

	evsel->priv = calloc(nr_args, sizeof(struct syscall_arg_fmt));
	if (evsel->priv != NULL) {
		syscall_arg_fmt__init_array(evsel->priv, evsel->tp_format->format.fields);
	if (fmt != NULL) {
		syscall_arg_fmt__init_array(fmt, evsel->tp_format->format.fields);
		return 0;
	}