summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/event.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 18:30:52 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 18:30:52 +0200
commit4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9 (patch)
tree1f69733e5daab4915a76a41de0e4d1dc61e12cfb /tools/perf/util/event.c
parentMerge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kerne... (diff)
parentMerge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acm... (diff)
downloadlinux-4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9.tar.xz
linux-4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9.zip
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (162 commits) tracing/kprobes: unregister_trace_probe needs to be called under mutex perf: expose event__process function perf events: Fix mmap offset determination perf, powerpc: fsl_emb: Restore setting perf_sample_data.period perf, powerpc: Convert the FSL driver to use local64_t perf tools: Don't keep unreferenced maps when unmaps are detected perf session: Invalidate last_match when removing threads from rb_tree perf session: Free the ref_reloc_sym memory at the right place x86,mmiotrace: Add support for tracing STOS instruction perf, sched migration: Librarize task states and event headers helpers perf, sched migration: Librarize the GUI class perf, sched migration: Make the GUI class client agnostic perf, sched migration: Make it vertically scrollable perf, sched migration: Parameterize cpu height and spacing perf, sched migration: Fix key bindings perf, sched migration: Ignore unhandled task states perf, sched migration: Handle ignored migrate out events perf: New migration tool overview tracing: Drop cpparg() macro perf: Use tracepoint_synchronize_unregister() to flush any pending tracepoint call ... Fix up trivial conflicts in Makefile and drivers/cpufreq/cpufreq.c
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r--tools/perf/util/event.c107
1 files changed, 74 insertions, 33 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 2fbf6a463c81..dab9e754a281 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 */
@@ -340,30 +334,29 @@ int event__synthesize_kernel_mmap(event__handler_t process,
return process(&ev, session);
}
-static void thread__comm_adjust(struct thread *self)
+static void thread__comm_adjust(struct thread *self, struct hists *hists)
{
char *comm = self->comm;
if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
(!symbol_conf.comm_list ||
strlist__has_entry(symbol_conf.comm_list, comm))) {
- unsigned int slen = strlen(comm);
+ u16 slen = strlen(comm);
- if (slen > comms__col_width) {
- comms__col_width = slen;
- threads__col_width = slen + 6;
- }
+ if (hists__new_col_len(hists, HISTC_COMM, slen))
+ hists__set_col_len(hists, HISTC_THREAD, slen + 6);
}
}
-static int thread__set_comm_adjust(struct thread *self, const char *comm)
+static int thread__set_comm_adjust(struct thread *self, const char *comm,
+ struct hists *hists)
{
int ret = thread__set_comm(self, comm);
if (ret)
return ret;
- thread__comm_adjust(self);
+ thread__comm_adjust(self, hists);
return 0;
}
@@ -374,7 +367,8 @@ int event__process_comm(event_t *self, struct perf_session *session)
dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid);
- if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) {
+ if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm,
+ &session->hists)) {
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
return -1;
}
@@ -456,6 +450,7 @@ static int event__process_kernel_mmap(event_t *self,
goto out_problem;
map->dso->short_name = name;
+ map->dso->sname_alloc = 1;
map->end = map->start + self->mmap.len;
} else if (is_kernel_mmap) {
const char *symbol_name = (self->mmap.filename +
@@ -514,12 +509,13 @@ int event__process_mmap(event_t *self, struct perf_session *session)
if (machine == NULL)
goto out_problem;
thread = perf_session__findnew(session, self->mmap.pid);
+ if (thread == NULL)
+ goto out_problem;
map = map__new(&machine->user_dsos, self->mmap.start,
self->mmap.len, self->mmap.pgoff,
self->mmap.pid, self->mmap.filename,
- MAP__FUNCTION, session->cwd, session->cwdlen);
-
- if (thread == NULL || map == NULL)
+ MAP__FUNCTION);
+ if (map == NULL)
goto out_problem;
thread__insert_map(thread, map);
@@ -552,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,
@@ -641,27 +657,49 @@ void thread__find_addr_location(struct thread *self,
al->sym = NULL;
}
-static void dso__calc_col_width(struct dso *self)
+static void dso__calc_col_width(struct dso *self, struct hists *hists)
{
if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
(!symbol_conf.dso_list ||
strlist__has_entry(symbol_conf.dso_list, self->name))) {
- u16 slen = self->short_name_len;
- if (verbose)
- slen = self->long_name_len;
- if (dsos__col_width < slen)
- dsos__col_width = slen;
+ u16 slen = dso__name_len(self);
+ hists__new_col_len(hists, HISTC_DSO, slen);
}
self->slen_calculated = 1;
}
int event__preprocess_sample(const event_t *self, struct perf_session *session,
- struct addr_location *al, symbol_filter_t filter)
+ struct addr_location *al, struct sample_data *data,
+ symbol_filter_t filter)
{
u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
- struct thread *thread = perf_session__findnew(session, self->ip.pid);
+ struct thread *thread;
+ event__parse_sample(self, session->sample_type, data);
+
+ dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n",
+ self->header.misc, data->pid, data->tid, data->ip,
+ data->period, data->cpu);
+
+ if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
+ unsigned int i;
+
+ dump_printf("... chain: nr:%Lu\n", data->callchain->nr);
+
+ if (!ip_callchain__valid(data->callchain, self)) {
+ pr_debug("call-chain problem with event, "
+ "skipping it.\n");
+ goto out_filtered;
+ }
+
+ if (dump_trace) {
+ for (i = 0; i < data->callchain->nr; i++)
+ dump_printf("..... %2d: %016Lx\n",
+ i, data->callchain->ips[i]);
+ }
+ }
+ thread = perf_session__findnew(session, self->ip.pid);
if (thread == NULL)
return -1;
@@ -687,6 +725,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
al->map ? al->map->dso->long_name :
al->level == 'H' ? "[hypervisor]" : "<not found>");
al->sym = NULL;
+ al->cpu = data->cpu;
if (al->map) {
if (symbol_conf.dso_list &&
@@ -703,16 +742,17 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
* sampled.
*/
if (!sort_dso.elide && !al->map->dso->slen_calculated)
- dso__calc_col_width(al->map->dso);
+ dso__calc_col_width(al->map->dso, &session->hists);
al->sym = map__find_symbol(al->map, al->addr, filter);
} else {
const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
- if (dsos__col_width < unresolved_col_width &&
+ if (hists__col_len(&session->hists, HISTC_DSO) < unresolved_col_width &&
!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
!symbol_conf.dso_list)
- dsos__col_width = unresolved_col_width;
+ hists__set_col_len(&session->hists, HISTC_DSO,
+ unresolved_col_width);
}
if (symbol_conf.sym_list && al->sym &&
@@ -726,9 +766,9 @@ out_filtered:
return 0;
}
-int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
+int event__parse_sample(const event_t *event, u64 type, struct sample_data *data)
{
- u64 *array = event->sample.array;
+ const u64 *array = event->sample.array;
if (type & PERF_SAMPLE_IP) {
data->ip = event->ip.ip;
@@ -767,7 +807,8 @@ int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
u32 *p = (u32 *)array;
data->cpu = *p;
array++;
- }
+ } else
+ data->cpu = -1;
if (type & PERF_SAMPLE_PERIOD) {
data->period = *array;