mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	perf hists: Check if accumulated when adding a hist entry
To support callchain accumulation, @entry should be recognized if it's accumulated or not when add_hist_entry() called. The period of an accumulated entry should be added to ->stat_acc but not ->stat. Add @sample_self arg for that. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Tested-by: Arun Sharma <asharma@fb.com> Tested-by: Rodrigo Campos <rodrigo@sdfg.com.ar> Cc: Frederic Weisbecker <fweisbec@gmail.com> Link: http://lkml.kernel.org/r/1401335910-16832-5-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa <jolsa@kernel.org>
This commit is contained in:
		
							parent
							
								
									f8be1c8c48
								
							
						
					
					
						commit
						a0b51af367
					
				
					 6 changed files with 26 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -65,7 +65,8 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
 | 
			
		|||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0);
 | 
			
		||||
	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0,
 | 
			
		||||
				true);
 | 
			
		||||
	if (he == NULL)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -315,7 +315,7 @@ static int hists__add_entry(struct hists *hists,
 | 
			
		|||
			    u64 weight, u64 transaction)
 | 
			
		||||
{
 | 
			
		||||
	if (__hists__add_entry(hists, al, NULL, NULL, NULL, period, weight,
 | 
			
		||||
			       transaction) != NULL)
 | 
			
		||||
			       transaction, true) != NULL)
 | 
			
		||||
		return 0;
 | 
			
		||||
	return -ENOMEM;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -247,7 +247,7 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
 | 
			
		|||
	pthread_mutex_lock(&evsel->hists.lock);
 | 
			
		||||
	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL,
 | 
			
		||||
				sample->period, sample->weight,
 | 
			
		||||
				sample->transaction);
 | 
			
		||||
				sample->transaction, true);
 | 
			
		||||
	pthread_mutex_unlock(&evsel->hists.lock);
 | 
			
		||||
	if (he == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 | 
			
		|||
				goto out;
 | 
			
		||||
 | 
			
		||||
			he = __hists__add_entry(&evsel->hists, &al, NULL,
 | 
			
		||||
						NULL, NULL, 1, 1, 0);
 | 
			
		||||
						NULL, NULL, 1, 1, 0, true);
 | 
			
		||||
			if (he == NULL)
 | 
			
		||||
				goto out;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 | 
			
		|||
				goto out;
 | 
			
		||||
 | 
			
		||||
			he = __hists__add_entry(&evsel->hists, &al, NULL,
 | 
			
		||||
						NULL, NULL, 1, 1, 0);
 | 
			
		||||
						NULL, NULL, 1, 1, 0, true);
 | 
			
		||||
			if (he == NULL)
 | 
			
		||||
				goto out;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,7 +279,8 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
 | 
			
		|||
 * histogram, sorted on item, collects periods
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static struct hist_entry *hist_entry__new(struct hist_entry *template)
 | 
			
		||||
static struct hist_entry *hist_entry__new(struct hist_entry *template,
 | 
			
		||||
					  bool sample_self)
 | 
			
		||||
{
 | 
			
		||||
	size_t callchain_size = 0;
 | 
			
		||||
	struct hist_entry *he;
 | 
			
		||||
| 
						 | 
				
			
			@ -299,6 +300,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
 | 
			
		|||
				return NULL;
 | 
			
		||||
			}
 | 
			
		||||
			memcpy(he->stat_acc, &he->stat, sizeof(he->stat));
 | 
			
		||||
			if (!sample_self)
 | 
			
		||||
				memset(&he->stat, 0, sizeof(he->stat));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (he->ms.map)
 | 
			
		||||
| 
						 | 
				
			
			@ -351,7 +354,8 @@ static u8 symbol__parent_filter(const struct symbol *parent)
 | 
			
		|||
 | 
			
		||||
