Commit 064b4e82 authored by Jin Yao's avatar Jin Yao Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Add a 'percore' event qualifier



Add a 'percore' event qualifier, like cpu/event=0,umask=0x3,percore=1/,
that sums up the event counts for both hardware threads in a core.

We can already do this with --per-core, but it's often useful to do
this together with other metrics that are collected per hardware thread.
So we need to support this per-core counting on a event level.

This can be implemented in only the user tool, no kernel support needed.

 v4:
 ---
 1. Add Arnaldo's patch which updates the documentation for
    this new qualifier.
 2. Rebase to latest perf/core branch

 v3:
 ---
 Simplify the code according to Jiri's comments.
 Before:
   "return term->val.percore ? true : false;"
 Now:
   "return term->val.percore;"

 v2:
 ---
 Change the qualifier name from 'coresum' to 'percore' according to
 comments from Jiri and Andi.

Signed-off-by: default avatarJin Yao <yao.jin@linux.intel.com>
Tested-by: default avatarRavi Bangoria <ravi.bangoria@linux.ibm.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jin Yao <yao.jin@intel.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1555077590-27664-2-git-send-email-yao.jin@linux.intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 6cf62656
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -199,6 +199,18 @@ also be supplied. For example:

  perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ...

EVENT QUALIFIERS:

It is also possible to add extra qualifiers to an event:

percore:

Sums up the event counts for all hardware threads in a core, e.g.:


  perf stat -e cpu/event=0,umask=0x3,percore=1/


EVENT GROUPS
------------

+2 −0
Original line number Diff line number Diff line
@@ -813,6 +813,8 @@ static void apply_config_terms(struct perf_evsel *evsel,
			break;
		case PERF_EVSEL__CONFIG_TERM_DRV_CFG:
			break;
		case PERF_EVSEL__CONFIG_TERM_PERCORE:
			break;
		default:
			break;
		}
+3 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ enum term_type {
	PERF_EVSEL__CONFIG_TERM_OVERWRITE,
	PERF_EVSEL__CONFIG_TERM_DRV_CFG,
	PERF_EVSEL__CONFIG_TERM_BRANCH,
	PERF_EVSEL__CONFIG_TERM_PERCORE,
};

struct perf_evsel_config_term {
@@ -67,6 +68,7 @@ struct perf_evsel_config_term {
		bool	overwrite;
		char	*branch;
		unsigned long max_events;
		bool	percore;
	} val;
	bool weak;
};
@@ -158,6 +160,7 @@ struct perf_evsel {
	struct perf_evsel	**metric_events;
	bool			collect_stat;
	bool			weak_group;
	bool			percore;
	const char		*pmu_name;
	struct {
		perf_evsel__sb_cb_t	*cb;
+27 −0
Original line number Diff line number Diff line
@@ -950,6 +950,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
	[PARSE_EVENTS__TERM_TYPE_OVERWRITE]		= "overwrite",
	[PARSE_EVENTS__TERM_TYPE_NOOVERWRITE]		= "no-overwrite",
	[PARSE_EVENTS__TERM_TYPE_DRV_CFG]		= "driver-config",
	[PARSE_EVENTS__TERM_TYPE_PERCORE]		= "percore",
};

static bool config_term_shrinked;
@@ -970,6 +971,7 @@ config_term_avail(int term_type, struct parse_events_error *err)
	case PARSE_EVENTS__TERM_TYPE_CONFIG2:
	case PARSE_EVENTS__TERM_TYPE_NAME:
	case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
	case PARSE_EVENTS__TERM_TYPE_PERCORE:
		return true;
	default:
		if (!err)
@@ -1061,6 +1063,14 @@ do { \
	case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
		CHECK_TYPE_VAL(NUM);
		break;
	case PARSE_EVENTS__TERM_TYPE_PERCORE:
		CHECK_TYPE_VAL(NUM);
		if ((unsigned int)term->val.num > 1) {
			err->str = strdup("expected 0 or 1");
			err->idx = term->err_val;
			return -EINVAL;
		}
		break;
	default:
		err->str = strdup("unknown term");
		err->idx = term->err_term;
@@ -1199,6 +1209,10 @@ do { \
		case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
			ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str);
			break;
		case PARSE_EVENTS__TERM_TYPE_PERCORE:
			ADD_CONFIG_TERM(PERCORE, percore,
					term->val.num ? true : false);
			break;
		default:
			break;
		}
@@ -1260,6 +1274,18 @@ int parse_events_add_tool(struct parse_events_state *parse_state,
	return add_event_tool(list, &parse_state->idx, tool_event);
}

static bool config_term_percore(struct list_head *config_terms)
{
	struct perf_evsel_config_term *term;

	list_for_each_entry(term, config_terms, list) {
		if (term->type == PERF_EVSEL__CONFIG_TERM_PERCORE)
			return term->val.percore;
	}

	return false;
}

int parse_events_add_pmu(struct parse_events_state *parse_state,
			 struct list_head *list, char *name,
			 struct list_head *head_config,
@@ -1333,6 +1359,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
		evsel->metric_name = info.metric_name;
		evsel->pmu_name = name;
		evsel->use_uncore_alias = use_uncore_alias;
		evsel->percore = config_term_percore(&evsel->config_terms);
	}

	return evsel ? 0 : -ENOMEM;
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ enum {
	PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
	PARSE_EVENTS__TERM_TYPE_OVERWRITE,
	PARSE_EVENTS__TERM_TYPE_DRV_CFG,
	PARSE_EVENTS__TERM_TYPE_PERCORE,
	__PARSE_EVENTS__TERM_TYPE_NR,
};

Loading