mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	perf c2c report: Add hitm/store percent related sort keys
They are to be displayed in the single cacheline output: percent_rmt_hitm, percent_lcl_hitm, percent_stores_l1hit, percent_stores_l1miss They display percentage of HITMs/stores for specific offset in the cacheline. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Ahern <dsahern@gmail.com> Cc: Don Zickus <dzickus@redhat.com> Cc: Joe Mario <jmario@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/n/tip-t365aosxtdut8sgrgn8mfoe4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
		
							parent
							
								
									f0c50c1593
								
							
						
					
					
						commit
						9cb3500afc
					
				
					 1 changed files with 202 additions and 0 deletions
				
			
		| 
						 | 
					@ -646,6 +646,167 @@ percent_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 | 
				
			||||||
	return per_left - per_right;
 | 
						return per_left - per_right;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct c2c_stats *he_stats(struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct c2c_hist_entry *c2c_he;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c2c_he = container_of(he, struct c2c_hist_entry, he);
 | 
				
			||||||
 | 
						return &c2c_he->stats;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct c2c_stats *total_stats(struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct c2c_hists *hists;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hists = container_of(he->hists, struct c2c_hists, hists);
 | 
				
			||||||
 | 
						return &hists->stats;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static double percent(int st, int tot)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return tot ? 100. * (double) st / (double) tot : 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PERCENT(__h, __f) percent(he_stats(__h)->__f, total_stats(__h)->__f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PERCENT_FN(__f)								\
 | 
				
			||||||
 | 
					static double percent_ ## __f(struct c2c_hist_entry *c2c_he)			\
 | 
				
			||||||
 | 
					{										\
 | 
				
			||||||
 | 
						struct c2c_hists *hists;						\
 | 
				
			||||||
 | 
															\
 | 
				
			||||||
 | 
						hists = container_of(c2c_he->he.hists, struct c2c_hists, hists);	\
 | 
				
			||||||
 | 
						return percent(c2c_he->stats.__f, hists->stats.__f);			\
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PERCENT_FN(rmt_hitm)
 | 
				
			||||||
 | 
					PERCENT_FN(lcl_hitm)
 | 
				
			||||||
 | 
					PERCENT_FN(st_l1hit)
 | 
				
			||||||
 | 
					PERCENT_FN(st_l1miss)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_rmt_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
							       struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int width = c2c_width(fmt, hpp, he->hists);
 | 
				
			||||||
 | 
						double per = PERCENT(he, rmt_hitm);
 | 
				
			||||||
 | 
						char buf[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_rmt_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
							       struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return percent_color(fmt, hpp, he, percent_rmt_hitm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int64_t
 | 
				
			||||||
 | 
					percent_rmt_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 | 
				
			||||||
 | 
							     struct hist_entry *left, struct hist_entry *right)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						double per_left;
 | 
				
			||||||
 | 
						double per_right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						per_left  = PERCENT(left, lcl_hitm);
 | 
				
			||||||
 | 
						per_right = PERCENT(right, lcl_hitm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return per_left - per_right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_lcl_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
							       struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int width = c2c_width(fmt, hpp, he->hists);
 | 
				
			||||||
 | 
						double per = PERCENT(he, lcl_hitm);
 | 
				
			||||||
 | 
						char buf[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_lcl_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
							       struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return percent_color(fmt, hpp, he, percent_lcl_hitm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int64_t
 | 
				
			||||||
 | 
					percent_lcl_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 | 
				
			||||||
 | 
							     struct hist_entry *left, struct hist_entry *right)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						double per_left;
 | 
				
			||||||
 | 
						double per_right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						per_left  = PERCENT(left, lcl_hitm);
 | 
				
			||||||
 | 
						per_right = PERCENT(right, lcl_hitm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return per_left - per_right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_stores_l1hit_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
								   struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int width = c2c_width(fmt, hpp, he->hists);
 | 
				
			||||||
 | 
						double per = PERCENT(he, st_l1hit);
 | 
				
			||||||
 | 
						char buf[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_stores_l1hit_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
								   struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return percent_color(fmt, hpp, he, percent_st_l1hit);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int64_t
 | 
				
			||||||
 | 
					percent_stores_l1hit_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 | 
				
			||||||
 | 
								struct hist_entry *left, struct hist_entry *right)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						double per_left;
 | 
				
			||||||
 | 
						double per_right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						per_left  = PERCENT(left, st_l1hit);
 | 
				
			||||||
 | 
						per_right = PERCENT(right, st_l1hit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return per_left - per_right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_stores_l1miss_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
								   struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int width = c2c_width(fmt, hpp, he->hists);
 | 
				
			||||||
 | 
						double per = PERCENT(he, st_l1miss);
 | 
				
			||||||
 | 
						char buf[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					percent_stores_l1miss_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 | 
				
			||||||
 | 
								    struct hist_entry *he)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return percent_color(fmt, hpp, he, percent_st_l1miss);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int64_t
 | 
				
			||||||
 | 
					percent_stores_l1miss_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 | 
				
			||||||
 | 
								  struct hist_entry *left, struct hist_entry *right)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						double per_left;
 | 
				
			||||||
 | 
						double per_right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						per_left  = PERCENT(left, st_l1miss);
 | 
				
			||||||
 | 
						per_right = PERCENT(right, st_l1miss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return per_left - per_right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define HEADER_LOW(__h)			\
 | 
					#define HEADER_LOW(__h)			\
 | 
				
			||||||
	{				\
 | 
						{				\
 | 
				
			||||||
		.line[1] = {		\
 | 
							.line[1] = {		\
 | 
				
			||||||
| 
						 | 
					@ -858,6 +1019,42 @@ static struct c2c_dimension dim_percent_hitm = {
 | 
				
			||||||
	.width		= 7,
 | 
						.width		= 7,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct c2c_dimension dim_percent_rmt_hitm = {
 | 
				
			||||||
 | 
						.header		= HEADER_SPAN("----- HITM -----", "Rmt", 1),
 | 
				
			||||||
 | 
						.name		= "percent_rmt_hitm",
 | 
				
			||||||
 | 
						.cmp		= percent_rmt_hitm_cmp,
 | 
				
			||||||
 | 
						.entry		= percent_rmt_hitm_entry,
 | 
				
			||||||
 | 
						.color		= percent_rmt_hitm_color,
 | 
				
			||||||
 | 
						.width		= 7,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct c2c_dimension dim_percent_lcl_hitm = {
 | 
				
			||||||
 | 
						.header		= HEADER_SPAN_LOW("Lcl"),
 | 
				
			||||||
 | 
						.name		= "percent_lcl_hitm",
 | 
				
			||||||
 | 
						.cmp		= percent_lcl_hitm_cmp,
 | 
				
			||||||
 | 
						.entry		= percent_lcl_hitm_entry,
 | 
				
			||||||
 | 
						.color		= percent_lcl_hitm_color,
 | 
				
			||||||
 | 
						.width		= 7,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct c2c_dimension dim_percent_stores_l1hit = {
 | 
				
			||||||
 | 
						.header		= HEADER_SPAN("-- Store Refs --", "L1 Hit", 1),
 | 
				
			||||||
 | 
						.name		= "percent_stores_l1hit",
 | 
				
			||||||
 | 
						.cmp		= percent_stores_l1hit_cmp,
 | 
				
			||||||
 | 
						.entry		= percent_stores_l1hit_entry,
 | 
				
			||||||
 | 
						.color		= percent_stores_l1hit_color,
 | 
				
			||||||
 | 
						.width		= 7,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct c2c_dimension dim_percent_stores_l1miss = {
 | 
				
			||||||
 | 
						.header		= HEADER_SPAN_LOW("L1 Miss"),
 | 
				
			||||||
 | 
						.name		= "percent_stores_l1miss",
 | 
				
			||||||
 | 
						.cmp		= percent_stores_l1miss_cmp,
 | 
				
			||||||
 | 
						.entry		= percent_stores_l1miss_entry,
 | 
				
			||||||
 | 
						.color		= percent_stores_l1miss_color,
 | 
				
			||||||
 | 
						.width		= 7,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct c2c_dimension *dimensions[] = {
 | 
					static struct c2c_dimension *dimensions[] = {
 | 
				
			||||||
	&dim_dcacheline,
 | 
						&dim_dcacheline,
 | 
				
			||||||
	&dim_offset,
 | 
						&dim_offset,
 | 
				
			||||||
| 
						 | 
					@ -881,6 +1078,10 @@ static struct c2c_dimension *dimensions[] = {
 | 
				
			||||||
	&dim_tot_recs,
 | 
						&dim_tot_recs,
 | 
				
			||||||
	&dim_tot_loads,
 | 
						&dim_tot_loads,
 | 
				
			||||||
	&dim_percent_hitm,
 | 
						&dim_percent_hitm,
 | 
				
			||||||
 | 
						&dim_percent_rmt_hitm,
 | 
				
			||||||
 | 
						&dim_percent_lcl_hitm,
 | 
				
			||||||
 | 
						&dim_percent_stores_l1hit,
 | 
				
			||||||
 | 
						&dim_percent_stores_l1miss,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -968,6 +1169,7 @@ static struct c2c_fmt *get_format(const char *name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt->cmp	= dim->se ? c2c_se_cmp   : dim->cmp;
 | 
						fmt->cmp	= dim->se ? c2c_se_cmp   : dim->cmp;
 | 
				
			||||||
	fmt->sort	= dim->se ? c2c_se_cmp   : dim->cmp;
 | 
						fmt->sort	= dim->se ? c2c_se_cmp   : dim->cmp;
 | 
				
			||||||
 | 
						fmt->color	= dim->se ? NULL	 : dim->color;
 | 
				
			||||||
	fmt->entry	= dim->se ? c2c_se_entry : dim->entry;
 | 
						fmt->entry	= dim->se ? c2c_se_entry : dim->entry;
 | 
				
			||||||
	fmt->header	= c2c_header;
 | 
						fmt->header	= c2c_header;
 | 
				
			||||||
	fmt->width	= c2c_width;
 | 
						fmt->width	= c2c_width;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue