diff options
| author | Mark Brown <broonie@kernel.org> | 2020-12-11 17:49:01 +0000 | 
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2020-12-11 17:49:01 +0000 | 
| commit | 3e98a021cc85e7d52acdd1eae8a988e975ec5bf9 (patch) | |
| tree | cecfac58b9550a602555a02a9d583ed0f3378b38 /tools/perf/util | |
| parent | 58f7553fa424fd0fd74e8b796d50c66014cebebe (diff) | |
| parent | 2fee9583198eb97b5351feda7bd825e0f778385c (diff) | |
Merge remote-tracking branch 'spi/for-5.11' into spi-next
Diffstat (limited to 'tools/perf/util')
| -rw-r--r-- | tools/perf/util/build-id.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/dwarf-aux.c | 28 | ||||
| -rw-r--r-- | tools/perf/util/hashmap.c | 3 | ||||
| -rw-r--r-- | tools/perf/util/hashmap.h | 27 | ||||
| -rw-r--r-- | tools/perf/util/include/linux/linkage.h | 7 | ||||
| -rw-r--r-- | tools/perf/util/machine.c | 11 | ||||
| -rw-r--r-- | tools/perf/util/probe-finder.c | 3 | ||||
| -rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 7 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 14 | ||||
| -rw-r--r-- | tools/perf/util/stat-display.c | 5 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 7 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 2 | ||||
| -rw-r--r-- | tools/perf/util/synthetic-events.c | 3 | 
13 files changed, 99 insertions, 20 deletions
| diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 8763772f1095..6b410c3d52dc 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -102,6 +102,8 @@ int build_id__sprintf(const struct build_id *build_id, char *bf)  	const u8 *raw = build_id->data;  	size_t i; +	bf[0] = 0x0; +  	for (i = 0; i < build_id->size; ++i) {  		sprintf(bid, "%02x", *raw);  		++raw; diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index aa898014ad12..7b2d471a6419 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -356,9 +356,25 @@ bool die_is_signed_type(Dwarf_Die *tp_die)  bool die_is_func_def(Dwarf_Die *dw_die)  {  	Dwarf_Attribute attr; +	Dwarf_Addr addr = 0; + +	if (dwarf_tag(dw_die) != DW_TAG_subprogram) +		return false; + +	if (dwarf_attr(dw_die, DW_AT_declaration, &attr)) +		return false; -	return (dwarf_tag(dw_die) == DW_TAG_subprogram && -		dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL); +	/* +	 * DW_AT_declaration can be lost from function declaration +	 * by gcc's bug #97060. +	 * So we need to check this subprogram DIE has DW_AT_inline +	 * or an entry address. +	 */ +	if (!dwarf_attr(dw_die, DW_AT_inline, &attr) && +	    die_entrypc(dw_die, &addr) < 0) +		return false; + +	return true;  }  /** @@ -373,6 +389,7 @@ bool die_is_func_def(Dwarf_Die *dw_die)  int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr)  {  	Dwarf_Addr base, end; +	Dwarf_Attribute attr;  	if (!addr)  		return -EINVAL; @@ -380,6 +397,13 @@ int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr)  	if (dwarf_entrypc(dw_die, addr) == 0)  		return 0; +	/* +	 *  Since the dwarf_ranges() will return 0 if there is no +	 * DW_AT_ranges attribute, we should check it first. +	 */ +	if (!dwarf_attr(dw_die, DW_AT_ranges, &attr)) +		return -ENOENT; +  	return dwarf_ranges(dw_die, 0, &base, addr, &end) < 0 ? -ENOENT : 0;  } diff --git a/tools/perf/util/hashmap.c b/tools/perf/util/hashmap.c index a405dad068f5..3c20b126d60d 100644 --- a/tools/perf/util/hashmap.c +++ b/tools/perf/util/hashmap.c @@ -15,6 +15,9 @@  /* make sure libbpf doesn't use kernel-only integer typedefs */  #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64 +/* prevent accidental re-addition of reallocarray() */ +#pragma GCC poison reallocarray +  /* start with 4 buckets */  #define HASHMAP_MIN_CAP_BITS 2 diff --git a/tools/perf/util/hashmap.h b/tools/perf/util/hashmap.h index e0af36b0e5d8..10a4c4cd13cf 100644 --- a/tools/perf/util/hashmap.h +++ b/tools/perf/util/hashmap.h @@ -15,6 +15,9 @@  static inline size_t hash_bits(size_t h, int bits)  {  	/* shuffle bits and return requested number of upper bits */ +	if (bits == 0) +		return 0; +  #if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)  	/* LP64 case */  	return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits); @@ -25,6 +28,18 @@ static inline size_t hash_bits(size_t h, int bits)  #endif  } +/* generic C-string hashing function */ +static inline size_t str_hash(const char *s) +{ +	size_t h = 0; + +	while (*s) { +		h = h * 31 + *s; +		s++; +	} +	return h; +} +  typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);  typedef bool (*hashmap_equal_fn)(const void *key1, const void *key2, void *ctx); @@ -162,17 +177,17 @@ bool hashmap__find(const struct hashmap *map, const void *key, void **value);   * @key: key to iterate entries for   */  #define hashmap__for_each_key_entry(map, cur, _key)			    \ -	for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\ -					     map->cap_bits);		    \ -		     map->buckets ? map->buckets[bkt] : NULL; });	    \ +	for (cur = map->buckets						    \ +		     ? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \ +		     : NULL;						    \  	     cur;							    \  	     cur = cur->next)						    \  		if (map->equal_fn(cur->key, (_key), map->ctx))  #define hashmap__for_each_key_entry_safe(map, cur, tmp, _key)		    \ -	for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\ -					     map->cap_bits);		    \ -		     cur = map->buckets ? map->buckets[bkt] : NULL; });	    \ +	for (cur = map->buckets						    \ +		     ? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \ +		     : NULL;						    \  	     cur && ({ tmp = cur->next; true; });			    \  	     cur = tmp)							    \  		if (map->equal_fn(cur->key, (_key), map->ctx)) diff --git a/tools/perf/util/include/linux/linkage.h b/tools/perf/util/include/linux/linkage.h index b8a5159361b4..5acf053fca7d 100644 --- a/tools/perf/util/include/linux/linkage.h +++ b/tools/perf/util/include/linux/linkage.h @@ -25,6 +25,7 @@  /* SYM_L_* -- linkage of symbols */  #define SYM_L_GLOBAL(name)			.globl name +#define SYM_L_WEAK(name)			.weak name  #define SYM_L_LOCAL(name)			/* nothing */  #define ALIGN __ALIGN @@ -84,6 +85,12 @@  	SYM_END(name, SYM_T_FUNC)  #endif +/* SYM_FUNC_START_WEAK -- use for weak functions */ +#ifndef SYM_FUNC_START_WEAK +#define SYM_FUNC_START_WEAK(name)			\ +	SYM_START(name, SYM_L_WEAK, SYM_A_ALIGN) +#endif +  /*   * SYM_FUNC_END -- the end of SYM_FUNC_START_LOCAL, SYM_FUNC_START,   * SYM_FUNC_START_WEAK, ... diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7d4194ffc5b0..15385ea00190 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -786,11 +786,20 @@ static int machine__process_ksymbol_unregister(struct machine *machine,  					       union perf_event *event,  					       struct perf_sample *sample __maybe_unused)  { +	struct symbol *sym;  	struct map *map;  	map = maps__find(&machine->kmaps, event->ksymbol.addr); -	if (map) +	if (!map) +		return 0; + +	if (map != machine->vmlinux_map)  		maps__remove(&machine->kmaps, map); +	else { +		sym = dso__find_symbol(map->dso, map->map_ip(map, map->start)); +		if (sym) +			dso__delete_symbol(map->dso, sym); +	}  	return 0;  } diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 2c4061035f77..76dd349aa48d 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1885,8 +1885,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)  	if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))  		return DWARF_CB_OK; -	if (die_is_func_def(sp_die) && -	    die_match_name(sp_die, lr->function)) { +	if (die_match_name(sp_die, lr->function) && die_is_func_def(sp_die)) {  		lf->fname = dwarf_decl_file(sp_die);  		dwarf_decl_line(sp_die, &lr->offset);  		pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 7cbd024e3e63..c83c2c6564e0 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1592,7 +1592,6 @@ static void _free_command_line(wchar_t **command_line, int num)  static int python_start_script(const char *script, int argc, const char **argv)  {  	struct tables *tables = &tables_global; -	PyMODINIT_FUNC (*initfunc)(void);  #if PY_MAJOR_VERSION < 3  	const char **command_line;  #else @@ -1607,20 +1606,18 @@ static int python_start_script(const char *script, int argc, const char **argv)  	FILE *fp;  #if PY_MAJOR_VERSION < 3 -	initfunc = initperf_trace_context;  	command_line = malloc((argc + 1) * sizeof(const char *));  	command_line[0] = script;  	for (i = 1; i < argc + 1; i++)  		command_line[i] = argv[i - 1]; +	PyImport_AppendInittab(name, initperf_trace_context);  #else -	initfunc = PyInit_perf_trace_context;  	command_line = malloc((argc + 1) * sizeof(wchar_t *));  	command_line[0] = Py_DecodeLocale(script, NULL);  	for (i = 1; i < argc + 1; i++)  		command_line[i] = Py_DecodeLocale(argv[i - 1], NULL); +	PyImport_AppendInittab(name, PyInit_perf_trace_context);  #endif - -	PyImport_AppendInittab(name, initfunc);  	Py_Initialize();  #if PY_MAJOR_VERSION < 3 diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7a5f03764702..098080287c68 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -595,6 +595,7 @@ static void perf_event__mmap2_swap(union perf_event *event,  	event->mmap2.maj   = bswap_32(event->mmap2.maj);  	event->mmap2.min   = bswap_32(event->mmap2.min);  	event->mmap2.ino   = bswap_64(event->mmap2.ino); +	event->mmap2.ino_generation = bswap_64(event->mmap2.ino_generation);  	if (sample_id_all) {  		void *data = &event->mmap2.filename; @@ -710,6 +711,18 @@ static void perf_event__namespaces_swap(union perf_event *event,  		swap_sample_id_all(event, &event->namespaces.link_info[i]);  } +static void perf_event__cgroup_swap(union perf_event *event, bool sample_id_all) +{ +	event->cgroup.id = bswap_64(event->cgroup.id); + +	if (sample_id_all) { +		void *data = &event->cgroup.path; + +		data += PERF_ALIGN(strlen(data) + 1, sizeof(u64)); +		swap_sample_id_all(event, data); +	} +} +  static u8 revbyte(u8 b)  {  	int rev = (b >> 4) | ((b & 0xf) << 4); @@ -952,6 +965,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {  	[PERF_RECORD_SWITCH]		  = perf_event__switch_swap,  	[PERF_RECORD_SWITCH_CPU_WIDE]	  = perf_event__switch_swap,  	[PERF_RECORD_NAMESPACES]	  = perf_event__namespaces_swap, +	[PERF_RECORD_CGROUP]		  = perf_event__cgroup_swap,  	[PERF_RECORD_TEXT_POKE]		  = perf_event__text_poke_swap,  	[PERF_RECORD_HEADER_ATTR]	  = perf_event__hdr_attr_swap,  	[PERF_RECORD_HEADER_EVENT_TYPE]	  = perf_event__event_type_swap, diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 4b57c0c07632..a963b5b8eb72 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -324,13 +324,10 @@ static int first_shadow_cpu(struct perf_stat_config *config,  	struct evlist *evlist = evsel->evlist;  	int i; -	if (!config->aggr_get_id) -		return 0; -  	if (config->aggr_mode == AGGR_NONE)  		return id; -	if (config->aggr_mode == AGGR_GLOBAL) +	if (!config->aggr_get_id)  		return 0;  	for (i = 0; i < evsel__nr_cpus(evsel); i++) { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 6138866665df..0d14abdf3d72 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -515,6 +515,13 @@ void dso__insert_symbol(struct dso *dso, struct symbol *sym)  	}  } +void dso__delete_symbol(struct dso *dso, struct symbol *sym) +{ +	rb_erase_cached(&sym->rb_node, &dso->symbols); +	symbol__delete(sym); +	dso__reset_find_symbol_cache(dso); +} +  struct symbol *dso__find_symbol(struct dso *dso, u64 addr)  {  	if (dso->last_find_result.addr != addr || dso->last_find_result.symbol == NULL) { diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index f4801c488def..954d6a049ee2 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -131,6 +131,8 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map);  void dso__insert_symbol(struct dso *dso,  			struct symbol *sym); +void dso__delete_symbol(struct dso *dso, +			struct symbol *sym);  struct symbol *dso__find_symbol(struct dso *dso, u64 addr);  struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name); diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 8a23391558cf..d9c624377da7 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -563,6 +563,9 @@ int perf_event__synthesize_cgroups(struct perf_tool *tool,  	char cgrp_root[PATH_MAX];  	size_t mount_len;  /* length of mount point in the path */ +	if (!tool || !tool->cgroup_events) +		return 0; +  	if (cgroupfs_find_mountpoint(cgrp_root, PATH_MAX, "perf_event") < 0) {  		pr_debug("cannot find cgroup mount point\n");  		return -1; | 
