Commit 287f2649 authored by Jin Yao's avatar Jin Yao Committed by Arnaldo Carvalho de Melo

perf metricgroup: Scale the metric result

Some metrics define the scale unit, such as

    {
        "BriefDescription": "Intel Optane DC persistent memory read latency (ns). Derived from unc_m_pmm_rpq_occupancy.all",
        "Counter": "0,1,2,3",
        "EventCode": "0xE0",
        "EventName": "UNC_M_PMM_READ_LATENCY",
        "MetricExpr": "UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS",
        "MetricName": "UNC_M_PMM_READ_LATENCY",
        "PerPkg": "1",
        "ScaleUnit": "6000000000ns",
        "UMask": "0x1",
        "Unit": "iMC"
    },

For above example, the ratio should be,

ratio = (UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS) * 6000000000

But in current code, the ratio is not scaled ( * 6000000000)

With this patch, the ratio is scaled and the unit (ns) is printed.

For example,
  #    219.4 ns  UNC_M_PMM_READ_LATENCY
Signed-off-by: default avatarJin Yao <yao.jin@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20190828055932.8269-4-yao.jin@linux.intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent a55ab7c4
...@@ -87,6 +87,7 @@ struct egroup { ...@@ -87,6 +87,7 @@ struct egroup {
const char **ids; const char **ids;
const char *metric_name; const char *metric_name;
const char *metric_expr; const char *metric_expr;
const char *metric_unit;
}; };
static bool record_evsel(int *ind, struct evsel **start, static bool record_evsel(int *ind, struct evsel **start,
...@@ -182,6 +183,7 @@ static int metricgroup__setup_events(struct list_head *groups, ...@@ -182,6 +183,7 @@ static int metricgroup__setup_events(struct list_head *groups,
} }
expr->metric_expr = eg->metric_expr; expr->metric_expr = eg->metric_expr;
expr->metric_name = eg->metric_name; expr->metric_name = eg->metric_name;
expr->metric_unit = eg->metric_unit;
expr->metric_events = metric_events; expr->metric_events = metric_events;
list_add(&expr->nd, &me->head); list_add(&expr->nd, &me->head);
} }
...@@ -453,6 +455,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events, ...@@ -453,6 +455,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
eg->idnum = idnum; eg->idnum = idnum;
eg->metric_name = pe->metric_name; eg->metric_name = pe->metric_name;
eg->metric_expr = pe->metric_expr; eg->metric_expr = pe->metric_expr;
eg->metric_unit = pe->unit;
list_add_tail(&eg->nd, group_list); list_add_tail(&eg->nd, group_list);
ret = 0; ret = 0;
} }
......
...@@ -20,6 +20,7 @@ struct metric_expr { ...@@ -20,6 +20,7 @@ struct metric_expr {
struct list_head nd; struct list_head nd;
const char *metric_expr; const char *metric_expr;
const char *metric_name; const char *metric_name;
const char *metric_unit;
struct evsel **metric_events; struct evsel **metric_events;
}; };
......
...@@ -715,6 +715,7 @@ static void generic_metric(struct perf_stat_config *config, ...@@ -715,6 +715,7 @@ static void generic_metric(struct perf_stat_config *config,
struct evsel **metric_events, struct evsel **metric_events,
char *name, char *name,
const char *metric_name, const char *metric_name,
const char *metric_unit,
double avg, double avg,
int cpu, int cpu,
struct perf_stat_output_ctx *out, struct perf_stat_output_ctx *out,
...@@ -722,7 +723,7 @@ static void generic_metric(struct perf_stat_config *config, ...@@ -722,7 +723,7 @@ static void generic_metric(struct perf_stat_config *config,
{ {
print_metric_t print_metric = out->print_metric; print_metric_t print_metric = out->print_metric;
struct parse_ctx pctx; struct parse_ctx pctx;
double ratio; double ratio, scale;
int i; int i;
void *ctxp = out->ctx; void *ctxp = out->ctx;
char *n, *pn; char *n, *pn;
...@@ -732,7 +733,6 @@ static void generic_metric(struct perf_stat_config *config, ...@@ -732,7 +733,6 @@ static void generic_metric(struct perf_stat_config *config,
for (i = 0; metric_events[i]; i++) { for (i = 0; metric_events[i]; i++) {
struct saved_value *v; struct saved_value *v;
struct stats *stats; struct stats *stats;
double scale;
if (!strcmp(metric_events[i]->name, "duration_time")) { if (!strcmp(metric_events[i]->name, "duration_time")) {
stats = &walltime_nsecs_stats; stats = &walltime_nsecs_stats;
...@@ -762,16 +762,32 @@ static void generic_metric(struct perf_stat_config *config, ...@@ -762,16 +762,32 @@ static void generic_metric(struct perf_stat_config *config,
if (!metric_events[i]) { if (!metric_events[i]) {
const char *p = metric_expr; const char *p = metric_expr;
if (expr__parse(&ratio, &pctx, &p) == 0) if (expr__parse(&ratio, &pctx, &p) == 0) {
char *unit;
char metric_bf[64];
if (metric_unit && metric_name) {
if (perf_pmu__convert_scale(metric_unit,
&unit, &scale) >= 0) {
ratio *= scale;
}
scnprintf(metric_bf, sizeof(metric_bf),
"%s %s", unit, metric_name);
print_metric(config, ctxp, NULL, "%8.1f",
metric_bf, ratio);
} else {
print_metric(config, ctxp, NULL, "%8.1f", print_metric(config, ctxp, NULL, "%8.1f",
metric_name ? metric_name ?
metric_name : metric_name :
out->force_header ? name : "", out->force_header ? name : "",
ratio); ratio);
else }
} else {
print_metric(config, ctxp, NULL, NULL, print_metric(config, ctxp, NULL, NULL,
out->force_header ? out->force_header ?
(metric_name ? metric_name : name) : "", 0); (metric_name ? metric_name : name) : "", 0);
}
} else } else
print_metric(config, ctxp, NULL, NULL, "", 0); print_metric(config, ctxp, NULL, NULL, "", 0);
...@@ -992,7 +1008,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, ...@@ -992,7 +1008,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
print_metric(config, ctxp, NULL, NULL, name, 0); print_metric(config, ctxp, NULL, NULL, name, 0);
} else if (evsel->metric_expr) { } else if (evsel->metric_expr) {
generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name, generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name,
evsel->metric_name, avg, cpu, out, st); evsel->metric_name, NULL, avg, cpu, out, st);
} else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) { } else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) {
char unit = 'M'; char unit = 'M';
char unit_buf[10]; char unit_buf[10];
...@@ -1021,7 +1037,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, ...@@ -1021,7 +1037,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
out->new_line(config, ctxp); out->new_line(config, ctxp);
generic_metric(config, mexp->metric_expr, mexp->metric_events, generic_metric(config, mexp->metric_expr, mexp->metric_events,
evsel->name, mexp->metric_name, evsel->name, mexp->metric_name,
avg, cpu, out, st); mexp->metric_unit, avg, cpu, out, st);
} }
} }
if (num == 0) if (num == 0)
......
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