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

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.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 6cf62656
...@@ -199,6 +199,18 @@ also be supplied. For example: ...@@ -199,6 +199,18 @@ also be supplied. For example:
perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ... 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 EVENT GROUPS
------------ ------------
......
...@@ -813,6 +813,8 @@ static void apply_config_terms(struct perf_evsel *evsel, ...@@ -813,6 +813,8 @@ static void apply_config_terms(struct perf_evsel *evsel,
break; break;
case PERF_EVSEL__CONFIG_TERM_DRV_CFG: case PERF_EVSEL__CONFIG_TERM_DRV_CFG:
break; break;
case PERF_EVSEL__CONFIG_TERM_PERCORE:
break;
default: default:
break; break;
} }
......
...@@ -50,6 +50,7 @@ enum term_type { ...@@ -50,6 +50,7 @@ enum term_type {
PERF_EVSEL__CONFIG_TERM_OVERWRITE, PERF_EVSEL__CONFIG_TERM_OVERWRITE,
PERF_EVSEL__CONFIG_TERM_DRV_CFG, PERF_EVSEL__CONFIG_TERM_DRV_CFG,
PERF_EVSEL__CONFIG_TERM_BRANCH, PERF_EVSEL__CONFIG_TERM_BRANCH,
PERF_EVSEL__CONFIG_TERM_PERCORE,
}; };
struct perf_evsel_config_term { struct perf_evsel_config_term {
...@@ -67,6 +68,7 @@ struct perf_evsel_config_term { ...@@ -67,6 +68,7 @@ struct perf_evsel_config_term {
bool overwrite; bool overwrite;
char *branch; char *branch;
unsigned long max_events; unsigned long max_events;
bool percore;
} val; } val;
bool weak; bool weak;
}; };
...@@ -158,6 +160,7 @@ struct perf_evsel { ...@@ -158,6 +160,7 @@ struct perf_evsel {
struct perf_evsel **metric_events; struct perf_evsel **metric_events;
bool collect_stat; bool collect_stat;
bool weak_group; bool weak_group;
bool percore;
const char *pmu_name; const char *pmu_name;
struct { struct {
perf_evsel__sb_cb_t *cb; perf_evsel__sb_cb_t *cb;
......
...@@ -950,6 +950,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = { ...@@ -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_OVERWRITE] = "overwrite",
[PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite", [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
[PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config", [PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config",
[PARSE_EVENTS__TERM_TYPE_PERCORE] = "percore",
}; };
static bool config_term_shrinked; static bool config_term_shrinked;
...@@ -970,6 +971,7 @@ config_term_avail(int term_type, struct parse_events_error *err) ...@@ -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_CONFIG2:
case PARSE_EVENTS__TERM_TYPE_NAME: case PARSE_EVENTS__TERM_TYPE_NAME:
case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
case PARSE_EVENTS__TERM_TYPE_PERCORE:
return true; return true;
default: default:
if (!err) if (!err)
...@@ -1061,6 +1063,14 @@ do { \ ...@@ -1061,6 +1063,14 @@ do { \
case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
CHECK_TYPE_VAL(NUM); CHECK_TYPE_VAL(NUM);
break; 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: default:
err->str = strdup("unknown term"); err->str = strdup("unknown term");
err->idx = term->err_term; err->idx = term->err_term;
...@@ -1199,6 +1209,10 @@ do { \ ...@@ -1199,6 +1209,10 @@ do { \
case PARSE_EVENTS__TERM_TYPE_DRV_CFG: case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str); ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str);
break; break;
case PARSE_EVENTS__TERM_TYPE_PERCORE:
ADD_CONFIG_TERM(PERCORE, percore,
term->val.num ? true : false);
break;
default: default:
break; break;
} }
...@@ -1260,6 +1274,18 @@ int parse_events_add_tool(struct parse_events_state *parse_state, ...@@ -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); 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, int parse_events_add_pmu(struct parse_events_state *parse_state,
struct list_head *list, char *name, struct list_head *list, char *name,
struct list_head *head_config, struct list_head *head_config,
...@@ -1333,6 +1359,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, ...@@ -1333,6 +1359,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
evsel->metric_name = info.metric_name; evsel->metric_name = info.metric_name;
evsel->pmu_name = name; evsel->pmu_name = name;
evsel->use_uncore_alias = use_uncore_alias; evsel->use_uncore_alias = use_uncore_alias;
evsel->percore = config_term_percore(&evsel->config_terms);
} }
return evsel ? 0 : -ENOMEM; return evsel ? 0 : -ENOMEM;
......
...@@ -75,6 +75,7 @@ enum { ...@@ -75,6 +75,7 @@ enum {
PARSE_EVENTS__TERM_TYPE_NOOVERWRITE, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
PARSE_EVENTS__TERM_TYPE_OVERWRITE, PARSE_EVENTS__TERM_TYPE_OVERWRITE,
PARSE_EVENTS__TERM_TYPE_DRV_CFG, PARSE_EVENTS__TERM_TYPE_DRV_CFG,
PARSE_EVENTS__TERM_TYPE_PERCORE,
__PARSE_EVENTS__TERM_TYPE_NR, __PARSE_EVENTS__TERM_TYPE_NR,
}; };
......
...@@ -283,6 +283,7 @@ inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); } ...@@ -283,6 +283,7 @@ inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); } no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); } overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); } no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
percore { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_PERCORE); }
, { return ','; } , { return ','; }
"/" { BEGIN(INITIAL); return '/'; } "/" { BEGIN(INITIAL); return '/'; }
{name_minus} { return str(yyscanner, PE_NAME); } {name_minus} { return str(yyscanner, PE_NAME); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment