diff options
Diffstat (limited to 'tools/perf/util/machine.c')
| -rw-r--r-- | tools/perf/util/machine.c | 36 | 
1 files changed, 29 insertions, 7 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index dc7aafe45a2b..147ed85ea2bc 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -15,6 +15,7 @@  #include "strlist.h"  #include "thread.h"  #include "vdso.h" +#include "util.h"  #include <stdbool.h>  #include <sys/types.h>  #include <sys/stat.h> @@ -24,7 +25,7 @@  #include "asm/bug.h"  #include "bpf-event.h" -#include "sane_ctype.h" +#include <linux/ctype.h>  #include <symbol/kallsyms.h>  #include <linux/mman.h> @@ -209,6 +210,18 @@ void machine__exit(struct machine *machine)  	for (i = 0; i < THREADS__TABLE_SIZE; i++) {  		struct threads *threads = &machine->threads[i]; +		struct thread *thread, *n; +		/* +		 * Forget about the dead, at this point whatever threads were +		 * left in the dead lists better have a reference count taken +		 * by who is using them, and then, when they drop those references +		 * and it finally hits zero, thread__put() will check and see that +		 * its not in the dead threads list and will not try to remove it +		 * from there, just calling thread__delete() straight away. +		 */ +		list_for_each_entry_safe(thread, n, &threads->dead, node) +			list_del_init(&thread->node); +  		exit_rwsem(&threads->lock);  	}  } @@ -704,12 +717,12 @@ static int machine__process_ksymbol_register(struct machine *machine,  			return -ENOMEM;  		map->start = event->ksymbol_event.addr; -		map->pgoff = map->start;  		map->end = map->start + event->ksymbol_event.len;  		map_groups__insert(&machine->kmaps, map);  	} -	sym = symbol__new(event->ksymbol_event.addr, event->ksymbol_event.len, +	sym = symbol__new(map->map_ip(map, map->start), +			  event->ksymbol_event.len,  			  0, 0, event->ksymbol_event.name);  	if (!sym)  		return -ENOMEM; @@ -1241,9 +1254,9 @@ static char *get_kernel_version(const char *root_dir)  		return NULL;  	tmp = fgets(version, sizeof(version), file); -	if (!tmp) -		*version = '\0';  	fclose(file); +	if (!tmp) +		return NULL;  	name = strstr(version, prefix);  	if (!name) @@ -1758,9 +1771,11 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,  	if (threads->last_match == th)  		threads__set_last_match(threads, NULL); -	BUG_ON(refcount_read(&th->refcnt) == 0);  	if (lock)  		down_write(&threads->lock); + +	BUG_ON(refcount_read(&th->refcnt) == 0); +  	rb_erase_cached(&th->rb_node, &threads->entries);  	RB_CLEAR_NODE(&th->rb_node);  	--threads->nr; @@ -1770,9 +1785,16 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,  	 * will be called and we will remove it from the dead_threads list.  	 */  	list_add_tail(&th->node, &threads->dead); + +	/* +	 * We need to do the put here because if this is the last refcount, +	 * then we will be touching the threads->dead head when removing the +	 * thread. +	 */ +	thread__put(th); +  	if (lock)  		up_write(&threads->lock); -	thread__put(th);  }  void machine__remove_thread(struct machine *machine, struct thread *th)  | 
