diff options
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-inject.c | 4 | ||||
-rw-r--r-- | tools/perf/util/jit.h | 2 | ||||
-rw-r--r-- | tools/perf/util/jitdump.c | 84 | ||||
-rw-r--r-- | tools/perf/util/namespaces.c | 12 | ||||
-rw-r--r-- | tools/perf/util/namespaces.h | 2 |
5 files changed, 82 insertions, 22 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 43937f4b399a..6fe44d97fde5 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -313,7 +313,7 @@ static int perf_event__jit_repipe_mmap(struct perf_tool *tool, * if jit marker, then inject jit mmaps and generate ELF images */ ret = jit_process(inject->session, &inject->output, machine, - event->mmap.filename, event->mmap.pid, &n); + event->mmap.filename, event->mmap.pid, event->mmap.tid, &n); if (ret < 0) return ret; if (ret) { @@ -413,7 +413,7 @@ static int perf_event__jit_repipe_mmap2(struct perf_tool *tool, * if jit marker, then inject jit mmaps and generate ELF images */ ret = jit_process(inject->session, &inject->output, machine, - event->mmap2.filename, event->mmap2.pid, &n); + event->mmap2.filename, event->mmap2.pid, event->mmap2.tid, &n); if (ret < 0) return ret; if (ret) { diff --git a/tools/perf/util/jit.h b/tools/perf/util/jit.h index 6817ffc2a059..fb810e1b2de7 100644 --- a/tools/perf/util/jit.h +++ b/tools/perf/util/jit.h @@ -5,7 +5,7 @@ #include <data.h> int jit_process(struct perf_session *session, struct perf_data *output, - struct machine *machine, char *filename, pid_t pid, u64 *nbytes); + struct machine *machine, char *filename, pid_t pid, pid_t tid, u64 *nbytes); int jit_inject_record(const char *filename); 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; } diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index f4b3512d8dd2..608b20c72a5c 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -287,3 +287,15 @@ char *nsinfo__realpath(const char *path, struct nsinfo *nsi) return rpath; } + +int nsinfo__stat(const char *filename, struct stat *st, struct nsinfo *nsi) +{ + int ret; + struct nscookie nsc; + + nsinfo__mountns_enter(nsi, &nsc); + ret = stat(filename, st); + nsinfo__mountns_exit(&nsc); + + return ret; +} diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 1cc8637cf885..ad9775db7b9c 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -8,6 +8,7 @@ #define __PERF_NAMESPACES_H #include <sys/types.h> +#include <sys/stat.h> #include <linux/stddef.h> #include <linux/perf_event.h> #include <linux/refcount.h> @@ -56,6 +57,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc); void nsinfo__mountns_exit(struct nscookie *nc); char *nsinfo__realpath(const char *path, struct nsinfo *nsi); +int nsinfo__stat(const char *filename, struct stat *st, struct nsinfo *nsi); static inline void __nsinfo__zput(struct nsinfo **nsip) { |