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

perf parse-events: Compare with hybrid pmu name



On hybrid platform, user may want to enable event only on one pmu.
Following syntax will be supported:

cpu_core/<event>/
cpu_atom/<event>/

For hardware event, hardware cache event and raw event, two events
are created by default. We pass the specified pmu name in parse_state
and it would be checked before event creation. So next only the
event with the specified pmu would be created.

Signed-off-by: default avatarJin Yao <yao.jin@linux.intel.com>
Reviewed-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210427070139.25256-12-yao.jin@linux.intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 94da591b
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -59,6 +59,15 @@ static int create_event_hybrid(__u32 config_type, int *idx,
	return 0;
}

static int pmu_cmp(struct parse_events_state *parse_state,
		   struct perf_pmu *pmu)
{
	if (!parse_state->hybrid_pmu_name)
		return 0;

	return strcmp(parse_state->hybrid_pmu_name, pmu->name);
}

static int add_hw_hybrid(struct parse_events_state *parse_state,
			 struct list_head *list, struct perf_event_attr *attr,
			 char *name, struct list_head *config_terms)
@@ -67,6 +76,9 @@ static int add_hw_hybrid(struct parse_events_state *parse_state,
	int ret;

	perf_pmu__for_each_hybrid_pmu(pmu) {
		if (pmu_cmp(parse_state, pmu))
			continue;

		ret = create_event_hybrid(PERF_TYPE_HARDWARE,
					  &parse_state->idx, list, attr, name,
					  config_terms, pmu);
@@ -103,6 +115,9 @@ static int add_raw_hybrid(struct parse_events_state *parse_state,
	int ret;

	perf_pmu__for_each_hybrid_pmu(pmu) {
		if (pmu_cmp(parse_state, pmu))
			continue;

		ret = create_raw_event_hybrid(&parse_state->idx, list, attr,
					      name, config_terms, pmu);
		if (ret)
@@ -138,7 +153,8 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
				   struct perf_event_attr *attr, char *name,
				   struct list_head *config_terms,
				   bool *hybrid)
				   bool *hybrid,
				   struct parse_events_state *parse_state)
{
	struct perf_pmu *pmu;
	int ret;
@@ -149,6 +165,9 @@ int parse_events__add_cache_hybrid(struct list_head *list, int *idx,

	*hybrid = true;
	perf_pmu__for_each_hybrid_pmu(pmu) {
		if (pmu_cmp(parse_state, pmu))
			continue;

		ret = create_event_hybrid(PERF_TYPE_HW_CACHE, idx, list,
					  attr, name, config_terms, pmu);
		if (ret)
+2 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
				   struct perf_event_attr *attr, char *name,
				   struct list_head *config_terms,
				   bool *hybrid);
				   bool *hybrid,
				   struct parse_events_state *parse_state);

#endif /* __PERF_PARSE_EVENTS_HYBRID_H */
+3 −2
Original line number Diff line number Diff line
@@ -453,7 +453,8 @@ static int config_attr(struct perf_event_attr *attr,
int parse_events_add_cache(struct list_head *list, int *idx,
			   char *type, char *op_result1, char *op_result2,
			   struct parse_events_error *err,
			   struct list_head *head_config)
			   struct list_head *head_config,
			   struct parse_events_state *parse_state)
{
	struct perf_event_attr attr;
	LIST_HEAD(config_terms);
@@ -524,7 +525,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,

	ret = parse_events__add_cache_hybrid(list, idx, &attr,
					     config_name ? : name, &config_terms,
					     &hybrid);
					     &hybrid, parse_state);
	if (hybrid)
		return ret;

+3 −1
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ struct parse_events_state {
	struct list_head	  *terms;
	int			   stoken;
	struct perf_pmu		  *fake_pmu;
	char			  *hybrid_pmu_name;
};

void parse_events__handle_error(struct parse_events_error *err, int idx,
@@ -188,7 +189,8 @@ int parse_events_add_tool(struct parse_events_state *parse_state,
int parse_events_add_cache(struct list_head *list, int *idx,
			   char *type, char *op_result1, char *op_result2,
			   struct parse_events_error *error,
			   struct list_head *head_config);
			   struct list_head *head_config,
			   struct parse_events_state *parse_state);
int parse_events_add_breakpoint(struct list_head *list, int *idx,
				u64 addr, char *type, u64 len);
int parse_events_add_pmu(struct parse_events_state *parse_state,
+6 −3
Original line number Diff line number Diff line
@@ -454,7 +454,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_e

	list = alloc_list();
	ABORT_ON(!list);
	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6);
	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6,
				     parse_state);
	parse_events_terms__delete($6);
	free($1);
	free($3);
@@ -475,7 +476,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config

	list = alloc_list();
	ABORT_ON(!list);
	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4);
	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4,
				     parse_state);
	parse_events_terms__delete($4);
	free($1);
	free($3);
@@ -495,7 +497,8 @@ PE_NAME_CACHE_TYPE opt_event_config

	list = alloc_list();
	ABORT_ON(!list);
	err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2);
	err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2,
				     parse_state);
	parse_events_terms__delete($2);
	free($1);
	if (err) {