diff options
Diffstat (limited to 'tools/perf/builtin-inject.c')
| -rw-r--r-- | tools/perf/builtin-inject.c | 96 | 
1 files changed, 30 insertions, 66 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 372ecb3e2c06..7e124a7b8bfd 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -45,6 +45,7 @@ struct perf_inject {  	u64			aux_id;  	struct list_head	samples;  	struct itrace_synth_opts itrace_synth_opts; +	char			event_copy[PERF_SAMPLE_MAX_SIZE];  };  struct event_entry { @@ -214,6 +215,28 @@ static int perf_event__drop_aux(struct perf_tool *tool,  	return 0;  } +static union perf_event * +perf_inject__cut_auxtrace_sample(struct perf_inject *inject, +				 union perf_event *event, +				 struct perf_sample *sample) +{ +	size_t sz1 = sample->aux_sample.data - (void *)event; +	size_t sz2 = event->header.size - sample->aux_sample.size - sz1; +	union perf_event *ev = (union perf_event *)inject->event_copy; + +	if (sz1 > event->header.size || sz2 > event->header.size || +	    sz1 + sz2 > event->header.size || +	    sz1 < sizeof(struct perf_event_header) + sizeof(u64)) +		return event; + +	memcpy(ev, event, sz1); +	memcpy((void *)ev + sz1, (void *)event + event->header.size - sz2, sz2); +	ev->header.size = sz1 + sz2; +	((u64 *)((void *)ev + sz1))[-1] = 0; + +	return ev; +} +  typedef int (*inject_handler)(struct perf_tool *tool,  			      union perf_event *event,  			      struct perf_sample *sample, @@ -226,6 +249,9 @@ static int perf_event__repipe_sample(struct perf_tool *tool,  				     struct evsel *evsel,  				     struct machine *machine)  { +	struct perf_inject *inject = container_of(tool, struct perf_inject, +						  tool); +  	if (evsel && evsel->handler) {  		inject_handler f = evsel->handler;  		return f(tool, event, sample, evsel, machine); @@ -233,6 +259,9 @@ static int perf_event__repipe_sample(struct perf_tool *tool,  	build_id__mark_dso_hit(tool, event, sample, evsel, machine); +	if (inject->itrace_synth_opts.set && sample->aux_sample.size) +		event = perf_inject__cut_auxtrace_sample(inject, event, sample); +  	return perf_event__repipe_synth(tool, event);  } @@ -374,17 +403,6 @@ static int perf_event__repipe_tracing_data(struct perf_session *session,  	return err;  } -static int perf_event__repipe_id_index(struct perf_session *session, -				       union perf_event *event) -{ -	int err; - -	perf_event__repipe_synth(session->tool, event); -	err = perf_event__process_id_index(session, event); - -	return err; -} -  static int dso__read_build_id(struct dso *dso)  {  	if (dso->has_build_id) @@ -578,58 +596,6 @@ static void strip_init(struct perf_inject *inject)  		evsel->handler = drop_sample;  } -static bool has_tracking(struct evsel *evsel) -{ -	return evsel->core.attr.mmap || evsel->core.attr.mmap2 || evsel->core.attr.comm || -	       evsel->core.attr.task; -} - -#define COMPAT_MASK (PERF_SAMPLE_ID | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \ -		     PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_IDENTIFIER) - -/* - * In order that the perf.data file is parsable, tracking events like MMAP need - * their selected event to exist, except if there is only 1 selected event left - * and it has a compatible sample type. - */ -static bool ok_to_remove(struct evlist *evlist, -			 struct evsel *evsel_to_remove) -{ -	struct evsel *evsel; -	int cnt = 0; -	bool ok = false; - -	if (!has_tracking(evsel_to_remove)) -		return true; - -	evlist__for_each_entry(evlist, evsel) { -		if (evsel->handler != drop_sample) { -			cnt += 1; -			if ((evsel->core.attr.sample_type & COMPAT_MASK) == -			    (evsel_to_remove->core.attr.sample_type & COMPAT_MASK)) -				ok = true; -		} -	} - -	return ok && cnt == 1; -} - -static void strip_fini(struct perf_inject *inject) -{ -	struct evlist *evlist = inject->session->evlist; -	struct evsel *evsel, *tmp; - -	/* Remove non-synthesized evsels if possible */ -	evlist__for_each_entry_safe(evlist, tmp, evsel) { -		if (evsel->handler == drop_sample && -		    ok_to_remove(evlist, evsel)) { -			pr_debug("Deleting %s\n", perf_evsel__name(evsel)); -			evlist__remove(evlist, evsel); -			evsel__delete(evsel); -		} -	} -} -  static int __cmd_inject(struct perf_inject *inject)  {  	int ret = -EINVAL; @@ -674,7 +640,7 @@ static int __cmd_inject(struct perf_inject *inject)  		inject->tool.comm	    = perf_event__repipe_comm;  		inject->tool.namespaces	    = perf_event__repipe_namespaces;  		inject->tool.exit	    = perf_event__repipe_exit; -		inject->tool.id_index	    = perf_event__repipe_id_index; +		inject->tool.id_index	    = perf_event__process_id_index;  		inject->tool.auxtrace_info  = perf_event__process_auxtrace_info;  		inject->tool.auxtrace	    = perf_event__process_auxtrace;  		inject->tool.aux	    = perf_event__drop_aux; @@ -729,8 +695,6 @@ static int __cmd_inject(struct perf_inject *inject)  				evlist__remove(session->evlist, evsel);  				evsel__delete(evsel);  			} -			if (inject->strip) -				strip_fini(inject);  		}  		session->header.data_offset = output_data_offset;  		session->header.data_size = inject->bytes_written;  |