diff options
Diffstat (limited to 'tools/perf/util/machine.c')
| -rw-r--r-- | tools/perf/util/machine.c | 198 | 
1 files changed, 92 insertions, 106 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 70a9f8716a4b..c8c5410315e8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -42,6 +42,11 @@  static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock); +static struct dso *machine__kernel_dso(struct machine *machine) +{ +	return machine->vmlinux_map->dso; +} +  static void dsos__init(struct dsos *dsos)  {  	INIT_LIST_HEAD(&dsos->head); @@ -81,7 +86,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)  	int err = -ENOMEM;  	memset(machine, 0, sizeof(*machine)); -	map_groups__init(&machine->kmaps, machine); +	maps__init(&machine->kmaps, machine);  	RB_CLEAR_NODE(&machine->rb_node);  	dsos__init(&machine->dsos); @@ -212,7 +217,7 @@ void machine__exit(struct machine *machine)  		return;  	machine__destroy_kernel_maps(machine); -	map_groups__exit(&machine->kmaps); +	maps__exit(&machine->kmaps);  	dsos__exit(&machine->dsos);  	machine__exit_vdso(machine);  	zfree(&machine->root_dir); @@ -407,28 +412,28 @@ static void machine__update_thread_pid(struct machine *machine,  	if (!leader)  		goto out_err; -	if (!leader->mg) -		leader->mg = map_groups__new(machine); +	if (!leader->maps) +		leader->maps = maps__new(machine); -	if (!leader->mg) +	if (!leader->maps)  		goto out_err; -	if (th->mg == leader->mg) +	if (th->maps == leader->maps)  		return; -	if (th->mg) { +	if (th->maps) {  		/*  		 * Maps are created from MMAP events which provide the pid and  		 * tid.  Consequently there never should be any maps on a thread  		 * with an unknown pid.  Just print an error if there are.  		 */ -		if (!map_groups__empty(th->mg)) +		if (!maps__empty(th->maps))  			pr_err("Discarding thread maps for %d:%d\n",  			       th->pid_, th->tid); -		map_groups__put(th->mg); +		maps__put(th->maps);  	} -	th->mg = map_groups__get(leader->mg); +	th->maps = maps__get(leader->maps);  out_put:  	thread__put(leader);  	return; @@ -531,14 +536,13 @@ static struct thread *____machine__findnew_thread(struct machine *machine,  		rb_insert_color_cached(&th->rb_node, &threads->entries, leftmost);  		/* -		 * We have to initialize map_groups separately -		 * after rb tree is updated. +		 * We have to initialize maps separately after rb tree is updated.  		 *  		 * The reason is that we call machine__findnew_thread -		 * within thread__init_map_groups to find the thread +		 * within thread__init_maps to find the thread  		 * leader and that would screwed the rb tree.  		 */ -		if (thread__init_map_groups(th, machine)) { +		if (thread__init_maps(th, machine)) {  			rb_erase_cached(&th->rb_node, &threads->entries);  			RB_CLEAR_NODE(&th->rb_node);  			thread__put(th); @@ -719,9 +723,8 @@ static int machine__process_ksymbol_register(struct machine *machine,  					     struct perf_sample *sample __maybe_unused)  {  	struct symbol *sym; -	struct map *map; +	struct map *map = maps__find(&machine->kmaps, event->ksymbol.addr); -	map = map_groups__find(&machine->kmaps, event->ksymbol.addr);  	if (!map) {  		map = dso__new_map(event->ksymbol.name);  		if (!map) @@ -729,7 +732,7 @@ static int machine__process_ksymbol_register(struct machine *machine,  		map->start = event->ksymbol.addr;  		map->end = map->start + event->ksymbol.len; -		map_groups__insert(&machine->kmaps, map); +		maps__insert(&machine->kmaps, map);  	}  	sym = symbol__new(map->map_ip(map, map->start), @@ -747,9 +750,9 @@ static int machine__process_ksymbol_unregister(struct machine *machine,  {  	struct map *map; -	map = map_groups__find(&machine->kmaps, event->ksymbol.addr); +	map = maps__find(&machine->kmaps, event->ksymbol.addr);  	if (map) -		map_groups__remove(&machine->kmaps, map); +		maps__remove(&machine->kmaps, map);  	return 0;  } @@ -767,45 +770,16 @@ int machine__process_ksymbol(struct machine *machine __maybe_unused,  	return machine__process_ksymbol_register(machine, event, sample);  } -static void dso__adjust_kmod_long_name(struct dso *dso, const char *filename) -{ -	const char *dup_filename; - -	if (!filename || !dso || !dso->long_name) -		return; -	if (dso->long_name[0] != '[') -		return; -	if (!strchr(filename, '/')) -		return; - -	dup_filename = strdup(filename); -	if (!dup_filename) -		return; - -	dso__set_long_name(dso, dup_filename, true); -} - -struct map *machine__findnew_module_map(struct machine *machine, u64 start, -					const char *filename) +static struct map *machine__addnew_module_map(struct machine *machine, u64 start, +					      const char *filename)  {  	struct map *map = NULL; -	struct dso *dso = NULL;  	struct kmod_path m; +	struct dso *dso;  	if (kmod_path__parse_name(&m, filename))  		return NULL; -	map = map_groups__find_by_name(&machine->kmaps, m.name); -	if (map) { -		/* -		 * If the map's dso is an offline module, give dso__load() -		 * a chance to find the file path of that module by fixing -		 * long_name. -		 */ -		dso__adjust_kmod_long_name(map->dso, filename); -		goto out; -	} -  	dso = machine__findnew_module_dso(machine, &m, filename);  	if (dso == NULL)  		goto out; @@ -814,9 +788,9 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start,  	if (map == NULL)  		goto out; -	map_groups__insert(&machine->kmaps, map); +	maps__insert(&machine->kmaps, map); -	/* Put the map here because map_groups__insert alread got it */ +	/* Put the map here because maps__insert alread got it */  	map__put(map);  out:  	/* put the dso here, corresponding to  machine__findnew_module_dso */ @@ -861,7 +835,7 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)  {  	int i;  	size_t printed = 0; -	struct dso *kdso = machine__kernel_map(machine)->dso; +	struct dso *kdso = machine__kernel_dso(machine);  	if (kdso->has_build_id) {  		char filename[PATH_MAX]; @@ -1001,7 +975,7 @@ int machine__create_extra_kernel_map(struct machine *machine,  	kmap->kmaps = &machine->kmaps;  	strlcpy(kmap->name, xm->name, KMAP_NAME_LEN); -	map_groups__insert(&machine->kmaps, map); +	maps__insert(&machine->kmaps, map);  	pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n",  		  kmap->name, map->start, map->end); @@ -1046,8 +1020,7 @@ static u64 find_entry_trampoline(struct dso *dso)  int machine__map_x86_64_entry_trampolines(struct machine *machine,  					  struct dso *kernel)  { -	struct map_groups *kmaps = &machine->kmaps; -	struct maps *maps = &kmaps->maps; +	struct maps *kmaps = &machine->kmaps;  	int nr_cpus_avail, cpu;  	bool found = false;  	struct map *map; @@ -1057,14 +1030,14 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,  	 * In the vmlinux case, pgoff is a virtual address which must now be  	 * mapped to a vmlinux offset.  	 */ -	for (map = maps__first(maps); map; map = map__next(map)) { +	maps__for_each_entry(kmaps, map) {  		struct kmap *kmap = __map__kmap(map);  		struct map *dest_map;  		if (!kmap || !is_entry_trampoline(kmap->name))  			continue; -		dest_map = map_groups__find(kmaps, map->pgoff); +		dest_map = maps__find(kmaps, map->pgoff);  		if (dest_map != map)  			map->pgoff = dest_map->map_ip(dest_map, map->pgoff);  		found = true; @@ -1126,7 +1099,7 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)  		return -1;  	kmap->kmaps = &machine->kmaps; -	map_groups__insert(&machine->kmaps, map); +	maps__insert(&machine->kmaps, map);  	return 0;  } @@ -1140,7 +1113,7 @@ void machine__destroy_kernel_maps(struct machine *machine)  		return;  	kmap = map__kmap(map); -	map_groups__remove(&machine->kmaps, map); +	maps__remove(&machine->kmaps, map);  	if (kmap && kmap->ref_reloc_sym) {  		zfree((char **)&kmap->ref_reloc_sym->name);  		zfree(&kmap->ref_reloc_sym); @@ -1235,7 +1208,7 @@ int machine__load_kallsyms(struct machine *machine, const char *filename)  		 * kernel, with modules between them, fixup the end of all  		 * sections.  		 */ -		map_groups__fixup_end(&machine->kmaps); +		maps__fixup_end(&machine->kmaps);  	}  	return ret; @@ -1286,11 +1259,10 @@ static bool is_kmod_dso(struct dso *dso)  	       dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE;  } -static int map_groups__set_module_path(struct map_groups *mg, const char *path, -				       struct kmod_path *m) +static int maps__set_module_path(struct maps *maps, const char *path, struct kmod_path *m)  {  	char *long_name; -	struct map *map = map_groups__find_by_name(mg, m->name); +	struct map *map = maps__find_by_name(maps, m->name);  	if (map == NULL)  		return 0; @@ -1314,8 +1286,7 @@ static int map_groups__set_module_path(struct map_groups *mg, const char *path,  	return 0;  } -static int map_groups__set_modules_path_dir(struct map_groups *mg, -				const char *dir_name, int depth) +static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, int depth)  {  	struct dirent *dent;  	DIR *dir = opendir(dir_name); @@ -1347,8 +1318,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,  					continue;  			} -			ret = map_groups__set_modules_path_dir(mg, path, -							       depth + 1); +			ret = maps__set_modules_path_dir(maps, path, depth + 1);  			if (ret < 0)  				goto out;  		} else { @@ -1359,7 +1329,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,  				goto out;  			if (m.kmod) -				ret = map_groups__set_module_path(mg, path, &m); +				ret = maps__set_module_path(maps, path, &m);  			zfree(&m.name); @@ -1386,7 +1356,7 @@ static int machine__set_modules_path(struct machine *machine)  		 machine->root_dir, version);  	free(version); -	return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); +	return maps__set_modules_path_dir(&machine->kmaps, modules_path, 0);  }  int __weak arch__fix_module_text_start(u64 *start __maybe_unused,  				u64 *size __maybe_unused, @@ -1404,7 +1374,7 @@ static int machine__create_module(void *arg, const char *name, u64 start,  	if (arch__fix_module_text_start(&start, &size, name) < 0)  		return -1; -	map = machine__findnew_module_map(machine, start, name); +	map = machine__addnew_module_map(machine, start, name);  	if (map == NULL)  		return -1;  	map->end = start + size; @@ -1459,11 +1429,11 @@ static void machine__update_kernel_mmap(struct machine *machine,  	struct map *map = machine__kernel_map(machine);  	map__get(map); -	map_groups__remove(&machine->kmaps, map); +	maps__remove(&machine->kmaps, map);  	machine__set_kernel_mmap(machine, start, end); -	map_groups__insert(&machine->kmaps, map); +	maps__insert(&machine->kmaps, map);  	map__put(map);  } @@ -1543,8 +1513,7 @@ static bool perf_event__is_extra_kernel_mmap(struct machine *machine,  static int machine__process_extra_kernel_map(struct machine *machine,  					     union perf_event *event)  { -	struct map *kernel_map = machine__kernel_map(machine); -	struct dso *kernel = kernel_map ? kernel_map->dso : NULL; +	struct dso *kernel = machine__kernel_dso(machine);  	struct extra_kernel_map xm = {  		.start = event->mmap.start,  		.end   = event->mmap.start + event->mmap.len, @@ -1580,8 +1549,8 @@ static int machine__process_kernel_mmap_event(struct machine *machine,  				strlen(machine->mmap_name) - 1) == 0;  	if (event->mmap.filename[0] == '/' ||  	    (!is_kernel_mmap && event->mmap.filename[0] == '[')) { -		map = machine__findnew_module_map(machine, event->mmap.start, -						  event->mmap.filename); +		map = machine__addnew_module_map(machine, event->mmap.start, +						 event->mmap.filename);  		if (map == NULL)  			goto out_problem; @@ -1676,6 +1645,12 @@ int machine__process_mmap2_event(struct machine *machine,  {  	struct thread *thread;  	struct map *map; +	struct dso_id dso_id = { +		.maj = event->mmap2.maj, +		.min = event->mmap2.min, +		.ino = event->mmap2.ino, +		.ino_generation = event->mmap2.ino_generation, +	};  	int ret = 0;  	if (dump_trace) @@ -1696,10 +1671,7 @@ int machine__process_mmap2_event(struct machine *machine,  	map = map__new(machine, event->mmap2.start,  			event->mmap2.len, event->mmap2.pgoff, -			event->mmap2.maj, -			event->mmap2.min, event->mmap2.ino, -			event->mmap2.ino_generation, -			event->mmap2.prot, +			&dso_id, event->mmap2.prot,  			event->mmap2.flags,  			event->mmap2.filename, thread); @@ -1752,9 +1724,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event  	map = map__new(machine, event->mmap.start,  			event->mmap.len, event->mmap.pgoff, -			0, 0, 0, 0, prot, 0, -			event->mmap.filename, -			thread); +			NULL, prot, 0, event->mmap.filename, thread);  	if (map == NULL)  		goto out_problem_map; @@ -1964,8 +1934,9 @@ static void ip__resolve_ams(struct thread *thread,  	ams->addr = ip;  	ams->al_addr = al.addr; -	ams->sym = al.sym; -	ams->map = al.map; +	ams->ms.maps = al.maps; +	ams->ms.sym = al.sym; +	ams->ms.map = al.map;  	ams->phys_addr = 0;  } @@ -1981,8 +1952,9 @@ static void ip__resolve_data(struct thread *thread,  	ams->addr = addr;  	ams->al_addr = al.addr; -	ams->sym = al.sym; -	ams->map = al.map; +	ams->ms.maps = al.maps; +	ams->ms.sym = al.sym; +	ams->ms.map = al.map;  	ams->phys_addr = phys_addr;  } @@ -2002,8 +1974,9 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,  	return mi;  } -static char *callchain_srcline(struct map *map, struct symbol *sym, u64 ip) +static char *callchain_srcline(struct map_symbol *ms, u64 ip)  { +	struct map *map = ms->map;  	char *srcline = NULL;  	if (!map || callchain_param.key == CCKEY_FUNCTION) @@ -2015,7 +1988,7 @@ static char *callchain_srcline(struct map *map, struct symbol *sym, u64 ip)  		bool show_addr = callchain_param.key == CCKEY_ADDRESS;  		srcline = get_srcline(map->dso, map__rip_2objdump(map, ip), -				      sym, show_sym, show_addr, ip); +				      ms->sym, show_sym, show_addr, ip);  		srcline__tree_insert(&map->dso->srclines, ip, srcline);  	} @@ -2038,6 +2011,7 @@ static int add_callchain_ip(struct thread *thread,  			    struct iterations *iter,  			    u64 branch_from)  { +	struct map_symbol ms;  	struct addr_location al;  	int nr_loop_iter = 0;  	u64 iter_cycles = 0; @@ -2095,8 +2069,11 @@ static int add_callchain_ip(struct thread *thread,  		iter_cycles = iter->cycles;  	} -	srcline = callchain_srcline(al.map, al.sym, al.addr); -	return callchain_cursor_append(cursor, ip, al.map, al.sym, +	ms.maps = al.maps; +	ms.map = al.map; +	ms.sym = al.sym; +	srcline = callchain_srcline(&ms, al.addr); +	return callchain_cursor_append(cursor, ip, &ms,  				       branch, flags, nr_loop_iter,  				       iter_cycles, branch_from, srcline);  } @@ -2403,7 +2380,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,  	}  check_calls: -	if (callchain_param.order != ORDER_CALLEE) { +	if (chain && callchain_param.order != ORDER_CALLEE) {  		err = find_prev_cpumode(chain, thread, cursor, parent, root_al,  					&cpumode, chain->nr - first_call);  		if (err) @@ -2444,9 +2421,10 @@ check_calls:  	return 0;  } -static int append_inlines(struct callchain_cursor *cursor, -			  struct map *map, struct symbol *sym, u64 ip) +static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms, u64 ip)  { +	struct symbol *sym = ms->sym; +	struct map *map = ms->map;  	struct inline_node *inline_node;  	struct inline_list *ilist;  	u64 addr; @@ -2467,8 +2445,12 @@ static int append_inlines(struct callchain_cursor *cursor,  	}  	list_for_each_entry(ilist, &inline_node->val, list) { -		ret = callchain_cursor_append(cursor, ip, map, -					      ilist->symbol, false, +		struct map_symbol ilist_ms = { +			.maps = ms->maps, +			.map = map, +			.sym = ilist->symbol, +		}; +		ret = callchain_cursor_append(cursor, ip, &ilist_ms, false,  					      NULL, 0, 0, 0, ilist->srcline);  		if (ret != 0) @@ -2484,22 +2466,21 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)  	const char *srcline = NULL;  	u64 addr = entry->ip; -	if (symbol_conf.hide_unresolved && entry->sym == NULL) +	if (symbol_conf.hide_unresolved && entry->ms.sym == NULL)  		return 0; -	if (append_inlines(cursor, entry->map, entry->sym, entry->ip) == 0) +	if (append_inlines(cursor, &entry->ms, entry->ip) == 0)  		return 0;  	/*  	 * Convert entry->ip from a virtual address to an offset in  	 * its corresponding binary.  	 */ -	if (entry->map) -		addr = map__map_ip(entry->map, entry->ip); +	if (entry->ms.map) +		addr = map__map_ip(entry->ms.map, entry->ip); -	srcline = callchain_srcline(entry->map, entry->sym, addr); -	return callchain_cursor_append(cursor, entry->ip, -				       entry->map, entry->sym, +	srcline = callchain_srcline(&entry->ms, addr); +	return callchain_cursor_append(cursor, entry->ip, &entry->ms,  				       false, NULL, 0, 0, 0, srcline);  } @@ -2725,9 +2706,14 @@ out:  	return addr_cpumode;  } +struct dso *machine__findnew_dso_id(struct machine *machine, const char *filename, struct dso_id *id) +{ +	return dsos__findnew_id(&machine->dsos, filename, id); +} +  struct dso *machine__findnew_dso(struct machine *machine, const char *filename)  { -	return dsos__findnew(&machine->dsos, filename); +	return machine__findnew_dso_id(machine, filename, NULL);  }  char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)  | 
