Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169826
b: refs/heads/master
c: 1ed091c
h: refs/heads/master
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Nov 27, 2009
1 parent 40a2fc5 commit 2789b07
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 223 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 62daacb51a2bf8480e6f6b3696b03f102fc15eb0
refs/heads/master: 1ed091c45ae33b2179d387573c3fe3f3b4adf60a
55 changes: 7 additions & 48 deletions trunk/tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,71 +124,30 @@ static void hist_hit(struct hist_entry *he, u64 ip)
h->ip[offset]);
}

static int hist_entry__add(struct thread *thread, struct map *map,
struct symbol *sym, u64 ip, u64 count, char level)
static int hist_entry__add(struct addr_location *al, u64 count)
{
bool hit;
struct hist_entry *he = __hist_entry__add(thread, map, sym, NULL, ip,
count, level, &hit);
struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit);
if (he == NULL)
return -ENOMEM;
hist_hit(he, ip);
hist_hit(he, al->addr);
return 0;
}

static int process_sample_event(event_t *event)
{
char level;
u64 ip = event->ip.ip;
struct map *map = NULL;
struct symbol *sym = NULL;
struct thread *thread = threads__findnew(event->ip.pid);
struct addr_location al;

dump_printf("(IP, %d): %d: %p\n", event->header.misc,
event->ip.pid, (void *)(long)ip);
event->ip.pid, (void *)(long)event->ip.ip);

if (thread == NULL) {
if (event__preprocess_sample(event, &al, symbol_filter) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}

dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);

if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
level = 'k';
sym = kernel_maps__find_function(ip, &map, symbol_filter);
dump_printf(" ...... dso: %s\n",
map ? map->dso->long_name : "<not found>");
} else if (event->header.misc & PERF_RECORD_MISC_USER) {
level = '.';
map = thread__find_map(thread, MAP__FUNCTION, ip);
if (map != NULL) {
ip = map->map_ip(map, ip);
sym = map__find_symbol(map, ip, symbol_filter);
} else {
/*
* If this is outside of all known maps,
* and is a negative address, try to look it
* up in the kernel dso, as it might be a
* vsyscall or vdso (which executes in user-mode).
*
* XXX This is nasty, we should have a symbol list in
* the "[vdso]" dso, but for now lets use the old
* trick of looking in the whole kernel symbol list.
*/
if ((long long)ip < 0)
sym = kernel_maps__find_function(ip, &map,
symbol_filter);
}
dump_printf(" ...... dso: %s\n",
map ? map->dso->long_name : "<not found>");
} else {
level = 'H';
dump_printf(" ...... dso: [hypervisor]\n");
}

if (hist_entry__add(thread, map, sym, ip, 1, level)) {
if (hist_entry__add(&al, 1)) {
fprintf(stderr, "problem incrementing symbol count, "
"skipping event\n");
return -1;
Expand Down
2 changes: 1 addition & 1 deletion trunk/tools/perf/builtin-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ static void __print_result(struct rb_root *root, int n_lines, int is_caller)
if (is_caller) {
addr = data->call_site;
if (!raw_ip)
sym = kernel_maps__find_function(addr, NULL, NULL);
sym = thread__find_function(kthread, addr, NULL);
} else
addr = data->ptr;

Expand Down
135 changes: 38 additions & 97 deletions trunk/tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,55 +408,6 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm)
return 0;
}


static struct symbol *
resolve_symbol(struct thread *thread, struct map **mapp, u64 *ipp)
{
struct map *map = mapp ? *mapp : NULL;
u64 ip = *ipp;

if (map)
goto got_map;

if (!thread)
return NULL;

map = thread__find_map(thread, MAP__FUNCTION, ip);
if (map != NULL) {
/*
* We have to do this here as we may have a dso
* with no symbol hit that has a name longer than
* the ones with symbols sampled.
*/
if (!sort_dso.elide && !map->dso->slen_calculated)
dso__calc_col_width(map->dso);

if (mapp)
*mapp = map;
got_map:
ip = map->map_ip(map, ip);
} else {
/*
* If this is outside of all known maps,
* and is a negative address, try to look it
* up in the kernel dso, as it might be a
* vsyscall or vdso (which executes in user-mode).
*
* XXX This is nasty, we should have a symbol list in
* the "[vdso]" dso, but for now lets use the old
* trick of looking in the whole kernel symbol list.
*/
if ((long long)ip < 0)
return kernel_maps__find_function(ip, mapp, NULL);
}
dump_printf(" ...... dso: %s\n",
map ? map->dso->long_name : "<not found>");
dump_printf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
*ipp = ip;

return map ? map__find_symbol(map, ip, NULL) : NULL;
}

