Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c338aee8 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by Ingo Molnar
Browse files

perf symbols: Do lazy symtab loading for the kernel & modules too



Just like we do with the other DSOs. This also simplifies the
kernel_maps setup process, now all that the tools need to do is
to call kernel_maps__init and the maps for the modules and
kernel will be created, then, later, when
kernel_maps__find_symbol() is used, it will also call
maps__find_symbol that already checks if the symtab was loaded,
loading it if needed.

Now if one does 'perf top --hide_kernel_symbols' we won't pay
the price of loading the (many) symbols in /proc/kallsyms or
vmlinux.

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1258757489-5978-4-git-send-email-acme@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 78075caa
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)

	if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
		level = 'k';
		sym = kernel_maps__find_symbol(ip, &map);
		sym = kernel_maps__find_symbol(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) {
@@ -637,9 +637,9 @@ static int __cmd_annotate(void)
		exit(0);
	}

	if (load_kernel(symbol_filter, use_modules) < 0) {
		perror("failed to load kernel symbols");
		return EXIT_FAILURE;
	if (kernel_maps__init(use_modules) < 0) {
		pr_err("failed to create kernel maps for symbol resolution\b");
		return -1;
	}

remap:
+3 −3
Original line number Diff line number Diff line
@@ -449,7 +449,7 @@ resolve_symbol(struct thread *thread, struct map **mapp, u64 *ipp)
		 * trick of looking in the whole kernel symbol list.
		 */
		if ((long long)ip < 0)
			return kernel_maps__find_symbol(ip, mapp);
			return kernel_maps__find_symbol(ip, mapp, NULL);
	}
	dump_printf(" ...... dso: %s\n",
		    map ? map->dso->long_name : "<not found>");
@@ -496,7 +496,7 @@ static struct symbol **resolve_callchain(struct thread *thread, struct map *map,
		case PERF_CONTEXT_HV:
			break;
		case PERF_CONTEXT_KERNEL:
			sym = kernel_maps__find_symbol(ip, &map);
			sym = kernel_maps__find_symbol(ip, &map, NULL);
			break;
		default:
			sym = resolve_symbol(thread, &map, &ip);
@@ -716,7 +716,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)

	if (cpumode == PERF_RECORD_MISC_KERNEL) {
		level = 'k';
		sym = kernel_maps__find_symbol(ip, &map);
		sym = kernel_maps__find_symbol(ip, &map, NULL);
		dump_printf(" ...... dso: %s\n",
			    map ? map->dso->long_name : "<not found>");
	} else if (cpumode == PERF_RECORD_MISC_USER) {
+7 −28
Original line number Diff line number Diff line
@@ -830,6 +830,8 @@ static void handle_keypress(int c)
		case 'q':
		case 'Q':
			printf("exiting.\n");
			if (dump_symtab)
				dsos__fprintf(stderr);
			exit(0);
		case 's':
			prompt_symbol(&sym_filter_entry, "Enter details symbol");
@@ -946,30 +948,6 @@ static int symbol_filter(struct map *map, struct symbol *sym)
	return 0;
}

static int parse_symbols(void)
{
	struct dso *kernel = dsos__load_kernel();

	if (kernel == NULL)
		return -1;

	if (dsos__load_modules() < 0)
		pr_debug("Couldn't read the complete list of modules, "
			 "continuing...\n");

	if (dsos__load_modules_sym(symbol_filter) < 0)
		pr_warning("Failed to read module symbols, continuing...\n");

	if (dso__load_kernel_sym(kernel, symbol_filter, 1) <= 0)
		pr_debug("Couldn't read the complete list of kernel symbols, "
			 "continuing...\n");

	if (dump_symtab)
		dsos__fprintf(stderr);

	return 0;
}

static void event__process_sample(const event_t *self, int counter)
{
	u64 ip = self->ip.ip;
@@ -1012,7 +990,7 @@ static void event__process_sample(const event_t *self, int counter)
		if (hide_kernel_symbols)
			return;

		sym = kernel_maps__find_symbol(ip, &map);
		sym = kernel_maps__find_symbol(ip, &map, symbol_filter);
		if (sym == NULL)
			return;
		break;
@@ -1339,7 +1317,7 @@ static const struct option options[] = {

int cmd_top(int argc, const char **argv, const char *prefix __used)
{
	int counter;
	int counter, err;

	page_size = sysconf(_SC_PAGE_SIZE);

@@ -1363,10 +1341,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
	if (delay_secs < 1)
		delay_secs = 1;

	parse_symbols();
	err = kernel_maps__init(true);
	if (err < 0)
		return err;
	parse_source(sym_filter_entry);


	/*
	 * User specified count overrides default frequency.
	 */
+2 −2
Original line number Diff line number Diff line
@@ -171,8 +171,8 @@ int mmap_dispatch_perf_file(struct perf_header **pheader,
		goto out_delete;

	err = -ENOMEM;
	if (load_kernel(NULL, 1) < 0) {
		pr_err("failed to load kernel symbols\n");
	if (kernel_maps__init(true) < 0) {
		pr_err("failed to setup the kernel maps to resolve symbols\n");
		goto out_delete;
	}

+3 −0
Original line number Diff line number Diff line
@@ -115,10 +115,13 @@ typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
void map__init(struct map *self, u64 start, u64 end, u64 pgoff,
	       struct dso *dso);
struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen);
void map__delete(struct map *self);
struct map *map__clone(struct map *self);
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *self, FILE *fp);
struct symbol *map__find_symbol(struct map *self, u64 ip, symbol_filter_t filter);
void map__fixup_start(struct map *self);
void map__fixup_end(struct map *self);

int event__synthesize_thread(pid_t pid, int (*process)(event_t *event));
void event__synthesize_threads(int (*process)(event_t *event));
Loading