diff options
Diffstat (limited to 'tools/perf/builtin-sched.c')
| -rw-r--r-- | tools/perf/builtin-sched.c | 120 | 
1 files changed, 67 insertions, 53 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index cc4ba506e119..9ab300b6f131 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -193,8 +193,8 @@ struct perf_sched {   * weird events, such as a task being switched away that is not current.   */  	struct perf_cpu	 max_cpu; -	u32		 curr_pid[MAX_CPUS]; -	struct thread	 *curr_thread[MAX_CPUS]; +	u32		 *curr_pid; +	struct thread	 **curr_thread;  	char		 next_shortname1;  	char		 next_shortname2;  	unsigned int	 replay_repeat; @@ -224,7 +224,7 @@ struct perf_sched {  	u64		 run_avg;  	u64		 all_runtime;  	u64		 all_count; -	u64		 cpu_last_switched[MAX_CPUS]; +	u64		 *cpu_last_switched;  	struct rb_root_cached atom_root, sorted_atom_root, merged_atom_root;  	struct list_head sort_list, cmp_pid;  	bool force; @@ -916,12 +916,12 @@ static int replay_fork_event(struct perf_sched *sched,  	if (verbose > 0) {  		printf("fork event\n"); -		printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid); -		printf("...  child: %s/%d\n", thread__comm_str(child), child->tid); +		printf("... parent: %s/%d\n", thread__comm_str(parent), thread__tid(parent)); +		printf("...  child: %s/%d\n", thread__comm_str(child), thread__tid(child));  	} -	register_pid(sched, parent->tid, thread__comm_str(parent)); -	register_pid(sched, child->tid, thread__comm_str(child)); +	register_pid(sched, thread__tid(parent), thread__comm_str(parent)); +	register_pid(sched, thread__tid(child), thread__comm_str(child));  out_put:  	thread__put(child);  	thread__put(parent); @@ -1316,7 +1316,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,  	if (!atoms) {  		if (thread_atoms_insert(sched, migrant))  			goto out_put; -		register_pid(sched, migrant->tid, thread__comm_str(migrant)); +		register_pid(sched, thread__tid(migrant), thread__comm_str(migrant));  		atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);  		if (!atoms) {  			pr_err("migration-event: Internal tree error"); @@ -1359,10 +1359,13 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_  	sched->all_runtime += work_list->total_runtime;  	sched->all_count   += work_list->nb_atoms; -	if (work_list->num_merged > 1) -		ret = printf("  %s:(%d) ", thread__comm_str(work_list->thread), work_list->num_merged); -	else -		ret = printf("  %s:%d ", thread__comm_str(work_list->thread), work_list->thread->tid); +	if (work_list->num_merged > 1) { +		ret = printf("  %s:(%d) ", thread__comm_str(work_list->thread), +			     work_list->num_merged); +	} else { +		ret = printf("  %s:%d ", thread__comm_str(work_list->thread), +			     thread__tid(work_list->thread)); +	}  	for (i = 0; i < 24 - ret; i++)  		printf(" "); @@ -1380,13 +1383,17 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_  static int pid_cmp(struct work_atoms *l, struct work_atoms *r)  { -	if (l->thread == r->thread) +	pid_t l_tid, r_tid; + +	if (RC_CHK_ACCESS(l->thread) == RC_CHK_ACCESS(r->thread))  		return 0; -	if (l->thread->tid < r->thread->tid) +	l_tid = thread__tid(l->thread); +	r_tid = thread__tid(r->thread); +	if (l_tid < r_tid)  		return -1; -	if (l->thread->tid > r->thread->tid) +	if (l_tid > r_tid)  		return 1; -	return (int)(l->thread - r->thread); +	return (int)(RC_CHK_ACCESS(l->thread) - RC_CHK_ACCESS(r->thread));  }  static int avg_cmp(struct work_atoms *l, struct work_atoms *r) @@ -1679,14 +1686,14 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,  	timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp));  	color_fprintf(stdout, color, "  %12s secs ", stimestamp); -	if (new_shortname || tr->comm_changed || (verbose > 0 && sched_in->tid)) { +	if (new_shortname || tr->comm_changed || (verbose > 0 && thread__tid(sched_in))) {  		const char *pid_color = color;  		if (thread__has_color(sched_in))  			pid_color = COLOR_PIDS;  		color_fprintf(stdout, pid_color, "%s => %s:%d", -		       tr->shortname, thread__comm_str(sched_in), sched_in->tid); +			tr->shortname, thread__comm_str(sched_in), thread__tid(sched_in));  		tr->comm_changed = false;  	} @@ -1948,8 +1955,8 @@ static char *timehist_get_commstr(struct thread *thread)  {  	static char str[32];  	const char *comm = thread__comm_str(thread); -	pid_t tid = thread->tid; -	pid_t pid = thread->pid_; +	pid_t tid = thread__tid(thread); +	pid_t pid = thread__pid(thread);  	int n;  	if (pid == 0) @@ -2032,7 +2039,7 @@ static char task_state_char(struct thread *thread, int state)  	unsigned bit = state ? ffs(state) : 0;  	/* 'I' for idle */ -	if (thread->tid == 0) +	if (thread__tid(thread) == 0)  		return 'I';  	return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?'; @@ -2067,7 +2074,7 @@ static void timehist_print_sample(struct perf_sched *sched,  		for (i = 0; i < max_cpus; ++i) {  			/* flag idle times with 'i'; others are sched events */  			if (i == sample->cpu) -				c = (thread->tid == 0) ? 'i' : 's'; +				c = (thread__tid(thread) == 0) ? 'i' : 's';  			else  				c = ' ';  			printf("%c", c); @@ -2094,7 +2101,7 @@ static void timehist_print_sample(struct perf_sched *sched,  	if (sched->show_wakeups && !sched->show_next)  		printf("  %-*s", comm_width, ""); -	if (thread->tid == 0) +	if (thread__tid(thread) == 0)  		goto out;  	if (sched->show_callchain) @@ -2104,7 +2111,7 @@ static void timehist_print_sample(struct perf_sched *sched,  			    EVSEL__PRINT_SYM | EVSEL__PRINT_ONELINE |  			    EVSEL__PRINT_CALLCHAIN_ARROW |  			    EVSEL__PRINT_SKIP_IGNORED, -			    &callchain_cursor, symbol_conf.bt_stop_list,  stdout); +			    get_tls_callchain_cursor(), symbol_conf.bt_stop_list,  stdout);  out:  	printf("\n"); @@ -2189,7 +2196,7 @@ static void save_task_callchain(struct perf_sched *sched,  				struct evsel *evsel,  				struct machine *machine)  { -	struct callchain_cursor *cursor = &callchain_cursor; +	struct callchain_cursor *cursor;  	struct thread *thread;  	/* want main thread for process - has maps */ @@ -2202,6 +2209,8 @@ static void save_task_callchain(struct perf_sched *sched,  	if (!sched->show_callchain || sample->callchain == NULL)  		return; +	cursor = get_tls_callchain_cursor(); +  	if (thread__resolve_callchain(thread, cursor, evsel, sample,  				      NULL, NULL, sched->max_stack + 2) != 0) {  		if (verbose > 0) @@ -2331,10 +2340,16 @@ static void save_idle_callchain(struct perf_sched *sched,  				struct idle_thread_runtime *itr,  				struct perf_sample *sample)  { +	struct callchain_cursor *cursor; +  	if (!sched->show_callchain || sample->callchain == NULL)  		return; -	callchain_cursor__copy(&itr->cursor, &callchain_cursor); +	cursor = get_tls_callchain_cursor(); +	if (cursor == NULL) +		return; + +	callchain_cursor__copy(&itr->cursor, cursor);  }  static struct thread *timehist_get_thread(struct perf_sched *sched, @@ -2577,6 +2592,7 @@ static int timehist_sched_change_event(struct perf_tool *tool,  	int rc = 0;  	int state = evsel__intval(evsel, sample, "prev_state"); +	addr_location__init(&al);  	if (machine__resolve(machine, &al, sample) < 0) {  		pr_err("problem processing %d event. skipping it\n",  		       event->header.type); @@ -2626,7 +2642,7 @@ static int timehist_sched_change_event(struct perf_tool *tool,  			t = ptime->end;  	} -	if (!sched->idle_hist || thread->tid == 0) { +	if (!sched->idle_hist || thread__tid(thread) == 0) {  		if (!cpu_list || test_bit(sample->cpu, cpu_bitmap))  			timehist_update_runtime_stats(tr, t, tprev); @@ -2634,7 +2650,7 @@ static int timehist_sched_change_event(struct perf_tool *tool,  			struct idle_thread_runtime *itr = (void *)tr;  			struct thread_runtime *last_tr; -			BUG_ON(thread->tid != 0); +			BUG_ON(thread__tid(thread) != 0);  			if (itr->last_thread == NULL)  				goto out; @@ -2685,6 +2701,7 @@ out:  	evsel__save_time(evsel, sample->time, sample->cpu); +	addr_location__exit(&al);  	return rc;  } @@ -2719,7 +2736,7 @@ static void print_thread_runtime(struct thread *t,  	float stddev;  	printf("%*s   %5d  %9" PRIu64 " ", -	       comm_width, timehist_get_commstr(t), t->ppid, +	       comm_width, timehist_get_commstr(t), thread__ppid(t),  	       (u64) r->run_stats.n);  	print_sched_time(r->total_run_time, 8); @@ -2739,7 +2756,7 @@ static void print_thread_waittime(struct thread *t,  				  struct thread_runtime *r)  {  	printf("%*s   %5d  %9" PRIu64 " ", -	       comm_width, timehist_get_commstr(t), t->ppid, +	       comm_width, timehist_get_commstr(t), thread__ppid(t),  	       (u64) r->run_stats.n);  	print_sched_time(r->total_run_time, 8); @@ -2760,7 +2777,7 @@ struct total_run_stats {  	u64  total_run_time;  }; -static int __show_thread_runtime(struct thread *t, void *priv) +static int show_thread_runtime(struct thread *t, void *priv)  {  	struct total_run_stats *stats = priv;  	struct thread_runtime *r; @@ -2783,22 +2800,6 @@ static int __show_thread_runtime(struct thread *t, void *priv)  	return 0;  } -static int show_thread_runtime(struct thread *t, void *priv) -{ -	if (t->dead) -		return 0; - -	return __show_thread_runtime(t, priv); -} - -static int show_deadthread_runtime(struct thread *t, void *priv) -{ -	if (!t->dead) -		return 0; - -	return __show_thread_runtime(t, priv); -} -  static size_t callchain__fprintf_folded(FILE *fp, struct callchain_node *node)  {  	const char *sep = " <- "; @@ -2890,11 +2891,6 @@ static void timehist_print_summary(struct perf_sched *sched,  	if (!task_count)  		printf("<no still running tasks>\n"); -	printf("\nTerminated tasks:\n"); -	machine__for_each_thread(m, show_deadthread_runtime, &totals); -	if (task_count == totals.task_count) -		printf("<no terminated tasks>\n"); -  	/* CPU idle stats not tracked when samples were skipped */  	if (sched->skipped_samples && !sched->idle_hist)  		return; @@ -3599,7 +3595,22 @@ int cmd_sched(int argc, const char **argv)  	mutex_init(&sched.start_work_mutex);  	mutex_init(&sched.work_done_wait_mutex); -	for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++) +	sched.curr_thread = calloc(MAX_CPUS, sizeof(*sched.curr_thread)); +	if (!sched.curr_thread) { +		ret = -ENOMEM; +		goto out; +	} +	sched.cpu_last_switched = calloc(MAX_CPUS, sizeof(*sched.cpu_last_switched)); +	if (!sched.cpu_last_switched) { +		ret = -ENOMEM; +		goto out; +	} +	sched.curr_pid = malloc(MAX_CPUS * sizeof(*sched.curr_pid)); +	if (!sched.curr_pid) { +		ret = -ENOMEM; +		goto out; +	} +	for (i = 0; i < MAX_CPUS; i++)  		sched.curr_pid[i] = -1;  	argc = parse_options_subcommand(argc, argv, sched_options, sched_subcommands, @@ -3668,6 +3679,9 @@ int cmd_sched(int argc, const char **argv)  	}  out: +	free(sched.curr_pid); +	free(sched.cpu_last_switched); +	free(sched.curr_thread);  	mutex_destroy(&sched.start_work_mutex);  	mutex_destroy(&sched.work_done_wait_mutex);  |