static int call__match(struct symbol *sym)
{
if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
Expand All @@ -469,7 +420,7 @@ static struct symbol **resolve_callchain(struct thread *thread,
struct ip_callchain *chain,
struct symbol **parent)
{
u64 context = PERF_CONTEXT_MAX;
u8 cpumode = PERF_RECORD_MISC_USER;
struct symbol **syms = NULL;
unsigned int i;

Expand All @@ -483,30 +434,31 @@ static struct symbol **resolve_callchain(struct thread *thread,

for (i = 0; i < chain->nr; i++) {
u64 ip = chain->ips[i];
struct symbol *sym = NULL;
struct addr_location al;

if (ip >= PERF_CONTEXT_MAX) {
context = ip;
switch (ip) {
case PERF_CONTEXT_HV:
cpumode = PERF_RECORD_MISC_HYPERVISOR; break;
case PERF_CONTEXT_KERNEL:
cpumode = PERF_RECORD_MISC_KERNEL; break;
case PERF_CONTEXT_USER:
cpumode = PERF_RECORD_MISC_USER; break;
default:
break;
}
continue;
}

switch (context) {
case PERF_CONTEXT_HV:
break;
case PERF_CONTEXT_KERNEL:
sym = kernel_maps__find_function(ip, NULL, NULL);
break;
default:
sym = resolve_symbol(thread, NULL, &ip);
break;
}

if (sym) {
if (sort__has_parent && !*parent && call__match(sym))
*parent = sym;
thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
ip, &al, NULL);
if (al.sym != NULL) {
if (sort__has_parent && !*parent &&
call__match(al.sym))
*parent = al.sym;
if (!callchain)
break;
syms[i] = sym;
syms[i] = al.sym;
}
}

Expand All @@ -517,20 +469,17 @@ static struct symbol **resolve_callchain(struct thread *thread,
* collect histogram counts
*/

static int
hist_entry__add(struct thread *thread, struct map *map,
struct symbol *sym, u64 ip, struct ip_callchain *chain,
char level, u64 count)
static int hist_entry__add(struct addr_location *al,
struct ip_callchain *chain, u64 count)
{
struct symbol **syms = NULL, *parent = NULL;
bool hit;
struct hist_entry *he;

if ((sort__has_parent || callchain) && chain)
syms = resolve_callchain(thread, chain, &parent);
syms = resolve_callchain(al->thread, chain, &parent);

he = __hist_entry__add(thread, map, sym, parent,
ip, count, level, &hit);
he = __hist_entry__add(al, parent, count, &hit);
if (he == NULL)
return -ENOMEM;

Expand Down Expand Up @@ -656,14 +605,12 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)

static int process_sample_event(event_t *event)
{
char level;
struct symbol *sym = NULL;
u64 ip = event->ip.ip;
u64 period = 1;
struct map *map = NULL;
void *more_data = event->ip.__more_data;
struct ip_callchain *chain = NULL;
int cpumode;
struct addr_location al;
struct thread *thread = threads__findnew(event->ip.pid);

if (sample_type & PERF_SAMPLE_PERIOD) {
Expand Down Expand Up @@ -709,32 +656,26 @@ static int process_sample_event(event_t *event)

cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;

if (cpumode == PERF_RECORD_MISC_KERNEL) {
level = 'k';
sym = kernel_maps__find_function(ip, &map, NULL);
dump_printf(" ...... dso: %s\n",
map ? map->dso->long_name : "<not found>");
} else if (cpumode == PERF_RECORD_MISC_USER) {
level = '.';
sym = resolve_symbol(thread, &map, &ip);

} else {
level = 'H';
dump_printf(" ...... dso: [hypervisor]\n");
}
thread__find_addr_location(thread, cpumode,
MAP__FUNCTION, ip, &al, NULL);
/*
* We have to do this here as we may have a dso with no symbol hit that
* has a name longer than the ones with symbols sampled.
*/
if (al.map && !sort_dso.elide && !al.map->dso->slen_calculated)
dso__calc_col_width(al.map->dso);

if (dso_list &&
(!map || !map->dso ||
!(strlist__has_entry(dso_list, map->dso->short_name) ||
(map->dso->short_name != map->dso->long_name &&
strlist__has_entry(dso_list, map->dso->long_name)))))
(!al.map || !al.map->dso ||
!(strlist__has_entry(dso_list, al.map->dso->short_name) ||
(al.map->dso->short_name != al.map->dso->long_name &&
strlist__has_entry(dso_list, al.map->dso->long_name)))))
return 0;

if (sym_list && sym && !strlist__has_entry(sym_list, sym->name))
if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
return 0;

if (hist_entry__add(thread, map, sym, ip,
chain, level, period)) {
if (hist_entry__add(&al, chain, period)) {
pr_debug("problem incrementing symbol count, skipping event\n");
return -1;
}
Expand Down
44 changes: 9 additions & 35 deletions trunk/tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -929,55 +929,28 @@ static int symbol_filter(struct map *map, struct symbol *sym)
static void event__process_sample(const event_t *self, int counter)
{
u64 ip = self->ip.ip;
struct map *map;
struct sym_entry *syme;
struct symbol *sym;
struct addr_location al;
u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;

switch (origin) {
case PERF_RECORD_MISC_USER: {
struct thread *thread;

case PERF_RECORD_MISC_USER:
if (hide_user_symbols)
return;

thread = threads__findnew(self->ip.pid);
if (thread == NULL)
return;

map = thread__find_map(thread, MAP__FUNCTION, ip);
if (map != NULL) {
ip = map->map_ip(map, ip);
sym = map__find_symbol(map, ip, symbol_filter);
if (sym == NULL)
return;
userspace_samples++;
break;
}
}
/*
* If this is outside of all known maps,
* and is a negative address, try to look it
* up in the kernel dso, as it might be a
* vsyscall or vdso (which executes in user-mode).
*/
if ((long long)ip >= 0)
return;
/* Fall thru */
break;
case PERF_RECORD_MISC_KERNEL:
if (hide_kernel_symbols)
return;

sym = kernel_maps__find_function(ip, &map, symbol_filter);
if (sym == NULL)
return;
break;
default:
return;
}

syme = symbol__priv(sym);
if (event__preprocess_sample(self, &al, symbol_filter) < 0 ||
al.sym == NULL)
return;

syme = symbol__priv(al.sym);
if (!syme->skip) {
syme->count[counter]++;
syme->origin = origin;
Expand All @@ -986,8 +959,9 @@ static void event__process_sample(const event_t *self, int counter)
if (list_empty(&syme->node) || !syme->node.next)
__list_insert_active_sym(syme);
pthread_mutex_unlock(&active_symbols_lock);
if (origin == PERF_RECORD_MISC_USER)
++userspace_samples;
++samples;
return;
}
}

Expand Down
Loading

0 comments on commit 2789b07

Please sign in to comment.