From b5a6325464b700c4bdac8799c495970516eed41c Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Tue, 3 Aug 2010 12:48:35 +0100 Subject: [PATCH 1/3] perf events: Fix mmap offset determination Fix buggy-looking code which unnecessarily adjusts the file offset fields read from /proc/*/maps. This may have gone unnoticed since the offset is usually 0 (and the logic in util/symbol.c may work incorrectly for other offset values). Commiter note: This fixes a bug introduced in 4af8b35, there is no need to shift pgoff twice, the show_map_vma routine in fs/proc/task_mmu.c already converts it from the number of pages to the size in bytes, and that is what appears in /proc/PID/map. Cc: Nicolas Pitre Cc: Will Deacon LKML-Reference: <1280836116-6654-2-git-send-email-dave.martin@linaro.org> Signed-off-by: Dave Martin Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 6b0db5577929..db8a1d4b4d8c 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -151,7 +151,6 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, continue; pbf += n + 3; if (*pbf == 'x') { /* vm_exec */ - u64 vm_pgoff; char *execname = strchr(bf, '/'); /* Catch VDSO */ @@ -162,12 +161,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, continue; pbf += 3; - n = hex2u64(pbf, &vm_pgoff); - /* pgoff is in bytes, not pages */ - if (n >= 0) - ev.mmap.pgoff = vm_pgoff << getpagesize(); - else - ev.mmap.pgoff = 0; + n = hex2u64(pbf, &ev.mmap.pgoff); size = strlen(execname); execname[size - 1] = '\0'; /* Remove \n */ From b83f920e179101a54721e5ab1d6c3edfb9d4bcbb Mon Sep 17 00:00:00 2001 From: Srikar Dronamraju Date: Mon, 2 Aug 2010 18:08:51 +0530 Subject: [PATCH 2/3] perf: expose event__process function The event__process function is useful in processing /proc//maps. All of the functions that are called from event__process are defined in util/event.c. Though its defined in builtin-top.c, it could be reused for perf probe for uprobes. Hence moving it to util/event.c and exporting the function. LKML-Reference: <20100802123851.GD22812@linux.vnet.ibm.com> Signed-off-by: Srikar Dronamraju Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 20 -------------------- tools/perf/util/event.c | 20 ++++++++++++++++++++ tools/perf/util/event.h | 1 + 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1e8e92e317b9..b513e40974f4 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1082,26 +1082,6 @@ static void event__process_sample(const event_t *self, } } -static int event__process(event_t *event, struct perf_session *session) -{ - switch (event->header.type) { - case PERF_RECORD_COMM: - event__process_comm(event, session); - break; - case PERF_RECORD_MMAP: - event__process_mmap(event, session); - break; - case PERF_RECORD_FORK: - case PERF_RECORD_EXIT: - event__process_task(event, session); - break; - default: - break; - } - - return 0; -} - struct mmap_data { int counter; void *base; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index db8a1d4b4d8c..dab9e754a281 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -548,6 +548,26 @@ int event__process_task(event_t *self, struct perf_session *session) return 0; } +int event__process(event_t *event, struct perf_session *session) +{ + switch (event->header.type) { + case PERF_RECORD_COMM: + event__process_comm(event, session); + break; + case PERF_RECORD_MMAP: + event__process_mmap(event, session); + break; + case PERF_RECORD_FORK: + case PERF_RECORD_EXIT: + event__process_task(event, session); + break; + default: + break; + } + + return 0; +} + void thread__find_addr_map(struct thread *self, struct perf_session *session, u8 cpumode, enum map_type type, pid_t pid, u64 addr, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 887ee63bbb62..8e790dae7026 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -154,6 +154,7 @@ int event__process_comm(event_t *self, struct perf_session *session); int event__process_lost(event_t *self, struct perf_session *session); int event__process_mmap(event_t *self, struct perf_session *session); int event__process_task(event_t *self, struct perf_session *session); +int event__process(event_t *event, struct perf_session *session); struct addr_location; int event__preprocess_sample(const event_t *self, struct perf_session *session, From 9da79ab83ee33ddc1fdd0858fd3d70925a1bde99 Mon Sep 17 00:00:00 2001 From: Srikar Dronamraju Date: Wed, 30 Jun 2010 14:15:48 +0530 Subject: [PATCH 3/3] tracing/kprobes: unregister_trace_probe needs to be called under mutex Comment in unregister_trace_probe() says probe_lock will be held when it gets called. However there is a case where it might called without the probe_lock being held. Also since we are traversing the probe_list and deleting an element from the probe_list, probe_lock should be held. This was first pointed in uprobes traceevent review by Frederic Weisbecker here. (http://lkml.org/lkml/2010/5/12/106) Cc: Ingo Molnar Cc: Masami Hiramatsu Acked-by: Masami Hiramatsu Acked-by: Steven Rostedt LKML-Reference: <20100630084548.GA10325@linux.vnet.ibm.com> Signed-off-by: Srikar Dronamraju Signed-off-by: Arnaldo Carvalho de Melo --- kernel/trace/trace_kprobe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1b79d1c15726..8b27c9849b42 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -925,14 +925,17 @@ static int create_trace_probe(int argc, char **argv) pr_info("Delete command needs an event name.\n"); return -EINVAL; } + mutex_lock(&probe_lock); tp = find_probe_event(event, group); if (!tp) { + mutex_unlock(&probe_lock); pr_info("Event %s/%s doesn't exist.\n", group, event); return -ENOENT; } /* delete an event */ unregister_trace_probe(tp); free_trace_probe(tp); + mutex_unlock(&probe_lock); return 0; }