Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5dafd7cb authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo' of...

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

New user visible features:

  - Support multiple probes on different binaries on the same command line (Masami Hiramatsu)

User visible changes:

  - Fix synthesizing fork_event.ppid for non-main thread (David Ahern)

  - Fix cross-endian analysis (David Ahern)

  - Fix segfault in 'perf buildid-list' when show DSOs with hits (He Kuang)

Infrastructure changes:

  - Fix type for references to data_head/tail (David Ahern)

  - Fix error path to do closedir() when synthesizing threads (Arnaldo Carvalho de Melo)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 51ab7155 7b8283b5
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ static struct {
	bool mod_events;
	bool uprobes;
	bool quiet;
	bool target_used;
	int nevents;
	struct perf_probe_event events[MAX_PROBES];
	struct strlist *dellist;
@@ -78,6 +79,12 @@ static int parse_probe_event(const char *str)
	}

	pev->uprobes = params.uprobes;
	if (params.target) {
		pev->target = strdup(params.target);
		if (!pev->target)
			return -ENOMEM;
		params.target_used = true;
	}

	/* Parse a perf-probe command into event */
	ret = parse_perf_probe_command(str, pev);
@@ -102,6 +109,7 @@ static int set_target(const char *ptr)
		params.target = strdup(ptr);
		if (!params.target)
			return -ENOMEM;
		params.target_used = false;

		found = 1;
		buf = ptr + (strlen(ptr) - 3);
@@ -178,7 +186,7 @@ static int opt_set_target(const struct option *opt, const char *str,
	int ret = -ENOENT;
	char *tmp;

	if  (str && !params.target) {
	if  (str) {
		if (!strcmp(opt->long_name, "exec"))
			params.uprobes = true;
#ifdef HAVE_DWARF_SUPPORT
@@ -200,7 +208,9 @@ static int opt_set_target(const struct option *opt, const char *str,
			if (!tmp)
				return -ENOMEM;
		}
		free(params.target);
		params.target = tmp;
		params.target_used = false;
		ret = 0;
	}

@@ -485,9 +495,14 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
	}

	if (params.nevents) {
		/* Ensure the last given target is used */
		if (params.target && !params.target_used) {
			pr_warning("  Error: -x/-m must follow the probe definitions.\n");
			usage_with_options(probe_usage, options);
		}

		ret = add_perf_probe_events(params.events, params.nevents,
					    params.max_probe_points,
					    params.target,
					    params.force_add);
		if (ret < 0) {
			pr_err_with_code("  Error: Failed to add events.", ret);
+2 −2
Original line number Diff line number Diff line
@@ -70,8 +70,8 @@ static int process_synthesized_event(struct perf_tool *tool,
static int record__mmap_read(struct record *rec, int idx)
{
	struct perf_mmap *md = &rec->evlist->mmap[idx];
	unsigned int head = perf_mmap__read_head(md);
	unsigned int old = md->prev;
	u64 head = perf_mmap__read_head(md);
	u64 old = md->prev;
	unsigned char *data = md->base + page_size;
	unsigned long size;
	void *buf;
+2 −6
Original line number Diff line number Diff line
@@ -59,12 +59,8 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused,
	dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid,
		    event->fork.ppid, event->fork.ptid);

	if (thread) {
		rb_erase(&thread->rb_node, &machine->threads);
		if (machine->last_match == thread)
			thread__zput(machine->last_match);
		thread__put(thread);
	}
	if (thread)
		machine__remove_thread(machine, thread);

	return 0;
}
+21 −10
Original line number Diff line number Diff line
@@ -183,8 +183,18 @@ static int perf_event__synthesize_fork(struct perf_tool *tool,
{
	memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size);

	/*
	 * for main thread set parent to ppid from status file. For other
	 * threads set parent pid to main thread. ie., assume main thread
	 * spawns all threads in a process
	*/
	if (tgid == pid) {
		event->fork.ppid = ppid;
		event->fork.ptid = ppid;
	} else {
		event->fork.ppid = tgid;
		event->fork.ptid = tgid;
	}
	event->fork.pid  = tgid;
	event->fork.tid  = pid;
	event->fork.header.type = PERF_RECORD_FORK;
@@ -377,6 +387,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,
	DIR *tasks;
	struct dirent dirent, *next;
	pid_t tgid, ppid;
	int rc = 0;

	/* special case: only send one comm event using passed in pid */
	if (!full) {
@@ -404,38 +415,38 @@ static int __event__synthesize_thread(union perf_event *comm_event,

	while (!readdir_r(tasks, &dirent, &next) && next) {
		char *end;
		int rc = 0;
		pid_t _pid;

		_pid = strtol(dirent.d_name, &end, 10);
		if (*end)
			continue;

		rc = -1;
		if (perf_event__prepare_comm(comm_event, _pid, machine,
					     &tgid, &ppid) != 0)
			return -1;
			break;

		if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
						ppid, process, machine) < 0)
			return -1;
			break;
		/*
		 * Send the prepared comm event
		 */
		if (process(tool, comm_event, &synth_sample, machine) != 0)
			return -1;
			break;

		rc = 0;
		if (_pid == pid) {
			/* process the parent's maps too */
			rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
						process, machine, mmap_data);
		}

			if (rc)
			return rc;
				break;
		}
	}

	closedir(tasks);
	return 0;
	return rc;
}

int perf_event__synthesize_thread_map(struct perf_tool *tool,
+3 −3
Original line number Diff line number Diff line
@@ -634,8 +634,8 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
{
	struct perf_mmap *md = &evlist->mmap[idx];
	unsigned int head = perf_mmap__read_head(md);
	unsigned int old = md->prev;
	u64 head = perf_mmap__read_head(md);
	u64 old = md->prev;
	unsigned char *data = md->base + page_size;
	union perf_event *event = NULL;

@@ -716,7 +716,7 @@ void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
	struct perf_mmap *md = &evlist->mmap[idx];

	if (!evlist->overwrite) {
		unsigned int old = md->prev;
		u64 old = md->prev;

		perf_mmap__write_tail(md, old);
	}
Loading