summary refs log tree commit diff
path: root/tools/perf/util/jitdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/jitdump.c')
-rw-r--r--tools/perf/util/jitdump.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
index 055bab7a92b3..9760d8e7b386 100644
--- a/tools/perf/util/jitdump.c
+++ b/tools/perf/util/jitdump.c
@@ -18,6 +18,7 @@
 #include "event.h"
 #include "debug.h"
 #include "evlist.h"
+#include "namespaces.h"
 #include "symbol.h"
 #include <elf.h>
 
@@ -35,6 +36,7 @@ struct jit_buf_desc {
 	struct perf_data *output;
 	struct perf_session *session;
 	struct machine *machine;
+	struct nsinfo  *nsi;
 	union jr_entry   *entry;
 	void             *buf;
 	uint64_t	 sample_type;
@@ -72,7 +74,8 @@ struct jit_tool {
 #define get_jit_tool(t) (container_of(tool, struct jit_tool, tool))
 
 static int
-jit_emit_elf(char *filename,
+jit_emit_elf(struct jit_buf_desc *jd,
+	     char *filename,
 	     const char *sym,
 	     uint64_t code_addr,
 	     const void *code,
@@ -83,14 +86,18 @@ jit_emit_elf(char *filename,
 	     uint32_t unwinding_header_size,
 	     uint32_t unwinding_size)
 {
-	int ret, fd;
+	int ret, fd, saved_errno;
+	struct nscookie nsc;
 
 	if (verbose > 0)
 		fprintf(stderr, "write ELF image %s\n", filename);
 
+	nsinfo__mountns_enter(jd->nsi, &nsc);
 	fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644);
+	saved_errno = errno;
+	nsinfo__mountns_exit(&nsc);
 	if (fd == -1) {
-		pr_warning("cannot create jit ELF %s: %s\n", filename, strerror(errno));
+		pr_warning("cannot create jit ELF %s: %s\n", filename, strerror(saved_errno));
 		return -1;
 	}
 
@@ -99,8 +106,11 @@ jit_emit_elf(char *filename,
 
         close(fd);
 
-        if (ret)
-                unlink(filename);
+	if (ret) {
+		nsinfo__mountns_enter(jd->nsi, &nsc);
+		unlink(filename);
+		nsinfo__mountns_exit(&nsc);
+	}
 
 	return ret;
 }
@@ -134,12 +144,15 @@ static int
 jit_open(struct jit_buf_desc *jd, const char *name)
 {
 	struct jitheader header;
+	struct nscookie nsc;
 	struct jr_prefix *prefix;
 	ssize_t bs, bsz = 0;
 	void *n, *buf = NULL;
 	int ret, retval = -1;
 
+	nsinfo__mountns_enter(jd->nsi, &nsc);
 	jd->in = fopen(name, "r");
+	nsinfo__mountns_exit(&nsc);
 	if (!jd->in)
 		return -1;
 
@@ -367,6 +380,20 @@ jit_inject_event(struct jit_buf_desc *jd, union perf_event *event)
 	return 0;
 }
 
+static pid_t jr_entry_pid(struct jit_buf_desc *jd, union jr_entry *jr)
+{
+	if (jd->nsi && jd->nsi->in_pidns)
+		return jd->nsi->tgid;
+	return jr->load.pid;
+}
+
+static pid_t jr_entry_tid(struct jit_buf_desc *jd, union jr_entry *jr)
+{
+	if (jd->nsi && jd->nsi->in_pidns)
+		return jd->nsi->pid;
+	return jr->load.tid;
+}
+
 static uint64_t convert_timestamp(struct jit_buf_desc *jd, uint64_t timestamp)
 {
 	struct perf_tsc_conversion tc;
@@ -402,14 +429,15 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
 	const char *sym;
 	uint64_t count;
 	int ret, csize, usize;
-	pid_t pid, tid;
+	pid_t nspid, pid, tid;
 	struct {
 		u32 pid, tid;
 		u64 time;
 	} *id;
 
-	pid   = jr->load.pid;
-	tid   = jr->load.tid;
+	nspid = jr->load.pid;
+	pid   = jr_entry_pid(jd, jr);
+	tid   = jr_entry_tid(jd, jr);
 	csize = jr->load.code_size;
 	usize = jd->unwinding_mapped_size;
 	addr  = jr->load.code_addr;
@@ -425,14 +453,14 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
 	filename = event->mmap2.filename;
 	size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so",
 			jd->dir,
-			pid,
+			nspid,
 			count);
 
 	size++; /* for \0 */
 
 	size = PERF_ALIGN(size, sizeof(u64));
 	uaddr = (uintptr_t)code;
-	ret = jit_emit_elf(filename, sym, addr, (const void *)uaddr, csize, jd->debug_data, jd->nr_debug_entries,
+	ret = jit_emit_elf(jd, filename, sym, addr, (const void *)uaddr, csize, jd->debug_data, jd->nr_debug_entries,
 			   jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size);
 
 	if (jd->debug_data && jd->nr_debug_entries) {
@@ -451,7 +479,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
 		free(event);
 		return -1;
 	}
-	if (stat(filename, &st))
+	if (nsinfo__stat(filename, &st, jd->nsi))
 		memset(&st, 0, sizeof(st));
 
 	event->mmap2.header.type = PERF_RECORD_MMAP2;
@@ -515,14 +543,15 @@ static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr)
 	int usize;
 	u16 idr_size;
 	int ret;
-	pid_t pid, tid;
+	pid_t nspid, pid, tid;
 	struct {
 		u32 pid, tid;
 		u64 time;
 	} *id;
 
-	pid = jr->move.pid;
-	tid =  jr->move.tid;
+	nspid = jr->load.pid;
+	pid   = jr_entry_pid(jd, jr);
+	tid   = jr_entry_tid(jd, jr);
 	usize = jd->unwinding_mapped_size;
 	idr_size = jd->machine->id_hdr_size;
 
@@ -536,12 +565,12 @@ static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr)
 	filename = event->mmap2.filename;
 	size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so",
 	         jd->dir,
-	         pid,
+		 nspid,
 		 jr->move.code_index);
 
 	size++; /* for \0 */
 
-	if (stat(filename, &st))
+	if (nsinfo__stat(filename, &st, jd->nsi))
 		memset(&st, 0, sizeof(st));
 
 	size = PERF_ALIGN(size, sizeof(u64));
@@ -700,7 +729,7 @@ jit_inject(struct jit_buf_desc *jd, char *path)
  * as captured in the RECORD_MMAP record
  */
 static int
-jit_detect(char *mmap_name, pid_t pid)
+jit_detect(char *mmap_name, pid_t pid, struct nsinfo *nsi)
  {
 	char *p;
 	char *end = NULL;
@@ -740,7 +769,7 @@ jit_detect(char *mmap_name, pid_t pid)
 	 * pid does not match mmap pid
 	 * pid==0 in system-wide mode (synthesized)
 	 */
-	if (pid && pid2 != pid)
+	if (pid && pid2 != nsi->nstgid)
 		return -1;
 	/*
 	 * validate suffix
@@ -782,16 +811,30 @@ jit_process(struct perf_session *session,
 	    struct machine *machine,
 	    char *filename,
 	    pid_t pid,
+	    pid_t tid,
 	    u64 *nbytes)
 {
+	struct thread *thread;
+	struct nsinfo *nsi;
 	struct evsel *first;
 	struct jit_buf_desc jd;
 	int ret;
 
+	thread = machine__findnew_thread(machine, pid, tid);
+	if (thread == NULL) {
+		pr_err("problem processing JIT mmap event, skipping it.\n");
+		return 0;
+	}
+
+	nsi = nsinfo__get(thread->nsinfo);
+	thread__put(thread);
+
 	/*
 	 * first, detect marker mmap (i.e., the jitdump mmap)
 	 */
-	if (jit_detect(filename, pid)) {
+	if (jit_detect(filename, pid, nsi)) {
+		nsinfo__put(nsi);
+
 		// Strip //anon* mmaps if we processed a jitdump for this pid
 		if (jit_has_pid(machine, pid) && (strncmp(filename, "//anon", 6) == 0))
 			return 1;
@@ -804,6 +847,7 @@ jit_process(struct perf_session *session,
 	jd.session = session;
 	jd.output  = output;
 	jd.machine = machine;
+	jd.nsi = nsi;
 
 	/*
 	 * track sample_type to compute id_all layout
@@ -821,5 +865,7 @@ jit_process(struct perf_session *session,
 		ret = 1;
 	}
 
+	nsinfo__put(jd.nsi);
+
 	return ret;
 }