static struct hist_entry *add_hist_entry(struct hists *hists,
 | 
			
		||||
					 struct hist_entry *entry,
 | 
			
		||||
					 struct addr_location *al)
 | 
			
		||||
					 struct addr_location *al,
 | 
			
		||||
					 bool sample_self)
 | 
			
		||||
{
 | 
			
		||||
	struct rb_node **p;
 | 
			
		||||
	struct rb_node *parent = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -375,7 +379,8 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
 | 
			
		|||
		cmp = hist_entry__cmp(he, entry);
 | 
			
		||||
 | 
			
		||||
		if (!cmp) {
 | 
			
		||||
			he_stat__add_period(&he->stat, period, weight);
 | 
			
		||||
			if (sample_self)
 | 
			
		||||
				he_stat__add_period(&he->stat, period, weight);
 | 
			
		||||
			if (symbol_conf.cumulate_callchain)
 | 
			
		||||
				he_stat__add_period(he->stat_acc, period, weight);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -405,14 +410,15 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
 | 
			
		|||
			p = &(*p)->rb_right;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	he = hist_entry__new(entry);
 | 
			
		||||
	he = hist_entry__new(entry, sample_self);
 | 
			
		||||
	if (!he)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	rb_link_node(&he->rb_node_in, parent, p);
 | 
			
		||||
	rb_insert_color(&he->rb_node_in, hists->entries_in);
 | 
			
		||||
out:
 | 
			
		||||
	he_stat__add_cpumode_period(&he->stat, al->cpumode, period);
 | 
			
		||||
	if (sample_self)
 | 
			
		||||
		he_stat__add_cpumode_period(&he->stat, al->cpumode, period);
 | 
			
		||||
	if (symbol_conf.cumulate_callchain)
 | 
			
		||||
		he_stat__add_cpumode_period(he->stat_acc, al->cpumode, period);
 | 
			
		||||
	return he;
 | 
			
		||||
| 
						 | 
				
			
			@ -423,7 +429,8 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 | 
			
		|||
				      struct symbol *sym_parent,
 | 
			
		||||
				      struct branch_info *bi,
 | 
			
		||||
				      struct mem_info *mi,
 | 
			
		||||
				      u64 period, u64 weight, u64 transaction)
 | 
			
		||||
				      u64 period, u64 weight, u64 transaction,
 | 
			
		||||
				      bool sample_self)
 | 
			
		||||
{
 | 
			
		||||
	struct hist_entry entry = {
 | 
			
		||||
		.thread	= al->thread,
 | 
			
		||||
| 
						 | 
				
			
			@ -448,7 +455,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 | 
			
		|||
		.transaction = transaction,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return add_hist_entry(hists, &entry, al);
 | 
			
		||||
	return add_hist_entry(hists, &entry, al, sample_self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
| 
						 | 
				
			
			@ -501,7 +508,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
 | 
			
		|||
	 * and the he_stat__add_period() function.
 | 
			
		||||
	 */
 | 
			
		||||
	he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi,
 | 
			
		||||
				cost, cost, 0);
 | 
			
		||||
				cost, cost, 0, true);
 | 
			
		||||
	if (!he)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -608,7 +615,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
 | 
			
		|||
	 * and not events sampled. Thus we use a pseudo period of 1.
 | 
			
		||||
	 */
 | 
			
		||||
	he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL,
 | 
			
		||||
				1, 1, 0);
 | 
			
		||||
				1, 1, 0, true);
 | 
			
		||||
	if (he == NULL)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -657,7 +664,7 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location
 | 
			
		|||
 | 
			
		||||
	he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
 | 
			
		||||
				sample->period, sample->weight,
 | 
			
		||||
				sample->transaction);
 | 
			
		||||
				sample->transaction, true);
 | 
			
		||||
	if (he == NULL)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1161,7 +1168,7 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists,
 | 
			
		|||
			p = &(*p)->rb_right;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	he = hist_entry__new(pair);
 | 
			
		||||
	he = hist_entry__new(pair, true);
 | 
			
		||||
	if (he) {
 | 
			
		||||
		memset(&he->stat, 0, sizeof(he->stat));
 | 
			
		||||
		he->hists = hists;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,7 +130,8 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 | 
			
		|||
				      struct symbol *parent,
 | 
			
		||||
				      struct branch_info *bi,
 | 
			
		||||
				      struct mem_info *mi, u64 period,
 | 
			
		||||
				      u64 weight, u64 transaction);
 | 
			
		||||
				      u64 weight, u64 transaction,
 | 
			
		||||
				      bool sample_self);
 | 
			
		||||
int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 | 
			
		||||
			 struct perf_evsel *evsel, struct perf_sample *sample,
 | 
			
		||||
			 int max_stack_depth);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue