Commit e3a6a624 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo-4.12-20170324' of...

Merge tag 'perf-core-for-mingo-4.12-20170324' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

 - Allow suppressing 'uncore_' when specifying PMU events (Andi Kleen)

 - Collapse identically named PMU events in 'perf stat', allow
   not merging it via --no-merge (Andi Kleen)

Fixes:

 - Use more precise 'grep -v' to suppress unwanted 'objdump -dS'
   disassembly output to not ditch line:number lines needed by
   'perf annotate --print-lines' logic (Taeung Song)

Infrastructure changes:

 - SDT (Statically Defined Tracing)/uprobes_events arguments improvements
   (Alexis Berlemont, Ravi Bangoria)

 - Improvements for the handling of JSON described vendor events,
   including having an expression parser to calculate metrics
   from multiple vendor events (Andi Kleen)

 - Update Intel JSON vendor event files (Andi Kleen)

 - Restore error reporting in 'perf probe -d' when none of the events
   requested to be deleted exist. (Kefeng Wang)

 - Bump MAX_CMDLEN in 'perf probe' to match what the kernel accepts
   (Ravi Bangoria)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 267dd0a0 bf874fcf
......@@ -24,6 +24,10 @@ Don't print descriptions.
--long-desc::
Print longer event descriptions.
--details::
Print how named events are resolved internally into perf events, and also
any extra expressions computed by perf stat.
[[EVENT_MODIFIERS]]
EVENT MODIFIERS
......
......@@ -236,6 +236,9 @@ To interpret the results it is usually needed to know on which
CPUs the workload runs on. If needed the CPUs can be forced using
taskset.
--no-merge::
Do not merge results from same PMUs.
EXAMPLES
--------
......
#include <string.h>
#include "../../perf.h"
#include "../../util/util.h"
#include "../../util/perf_regs.h"
const struct sample_reg sample_reg_masks[] = {
......@@ -26,3 +29,103 @@ const struct sample_reg sample_reg_masks[] = {
#endif
SMPL_REG_END
};
struct sdt_name_reg {
const char *sdt_name;
const char *uprobe_name;
};
#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m}
#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL}
static const struct sdt_name_reg sdt_reg_renamings[] = {
SDT_NAME_REG(eax, ax),
SDT_NAME_REG(rax, ax),
SDT_NAME_REG(ebx, bx),
SDT_NAME_REG(rbx, bx),
SDT_NAME_REG(ecx, cx),
SDT_NAME_REG(rcx, cx),
SDT_NAME_REG(edx, dx),
SDT_NAME_REG(rdx, dx),
SDT_NAME_REG(esi, si),
SDT_NAME_REG(rsi, si),
SDT_NAME_REG(sil, si),
SDT_NAME_REG(edi, di),
SDT_NAME_REG(rdi, di),
SDT_NAME_REG(dil, di),
SDT_NAME_REG(ebp, bp),
SDT_NAME_REG(rbp, bp),
SDT_NAME_REG(bpl, bp),
SDT_NAME_REG(rsp, sp),
SDT_NAME_REG(esp, sp),
SDT_NAME_REG(spl, sp),
/* rNN registers */
SDT_NAME_REG(r8b, r8),
SDT_NAME_REG(r8w, r8),
SDT_NAME_REG(r8d, r8),
SDT_NAME_REG(r9b, r9),
SDT_NAME_REG(r9w, r9),
SDT_NAME_REG(r9d, r9),
SDT_NAME_REG(r10b, r10),
SDT_NAME_REG(r10w, r10),
SDT_NAME_REG(r10d, r10),
SDT_NAME_REG(r11b, r11),
SDT_NAME_REG(r11w, r11),
SDT_NAME_REG(r11d, r11),
SDT_NAME_REG(r12b, r12),
SDT_NAME_REG(r12w, r12),
SDT_NAME_REG(r12d, r12),
SDT_NAME_REG(r13b, r13),
SDT_NAME_REG(r13w, r13),
SDT_NAME_REG(r13d, r13),
SDT_NAME_REG(r14b, r14),
SDT_NAME_REG(r14w, r14),
SDT_NAME_REG(r14d, r14),
SDT_NAME_REG(r15b, r15),
SDT_NAME_REG(r15w, r15),
SDT_NAME_REG(r15d, r15),
SDT_NAME_REG_END,
};
int sdt_rename_register(char **pdesc, char *old_name)
{
const struct sdt_name_reg *rnames = sdt_reg_renamings;
char *new_desc, *old_desc = *pdesc;
size_t prefix_len, sdt_len, uprobe_len, old_desc_len, offset;
int ret = -1;
while (ret != 0 && rnames->sdt_name != NULL) {
sdt_len = strlen(rnames->sdt_name);
ret = strncmp(old_name, rnames->sdt_name, sdt_len);
rnames += !!ret;
}
if (rnames->sdt_name == NULL)
return 0;
sdt_len = strlen(rnames->sdt_name);
uprobe_len = strlen(rnames->uprobe_name);
old_desc_len = strlen(old_desc) + 1;
new_desc = zalloc(old_desc_len + uprobe_len - sdt_len);
if (new_desc == NULL)
return -1;
/* Copy the chars before the register name (at least '%') */
prefix_len = old_name - old_desc;
memcpy(new_desc, old_desc, prefix_len);
/* Copy the new register name */
memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len);
/* Copy the chars after the register name (if need be) */
offset = prefix_len + sdt_len;
if (offset < old_desc_len)
memcpy(new_desc + prefix_len + uprobe_len,
old_desc + offset, old_desc_len - offset);
free(old_desc);
*pdesc = new_desc;
return 0;
}
......@@ -18,6 +18,7 @@
#include <subcmd/parse-options.h>
static bool desc_flag = true;
static bool details_flag;
int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
{
......@@ -30,6 +31,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
"Print extra event descriptions. --no-desc to not print."),
OPT_BOOLEAN('v', "long-desc", &long_desc_flag,
"Print longer event descriptions."),
OPT_BOOLEAN(0, "details", &details_flag,
"Print information on the perf event names and expressions used internally by events."),
OPT_INCR(0, "debug", &verbose,
"Enable debugging output"),
OPT_END()
......@@ -50,7 +53,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
printf("\nList of pre-defined events (to be used in -e):\n\n");
if (argc == 0) {
print_events(NULL, raw_dump, !desc_flag, long_desc_flag);
print_events(NULL, raw_dump, !desc_flag, long_desc_flag,
details_flag);
return 0;
}
......@@ -72,7 +76,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
print_hwcache_events(NULL, raw_dump);
else if (strcmp(argv[i], "pmu") == 0)
print_pmu_events(NULL, raw_dump, !desc_flag,
long_desc_flag);
long_desc_flag, details_flag);
else if (strcmp(argv[i], "sdt") == 0)
print_sdt_events(NULL, NULL, raw_dump);
else if ((sep = strchr(argv[i], ':')) != NULL) {
......@@ -80,7 +84,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
if (sep == NULL) {
print_events(argv[i], raw_dump, !desc_flag,
long_desc_flag);
long_desc_flag,
details_flag);
continue;
}
sep_idx = sep - argv[i];
......@@ -103,7 +108,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
print_hwcache_events(s, raw_dump);
print_pmu_events(s, raw_dump, !desc_flag,
long_desc_flag);
long_desc_flag,
details_flag);
print_tracepoint_events(NULL, s, raw_dump);
print_sdt_events(NULL, s, raw_dump);
free(s);
......
......@@ -442,8 +442,8 @@ static int perf_del_probe_events(struct strfilter *filter)
}
if (ret == -ENOENT && ret2 == -ENOENT)
pr_debug("\"%s\" does not hit any event.\n", str);
/* Note that this is silently ignored */
pr_warning("\"%s\" does not hit any event.\n", str);
else
ret = 0;
error:
......
......@@ -140,6 +140,7 @@ static unsigned int unit_width = 4; /* strlen("unit") */
static bool forever = false;
static bool metric_only = false;
static bool force_metric_only = false;
static bool no_merge = false;
static struct timespec ref_time;
static struct cpu_map *aggr_map;
static aggr_get_id_t aggr_get_id;
......@@ -1144,6 +1145,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
out.print_metric = pm;
out.new_line = nl;
out.ctx = &os;
out.force_header = false;
if (csv_output && !metric_only) {
print_noise(counter, noise);
......@@ -1182,11 +1184,81 @@ static void aggr_update_shadow(void)
}
}
static void collect_all_aliases(struct perf_evsel *counter,
void (*cb)(struct perf_evsel *counter, void *data,
bool first),
void *data)
{
struct perf_evsel *alias;
alias = list_prepare_entry(counter, &(evsel_list->entries), node);
list_for_each_entry_continue (alias, &evsel_list->entries, node) {
if (strcmp(perf_evsel__name(alias), perf_evsel__name(counter)) ||
alias->scale != counter->scale ||
alias->cgrp != counter->cgrp ||
strcmp(alias->unit, counter->unit) ||
nsec_counter(alias) != nsec_counter(counter))
break;
alias->merged_stat = true;
cb(alias, data, false);
}
}
static bool collect_data(struct perf_evsel *counter,
void (*cb)(struct perf_evsel *counter, void *data,
bool first),
void *data)
{
if (counter->merged_stat)
return false;
cb(counter, data, true);
if (!no_merge)
collect_all_aliases(counter, cb, data);
return true;
}
struct aggr_data {
u64 ena, run, val;
int id;
int nr;
int cpu;
};
static void aggr_cb(struct perf_evsel *counter, void *data, bool first)
{
struct aggr_data *ad = data;
int cpu, s2;
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
struct perf_counts_values *counts;
s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
if (s2 != ad->id)
continue;
if (first)
ad->nr++;
counts = perf_counts(counter->counts, cpu, 0);
/*
* When any result is bad, make them all to give
* consistent output in interval mode.
*/
if (counts->ena == 0 || counts->run == 0 ||
counter->counts->scaled == -1) {
ad->ena = 0;
ad->run = 0;
break;
}
ad->val += counts->val;
ad->ena += counts->ena;
ad->run += counts->run;
}
}
static void print_aggr(char *prefix)
{
FILE *output = stat_config.output;
struct perf_evsel *counter;
int cpu, s, s2, id, nr;
int s, id, nr;
double uval;
u64 ena, run, val;
bool first;
......@@ -1201,23 +1273,21 @@ static void print_aggr(char *prefix)
* Without each counter has its own line.
*/
for (s = 0; s < aggr_map->nr; s++) {
struct aggr_data ad;
if (prefix && metric_only)
fprintf(output, "%s", prefix);
id = aggr_map->map[s];
ad.id = id = aggr_map->map[s];
first = true;
evlist__for_each_entry(evsel_list, counter) {
val = ena = run = 0;
nr = 0;
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
if (s2 != id)
ad.val = ad.ena = ad.run = 0;
ad.nr = 0;
if (!collect_data(counter, aggr_cb, &ad))
continue;
val += perf_counts(counter->counts, cpu, 0)->val;
ena += perf_counts(counter->counts, cpu, 0)->ena;
run += perf_counts(counter->counts, cpu, 0)->run;
nr++;
}
nr = ad.nr;
ena = ad.ena;
run = ad.run;
val = ad.val;
if (first && metric_only) {
first = false;
aggr_printout(counter, id, nr);
......@@ -1261,6 +1331,21 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
}
}
struct caggr_data {
double avg, avg_enabled, avg_running;
};
static void counter_aggr_cb(struct perf_evsel *counter, void *data,
bool first __maybe_unused)
{
struct caggr_data *cd = data;
struct perf_stat_evsel *ps = counter->priv;
cd->avg += avg_stats(&ps->res_stats[0]);
cd->avg_enabled += avg_stats(&ps->res_stats[1]);
cd->avg_running += avg_stats(&ps->res_stats[2]);
}
/*
* Print out the results of a single counter:
* aggregated counts in system-wide mode
......@@ -1268,23 +1353,31 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
{
FILE *output = stat_config.output;
struct perf_stat_evsel *ps = counter->priv;
double avg = avg_stats(&ps->res_stats[0]);
double uval;
double avg_enabled, avg_running;
struct caggr_data cd = { .avg = 0.0 };
avg_enabled = avg_stats(&ps->res_stats[1]);
avg_running = avg_stats(&ps->res_stats[2]);
if (!collect_data(counter, counter_aggr_cb, &cd))
return;
if (prefix && !metric_only)
fprintf(output, "%s", prefix);
uval = avg * counter->scale;
printout(-1, 0, counter, uval, prefix, avg_running, avg_enabled, avg);
uval = cd.avg * counter->scale;
printout(-1, 0, counter, uval, prefix, cd.avg_running, cd.avg_enabled, cd.avg);
if (!metric_only)
fprintf(output, "\n");
}
static void counter_cb(struct perf_evsel *counter, void *data,
bool first __maybe_unused)
{
struct aggr_data *ad = data;
ad->val += perf_counts(counter->counts, ad->cpu, 0)->val;
ad->ena += perf_counts(counter->counts, ad->cpu, 0)->ena;
ad->run += perf_counts(counter->counts, ad->cpu, 0)->run;
}
/*
* Print out the results of a single counter:
* does not use aggregated count in system-wide
......@@ -1297,9 +1390,13 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
int cpu;
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
val = perf_counts(counter->counts, cpu, 0)->val;
ena = perf_counts(counter->counts, cpu, 0)->ena;
run = perf_counts(counter->counts, cpu, 0)->run;
struct aggr_data ad = { .cpu = cpu };
if (!collect_data(counter, counter_cb, &ad))
return;
val = ad.val;
ena = ad.ena;
run = ad.run;
if (prefix)
fprintf(output, "%s", prefix);
......@@ -1384,6 +1481,7 @@ static void print_metric_headers(const char *prefix, bool no_indent)
out.ctx = &os;
out.print_metric = print_metric_header;
out.new_line = new_line_metric;
out.force_header = true;
os.evsel = counter;
perf_stat__print_shadow_stats(counter, 0,
0,
......@@ -1644,6 +1742,7 @@ static const struct option stat_options[] = {
"list of cpus to monitor in system-wide"),
OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
"disable CPU count aggregation", AGGR_NONE),
OPT_BOOLEAN(0, "no-merge", &no_merge, "Do not merge identical named events"),
OPT_STRING('x', "field-separator", &csv_sep, "separator",
"print counts with custom separator"),
OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
......@@ -2401,6 +2500,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
(const char **) stat_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
perf_stat__collect_metric_expr(evsel_list);
perf_stat__init_shadow_stats();
if (csv_sep) {
......
[
{
"BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
"BriefDescription": "Uncore cache clock ticks",
"Counter": "0,1,2,3",
"EventName": "UNC_C_CLOCKTICKS",
"PerPkg": "1",
"Unit": "CBO"
},
{
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch)",
"Counter": "0,1,2,3",
"EventCode": "0x34",
"EventName": "UNC_C_LLC_LOOKUP.ANY",
......@@ -18,7 +18,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
"BriefDescription": "M line evictions from LLC (writebacks to memory)",
"Counter": "0,1,2,3",
"EventCode": "0x37",
"EventName": "UNC_C_LLC_VICTIMS.M_STATE",
......@@ -212,7 +212,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
"BriefDescription": "read requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS",
......@@ -221,7 +221,7 @@
"Unit": "HA"
},
{
"BriefDescription": "read requests to local home agent. Derived from unc_h_requests.reads_local",
"BriefDescription": "read requests to local home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS_LOCAL",
......@@ -230,7 +230,7 @@
"Unit": "HA"
},
{
"BriefDescription": "read requests to remote home agent. Derived from unc_h_requests.reads_remote",
"BriefDescription": "read requests to remote home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS_REMOTE",
......@@ -239,7 +239,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
"BriefDescription": "write requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES",
......@@ -248,7 +248,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to local home agent. Derived from unc_h_requests.writes_local",
"BriefDescription": "write requests to local home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES_LOCAL",
......@@ -257,7 +257,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to remote home agent. Derived from unc_h_requests.writes_remote",
"BriefDescription": "write requests to remote home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES_REMOTE",
......@@ -266,7 +266,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously). Derived from unc_h_snoop_resp.rspcnflct",
"BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously)",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPCNFLCT",
......@@ -275,7 +275,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
"BriefDescription": "M line forwarded from remote cache along with writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
......@@ -285,7 +285,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
"BriefDescription": "M line forwarded from remote cache with no writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
......@@ -295,7 +295,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
"BriefDescription": "Shared line response from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPS",
......@@ -305,7 +305,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
"BriefDescription": "Shared line forwarded from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
......
......@@ -3,7 +3,7 @@
"BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.RD",
"EventName": "LLC_MISSES.MEM_READ",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0x3",
......@@ -13,48 +13,44 @@
"BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.WR",
"EventName": "LLC_MISSES.MEM_WRITE",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0xC",
"Unit": "iMC"
},
{
"BriefDescription": "Memory controller clock ticks. Derived from unc_m_clockticks",
"Counter": "0,1,2,3",
"EventName": "UNC_M_CLOCKTICKS",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode",
"Counter": "0,1,2,3",
"EventCode": "0x85",
"EventName": "UNC_M_POWER_CHANNEL_PPD",
"MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_channel_ppd %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
"BriefDescription": "Cycles all ranks are in critical thermal throttle",
"Counter": "0,1,2,3",
"EventCode": "0x86",
"EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
"MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_critical_throttle_cycles %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
"BriefDescription": "Cycles Memory is in self refresh power mode",
"Counter": "0,1,2,3",
"EventCode": "0x43",
"EventName": "UNC_M_POWER_SELF_REFRESH",
"MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_self_refresh %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charges due to page misses. Derived from unc_m_pre_count.page_miss",
"BriefDescription": "Pre-charges due to page misses",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
......@@ -63,7 +59,7 @@
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charge for reads. Derived from unc_m_pre_count.rd",
"BriefDescription": "Pre-charge for reads",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.RD",
......@@ -72,7 +68,7 @@
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charge for writes. Derived from unc_m_pre_count.wr",
"BriefDescription": "Pre-charge for writes",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.WR",
......
[
{
"BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
"BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events",
"Counter": "0,1,2,3",
"EventName": "UNC_P_CLOCKTICKS",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C0 and C1. Derived from unc_p_power_state_occupancy.cores_c0",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C0. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
"Filter": "occ_sel=1",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c0 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C3. Derived from unc_p_power_state_occupancy.cores_c3",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C3. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
"Filter": "occ_sel=2",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c3 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C6 and C7. Derived from unc_p_power_state_occupancy.cores_c6",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C6. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events ",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
"Filter": "occ_sel=3",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c6 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "External Prochot. Derived from unc_p_prochot_external_cycles",
"BriefDescription": "Counts the number of cycles that we are in external PROCHOT mode. This mode is triggered when a sensor off the die determines that something off-die (like DRAM) is too hot and must throttle to avoid damaging the chip",
"Counter": "0,1,2,3",
"EventCode": "0xA",
"EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
"MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "prochot_external_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Thermal Strongest Upper Limit Cycles. Derived from unc_p_freq_max_limit_thermal_cycles",
"BriefDescription": "Counts the number of cycles when temperature is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_limit_thermal_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "OS Strongest Upper Limit Cycles. Derived from unc_p_freq_max_os_cycles",
"BriefDescription": "Counts the number of cycles when the OS is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x6",
"EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_os_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Power Strongest Upper Limit Cycles. Derived from unc_p_freq_max_power_cycles",
"BriefDescription": "Counts the number of cycles when power is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x5",
"EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_power_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Cycles spent changing Frequency. Derived from unc_p_freq_trans_cycles",
"BriefDescription": "Counts the number of cycles when current is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x74",
"EventName": "UNC_P_FREQ_TRANS_CYCLES",
"MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_trans_cycles %",
"PerPkg": "1",
"Unit": "PCU"
}
......
[
{
"BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
"BriefDescription": "Uncore cache clock ticks",
"Counter": "0,1,2,3",
"EventName": "UNC_C_CLOCKTICKS",
"PerPkg": "1",
"Unit": "CBO"
},
{
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch)",
"Counter": "0,1,2,3",
"EventCode": "0x34",
"EventName": "UNC_C_LLC_LOOKUP.ANY",
......@@ -18,7 +18,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
"BriefDescription": "M line evictions from LLC (writebacks to memory)",
"Counter": "0,1,2,3",
"EventCode": "0x37",
"EventName": "UNC_C_LLC_VICTIMS.M_STATE",
......@@ -212,7 +212,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
"BriefDescription": "read requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS",
......@@ -221,7 +221,7 @@
"Unit": "HA"
},
{
"BriefDescription": "read requests to local home agent. Derived from unc_h_requests.reads_local",
"BriefDescription": "read requests to local home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS_LOCAL",
......@@ -230,7 +230,7 @@
"Unit": "HA"
},
{
"BriefDescription": "read requests to remote home agent. Derived from unc_h_requests.reads_remote",
"BriefDescription": "read requests to remote home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS_REMOTE",
......@@ -239,7 +239,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
"BriefDescription": "write requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES",
......@@ -248,7 +248,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to local home agent. Derived from unc_h_requests.writes_local",
"BriefDescription": "write requests to local home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES_LOCAL",
......@@ -257,7 +257,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to remote home agent. Derived from unc_h_requests.writes_remote",
"BriefDescription": "write requests to remote home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES_REMOTE",
......@@ -266,7 +266,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously). Derived from unc_h_snoop_resp.rspcnflct",
"BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously)",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPCNFLCT",
......@@ -275,7 +275,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
"BriefDescription": "M line forwarded from remote cache along with writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
......@@ -285,7 +285,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
"BriefDescription": "M line forwarded from remote cache with no writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
......@@ -295,7 +295,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
"BriefDescription": "Shared line response from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPS",
......@@ -305,7 +305,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
"BriefDescription": "Shared line forwarded from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
......
[
{
"BriefDescription": "QPI clock ticks. Derived from unc_q_clockticks",
"BriefDescription": "QPI clock ticks",
"Counter": "0,1,2,3",
"EventCode": "0x14",
"EventName": "UNC_Q_CLOCKTICKS",
......@@ -10,7 +10,7 @@
{
"BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.DATA",
"EventName": "QPI_DATA_BANDWIDTH_TX",
"PerPkg": "1",
"ScaleUnit": "8Bytes",
"UMask": "0x2",
......@@ -19,7 +19,7 @@
{
"BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
"EventName": "QPI_CTL_BANDWIDTH_TX",
"PerPkg": "1",
"ScaleUnit": "8Bytes",
"UMask": "0x4",
......
......@@ -3,7 +3,7 @@
"BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.RD",
"EventName": "LLC_MISSES.MEM_READ",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0x3",
......@@ -13,48 +13,51 @@
"BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.WR",
"EventName": "LLC_MISSES.MEM_WRITE",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0xC",
"Unit": "iMC"
},
{
"BriefDescription": "Memory controller clock ticks. Derived from unc_m_clockticks",
"BriefDescription": "Memory controller clock ticks",
"Counter": "0,1,2,3",
"EventName": "UNC_M_CLOCKTICKS",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode",
"Counter": "0,1,2,3",
"EventCode": "0x85",
"EventName": "UNC_M_POWER_CHANNEL_PPD",
"MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_channel_ppd %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
"BriefDescription": "Cycles all ranks are in critical thermal throttle",
"Counter": "0,1,2,3",
"EventCode": "0x86",
"EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
"MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_critical_throttle_cycles %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
"BriefDescription": "Cycles Memory is in self refresh power mode",
"Counter": "0,1,2,3",
"EventCode": "0x43",
"EventName": "UNC_M_POWER_SELF_REFRESH",
"MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_self_refresh %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charges due to page misses. Derived from unc_m_pre_count.page_miss",
"BriefDescription": "Pre-charges due to page misses",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
......@@ -63,7 +66,7 @@
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charge for reads. Derived from unc_m_pre_count.rd",
"BriefDescription": "Pre-charge for reads",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.RD",
......@@ -72,7 +75,7 @@
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charge for writes. Derived from unc_m_pre_count.wr",
"BriefDescription": "Pre-charge for writes",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.WR",
......
[
{
"BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
"BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events",
"Counter": "0,1,2,3",
"EventName": "UNC_P_CLOCKTICKS",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C0 and C1. Derived from unc_p_power_state_occupancy.cores_c0",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C0. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
"Filter": "occ_sel=1",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c0 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C3. Derived from unc_p_power_state_occupancy.cores_c3",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C3. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
"Filter": "occ_sel=2",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c3 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C6 and C7. Derived from unc_p_power_state_occupancy.cores_c6",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C6. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events ",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
"Filter": "occ_sel=3",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c6 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "External Prochot. Derived from unc_p_prochot_external_cycles",
"BriefDescription": "Counts the number of cycles that we are in external PROCHOT mode. This mode is triggered when a sensor off the die determines that something off-die (like DRAM) is too hot and must throttle to avoid damaging the chip",
"Counter": "0,1,2,3",
"EventCode": "0xA",
"EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
"MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "prochot_external_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Thermal Strongest Upper Limit Cycles. Derived from unc_p_freq_max_limit_thermal_cycles",
"BriefDescription": "Counts the number of cycles when temperature is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_limit_thermal_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "OS Strongest Upper Limit Cycles. Derived from unc_p_freq_max_os_cycles",
"BriefDescription": "Counts the number of cycles when the OS is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x6",
"EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_os_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Power Strongest Upper Limit Cycles. Derived from unc_p_freq_max_power_cycles",
"BriefDescription": "Counts the number of cycles when power is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x5",
"EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_power_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Cycles spent changing Frequency. Derived from unc_p_freq_trans_cycles",
"BriefDescription": "Counts the number of cycles when current is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x74",
"EventName": "UNC_P_FREQ_TRANS_CYCLES",
"MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_trans_cycles %",
"PerPkg": "1",
"Unit": "PCU"
}
......
[
{
"BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
"BriefDescription": "Uncore cache clock ticks",
"Counter": "0,1,2,3",
"EventName": "UNC_C_CLOCKTICKS",
"PerPkg": "1",
"Unit": "CBO"
},
{
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch)",
"Counter": "0,1,2,3",
"EventCode": "0x34",
"EventName": "UNC_C_LLC_LOOKUP.ANY",
......@@ -18,7 +18,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
"BriefDescription": "M line evictions from LLC (writebacks to memory)",
"Counter": "0,1,2,3",
"EventCode": "0x37",
"EventName": "UNC_C_LLC_VICTIMS.M_STATE",
......@@ -212,7 +212,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
"BriefDescription": "read requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS",
......@@ -221,7 +221,7 @@
"Unit": "HA"
},
{
"BriefDescription": "read requests to local home agent. Derived from unc_h_requests.reads_local",
"BriefDescription": "read requests to local home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS_LOCAL",
......@@ -230,7 +230,7 @@
"Unit": "HA"
},
{
"BriefDescription": "read requests to remote home agent. Derived from unc_h_requests.reads_remote",
"BriefDescription": "read requests to remote home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS_REMOTE",
......@@ -239,7 +239,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
"BriefDescription": "write requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES",
......@@ -248,7 +248,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to local home agent. Derived from unc_h_requests.writes_local",
"BriefDescription": "write requests to local home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES_LOCAL",
......@@ -257,7 +257,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to remote home agent. Derived from unc_h_requests.writes_remote",
"BriefDescription": "write requests to remote home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES_REMOTE",
......@@ -266,7 +266,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously). Derived from unc_h_snoop_resp.rspcnflct",
"BriefDescription": "Conflict requests (requests for same address from multiple agents simultaneously)",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPCNFLCT",
......@@ -275,7 +275,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
"BriefDescription": "M line forwarded from remote cache along with writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
......@@ -285,7 +285,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
"BriefDescription": "M line forwarded from remote cache with no writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
......@@ -295,7 +295,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
"BriefDescription": "Shared line response from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPS",
......@@ -305,7 +305,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
"BriefDescription": "Shared line forwarded from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
......
[
{
"BriefDescription": "QPI clock ticks. Derived from unc_q_clockticks",
"BriefDescription": "QPI clock ticks",
"Counter": "0,1,2,3",
"EventCode": "0x14",
"EventName": "UNC_Q_CLOCKTICKS",
......@@ -10,7 +10,7 @@
{
"BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.DATA",
"EventName": "QPI_DATA_BANDWIDTH_TX",
"PerPkg": "1",
"ScaleUnit": "8Bytes",
"UMask": "0x2",
......@@ -19,7 +19,7 @@
{
"BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
"EventName": "QPI_CTL_BANDWIDTH_TX",
"PerPkg": "1",
"ScaleUnit": "8Bytes",
"UMask": "0x4",
......
......@@ -3,7 +3,7 @@
"BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.RD",
"EventName": "LLC_MISSES.MEM_READ",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0x3",
......@@ -13,48 +13,51 @@
"BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.WR",
"EventName": "LLC_MISSES.MEM_WRITE",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0xC",
"Unit": "iMC"
},
{
"BriefDescription": "Memory controller clock ticks. Derived from unc_m_clockticks",
"BriefDescription": "Memory controller clock ticks",
"Counter": "0,1,2,3",
"EventName": "UNC_M_CLOCKTICKS",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode",
"Counter": "0,1,2,3",
"EventCode": "0x85",
"EventName": "UNC_M_POWER_CHANNEL_PPD",
"MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_channel_ppd %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
"BriefDescription": "Cycles all ranks are in critical thermal throttle",
"Counter": "0,1,2,3",
"EventCode": "0x86",
"EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
"MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_critical_throttle_cycles %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
"BriefDescription": "Cycles Memory is in self refresh power mode",
"Counter": "0,1,2,3",
"EventCode": "0x43",
"EventName": "UNC_M_POWER_SELF_REFRESH",
"MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_self_refresh %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charges due to page misses. Derived from unc_m_pre_count.page_miss",
"BriefDescription": "Pre-charges due to page misses",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
......@@ -63,7 +66,7 @@
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charge for reads. Derived from unc_m_pre_count.rd",
"BriefDescription": "Pre-charge for reads",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.RD",
......@@ -72,7 +75,7 @@
"Unit": "iMC"
},
{
"BriefDescription": "Pre-charge for writes. Derived from unc_m_pre_count.wr",
"BriefDescription": "Pre-charge for writes",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.WR",
......
[
{
"BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events. Derived from unc_p_clockticks",
"BriefDescription": "PCU clock ticks. Use to get percentages of PCU cycles events",
"Counter": "0,1,2,3",
"EventName": "UNC_P_CLOCKTICKS",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C0 and C1. Derived from unc_p_power_state_occupancy.cores_c0",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C0. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C0",
"Filter": "occ_sel=1",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C0 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c0 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C3. Derived from unc_p_power_state_occupancy.cores_c3",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C3. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events and occupancy triggering to capture other details",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C3",
"Filter": "occ_sel=2",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C3 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c3 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "C6 and C7. Derived from unc_p_power_state_occupancy.cores_c6",
"BriefDescription": "This is an occupancy event that tracks the number of cores that are in C6. It can be used by itself to get the average number of cores in C0, with threshholding to generate histograms, or with other PCU events ",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_P_POWER_STATE_OCCUPANCY.CORES_C6",
"Filter": "occ_sel=3",
"MetricExpr": "(UNC_P_POWER_STATE_OCCUPANCY.CORES_C6 / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "power_state_occupancy.cores_c6 %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "External Prochot. Derived from unc_p_prochot_external_cycles",
"BriefDescription": "Counts the number of cycles that we are in external PROCHOT mode. This mode is triggered when a sensor off the die determines that something off-die (like DRAM) is too hot and must throttle to avoid damaging the chip",
"Counter": "0,1,2,3",
"EventCode": "0xA",
"EventName": "UNC_P_PROCHOT_EXTERNAL_CYCLES",
"MetricExpr": "(UNC_P_PROCHOT_EXTERNAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "prochot_external_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Thermal Strongest Upper Limit Cycles. Derived from unc_p_freq_max_limit_thermal_cycles",
"BriefDescription": "Counts the number of cycles when temperature is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_LIMIT_THERMAL_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_limit_thermal_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "OS Strongest Upper Limit Cycles. Derived from unc_p_freq_max_os_cycles",
"BriefDescription": "Counts the number of cycles when the OS is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x6",
"EventName": "UNC_P_FREQ_MAX_OS_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_OS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_os_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Power Strongest Upper Limit Cycles. Derived from unc_p_freq_max_power_cycles",
"BriefDescription": "Counts the number of cycles when power is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x5",
"EventName": "UNC_P_FREQ_MAX_POWER_CYCLES",
"MetricExpr": "(UNC_P_FREQ_MAX_POWER_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_max_power_cycles %",
"PerPkg": "1",
"Unit": "PCU"
},
{
"BriefDescription": "Cycles spent changing Frequency. Derived from unc_p_freq_trans_cycles",
"BriefDescription": "Counts the number of cycles when current is the upper limit on frequency",
"Counter": "0,1,2,3",
"EventCode": "0x74",
"EventName": "UNC_P_FREQ_TRANS_CYCLES",
"MetricExpr": "(UNC_P_FREQ_TRANS_CYCLES / UNC_P_CLOCKTICKS) * 100.",
"MetricName": "freq_trans_cycles %",
"PerPkg": "1",
"Unit": "PCU"
}
......
[
{
"BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
"BriefDescription": "Uncore cache clock ticks",
"Counter": "0,1,2,3",
"EventName": "UNC_C_CLOCKTICKS",
"PerPkg": "1",
"Unit": "CBO"
},
{
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch)",
"Counter": "0,1",
"EventCode": "0x34",
"EventName": "UNC_C_LLC_LOOKUP.ANY",
......@@ -18,7 +18,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
"BriefDescription": "M line evictions from LLC (writebacks to memory)",
"Counter": "0,1",
"EventCode": "0x37",
"EventName": "UNC_C_LLC_VICTIMS.M_STATE",
......@@ -237,7 +237,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "Occupancy for all LLC misses that are addressed to local memory. Derived from unc_c_tor_occupancy.miss_local",
"BriefDescription": "Occupancy for all LLC misses that are addressed to local memory",
"EventCode": "0x36",
"EventName": "UNC_C_TOR_OCCUPANCY.MISS_LOCAL",
"PerPkg": "1",
......@@ -254,7 +254,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "Occupancy for all LLC misses that are addressed to remote memory. Derived from unc_c_tor_occupancy.miss_remote",
"BriefDescription": "Occupancy for all LLC misses that are addressed to remote memory",
"EventCode": "0x36",
"EventName": "UNC_C_TOR_OCCUPANCY.MISS_REMOTE",
"PerPkg": "1",
......@@ -262,7 +262,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "Read requests to home agent. Derived from unc_h_requests.reads",
"BriefDescription": "Read requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS",
......@@ -271,7 +271,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Write requests to home agent. Derived from unc_h_requests.writes",
"BriefDescription": "Write requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES",
......@@ -280,7 +280,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache along with writeback to memory. Derived from unc_h_snoop_resp.rsp_fwd_wb",
"BriefDescription": "M line forwarded from remote cache along with writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSP_FWD_WB",
......@@ -290,7 +290,7 @@
"Unit": "HA"
},
{
"BriefDescription": "M line forwarded from remote cache with no writeback to memory. Derived from unc_h_snoop_resp.rspifwd",
"BriefDescription": "M line forwarded from remote cache with no writeback to memory",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPIFWD",
......@@ -300,7 +300,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line response from remote cache. Derived from unc_h_snoop_resp.rsps",
"BriefDescription": "Shared line response from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPS",
......@@ -310,7 +310,7 @@
"Unit": "HA"
},
{
"BriefDescription": "Shared line forwarded from remote cache. Derived from unc_h_snoop_resp.rspsfwd",
"BriefDescription": "Shared line forwarded from remote cache",
"Counter": "0,1,2,3",
"EventCode": "0x21",
"EventName": "UNC_H_SNOOP_RESP.RSPSFWD",
......
[
{
"BriefDescription": "QPI clock ticks. Use to get percentages for QPI cycles events. Derived from unc_q_clockticks",
"BriefDescription": "QPI clock ticks. Use to get percentages for QPI cycles events",
"Counter": "0,1,2,3",
"EventCode": "0x14",
"EventName": "UNC_Q_CLOCKTICKS",
......@@ -8,25 +8,27 @@
"Unit": "QPI LL"
},
{
"BriefDescription": "Cycles where receiving QPI link is in half-width mode. Derived from unc_q_rxl0p_power_cycles",
"BriefDescription": "Cycles where receiving QPI link is in half-width mode",
"Counter": "0,1,2,3",
"EventCode": "0x10",
"EventName": "UNC_Q_RxL0P_POWER_CYCLES",
"MetricExpr": "(UNC_Q_RxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
"MetricName": "rxl0p_power_cycles %",
"PerPkg": "1",
"Unit": "QPI LL"
},
{
"BriefDescription": "Cycles where transmitting QPI link is in half-width mode. Derived from unc_q_txl0p_power_cycles",
"BriefDescription": "Cycles where transmitting QPI link is in half-width mode",
"Counter": "0,1,2,3",
"EventCode": "0xd",
"EventName": "UNC_Q_TxL0P_POWER_CYCLES",
"MetricExpr": "(UNC_Q_TxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
"MetricName": "txl0p_power_cycles %",
"PerPkg": "1",
"Unit": "QPI LL"
},
{
"BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
"BriefDescription": "Number of data flits transmitted ",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.DATA",
"PerPkg": "1",
......@@ -35,7 +37,7 @@
"Unit": "QPI LL"
},
{
"BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
"BriefDescription": "Number of non data (control) flits transmitted ",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
"PerPkg": "1",
......
[
{
"BriefDescription": "Memory page activates for reads and writes. Derived from unc_m_act_count.rd",
"BriefDescription": "Memory page activates for reads and writes",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_M_ACT_COUNT.RD",
......@@ -13,7 +13,7 @@
"BriefDescription": "Read requests to memory controller. Derived from unc_m_cas_count.rd",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.RD",
"EventName": "LLC_MISSES.MEM_READ",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0x3",
......@@ -23,48 +23,51 @@
"BriefDescription": "Write requests to memory controller. Derived from unc_m_cas_count.wr",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.WR",
"EventName": "LLC_MISSES.MEM_WRITE",
"PerPkg": "1",
"ScaleUnit": "64Bytes",
"UMask": "0xC",
"Unit": "iMC"
},
{
"BriefDescription": "Memory controller clock ticks. Use to generate percentages for memory controller CYCLES events. Derived from unc_m_clockticks",
"BriefDescription": "Memory controller clock ticks. Use to generate percentages for memory controller CYCLES events",
"Counter": "0,1,2,3",
"EventName": "UNC_M_CLOCKTICKS",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode",
"Counter": "0,1,2,3",
"EventCode": "0x85",
"EventName": "UNC_M_POWER_CHANNEL_PPD",
"MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_channel_ppd %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
"BriefDescription": "Cycles all ranks are in critical thermal throttle",
"Counter": "0,1,2,3",
"EventCode": "0x86",
"EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
"MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_critical_throttle_cycles %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
"BriefDescription": "Cycles Memory is in self refresh power mode",
"Counter": "0,1,2,3",
"EventCode": "0x43",
"EventName": "UNC_M_POWER_SELF_REFRESH",
"MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_self_refresh %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Memory page conflicts. Derived from unc_m_pre_count.page_miss",
"BriefDescription": "Memory page conflicts",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
......
[
{
"BriefDescription": "Uncore cache clock ticks. Derived from unc_c_clockticks",
"BriefDescription": "Uncore cache clock ticks",
"Counter": "0,1,2,3",
"EventName": "UNC_C_CLOCKTICKS",
"PerPkg": "1",
"Unit": "CBO"
},
{
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch). Derived from unc_c_llc_lookup.any",
"BriefDescription": "All LLC Misses (code+ data rd + data wr - including demand and prefetch)",
"Counter": "0,1",
"EventCode": "0x34",
"EventName": "UNC_C_LLC_LOOKUP.ANY",
......@@ -18,7 +18,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "M line evictions from LLC (writebacks to memory). Derived from unc_c_llc_victims.m_state",
"BriefDescription": "M line evictions from LLC (writebacks to memory)",
"Counter": "0,1",
"EventCode": "0x37",
"EventName": "UNC_C_LLC_VICTIMS.M_STATE",
......@@ -171,11 +171,12 @@
"Unit": "CBO"
},
{
"BriefDescription": "Occupancy counter for all LLC misses; we divide this by UNC_C_CLOCKTICKS to get average Q depth. Derived from unc_c_tor_occupancy.miss_all",
"BriefDescription": "Occupancy counter for all LLC misses; we divide this by UNC_C_CLOCKTICKS to get average Q depth",
"EventCode": "0x36",
"EventName": "UNC_C_TOR_OCCUPANCY.MISS_ALL",
"Filter": "filter_opc=0x182",
"MetricExpr": "(UNC_C_TOR_OCCUPANCY.MISS_ALL / UNC_C_CLOCKTICKS) * 100.",
"MetricName": "tor_occupancy.miss_all %",
"PerPkg": "1",
"UMask": "0xa",
"Unit": "CBO"
......@@ -189,7 +190,7 @@
"Unit": "CBO"
},
{
"BriefDescription": "read requests to home agent. Derived from unc_h_requests.reads",
"BriefDescription": "read requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.READS",
......@@ -198,7 +199,7 @@
"Unit": "HA"
},
{
"BriefDescription": "write requests to home agent. Derived from unc_h_requests.writes",
"BriefDescription": "write requests to home agent",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_H_REQUESTS.WRITES",
......
[
{
"BriefDescription": "QPI clock ticks. Used to get percentages of QPI cycles events. Derived from unc_q_clockticks",
"BriefDescription": "QPI clock ticks. Used to get percentages of QPI cycles events",
"Counter": "0,1,2,3",
"EventCode": "0x14",
"EventName": "UNC_Q_CLOCKTICKS",
......@@ -8,25 +8,27 @@
"Unit": "QPI LL"
},
{
"BriefDescription": "Cycles where receiving QPI link is in half-width mode. Derived from unc_q_rxl0p_power_cycles",
"BriefDescription": "Cycles where receiving QPI link is in half-width mode",
"Counter": "0,1,2,3",
"EventCode": "0x10",
"EventName": "UNC_Q_RxL0P_POWER_CYCLES",
"MetricExpr": "(UNC_Q_RxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
"MetricName": "rxl0p_power_cycles %",
"PerPkg": "1",
"Unit": "QPI LL"
},
{
"BriefDescription": "Cycles where transmitting QPI link is in half-width mode. Derived from unc_q_txl0p_power_cycles",
"BriefDescription": "Cycles where transmitting QPI link is in half-width mode",
"Counter": "0,1,2,3",
"EventCode": "0xd",
"EventName": "UNC_Q_TxL0P_POWER_CYCLES",
"MetricExpr": "(UNC_Q_TxL0P_POWER_CYCLES / UNC_Q_CLOCKTICKS) * 100.",
"MetricName": "txl0p_power_cycles %",
"PerPkg": "1",
"Unit": "QPI LL"
},
{
"BriefDescription": "Number of data flits transmitted . Derived from unc_q_txl_flits_g0.data",
"BriefDescription": "Number of data flits transmitted ",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.DATA",
"PerPkg": "1",
......@@ -35,7 +37,7 @@
"Unit": "QPI LL"
},
{
"BriefDescription": "Number of non data (control) flits transmitted . Derived from unc_q_txl_flits_g0.non_data",
"BriefDescription": "Number of non data (control) flits transmitted ",
"Counter": "0,1,2,3",
"EventName": "UNC_Q_TxL_FLITS_G0.NON_DATA",
"PerPkg": "1",
......
[
{
"BriefDescription": "Memory page activates. Derived from unc_m_act_count",
"BriefDescription": "Memory page activates",
"Counter": "0,1,2,3",
"EventCode": "0x1",
"EventName": "UNC_M_ACT_COUNT",
......@@ -11,7 +11,7 @@
"BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.RD",
"EventName": "LLC_MISSES.MEM_READ",
"PerPkg": "1",
"UMask": "0x3",
"Unit": "iMC"
......@@ -20,47 +20,50 @@
"BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr",
"Counter": "0,1,2,3",
"EventCode": "0x4",
"EventName": "UNC_M_CAS_COUNT.WR",
"EventName": "LLC_MISSES.MEM_WRITE",
"PerPkg": "1",
"UMask": "0xc",
"Unit": "iMC"
},
{
"BriefDescription": "Memory controller clock ticks. Used to get percentages of memory controller cycles events. Derived from unc_m_clockticks",
"BriefDescription": "Memory controller clock ticks. Used to get percentages of memory controller cycles events",
"Counter": "0,1,2,3",
"EventName": "UNC_M_CLOCKTICKS",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode. Derived from unc_m_power_channel_ppd",
"BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode",
"Counter": "0,1,2,3",
"EventCode": "0x85",
"EventName": "UNC_M_POWER_CHANNEL_PPD",
"MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_channel_ppd %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles all ranks are in critical thermal throttle. Derived from unc_m_power_critical_throttle_cycles",
"BriefDescription": "Cycles all ranks are in critical thermal throttle",
"Counter": "0,1,2,3",
"EventCode": "0x86",
"EventName": "UNC_M_POWER_CRITICAL_THROTTLE_CYCLES",
"MetricExpr": "(UNC_M_POWER_CRITICAL_THROTTLE_CYCLES / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_critical_throttle_cycles %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Cycles Memory is in self refresh power mode. Derived from unc_m_power_self_refresh",
"BriefDescription": "Cycles Memory is in self refresh power mode",
"Counter": "0,1,2,3",
"EventCode": "0x43",
"EventName": "UNC_M_POWER_SELF_REFRESH",
"MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.",
"MetricName": "power_self_refresh %",
"PerPkg": "1",
"Unit": "iMC"
},
{
"BriefDescription": "Memory page conflicts. Derived from unc_m_pre_count.page_miss",
"BriefDescription": "Memory page conflicts",
"Counter": "0,1,2,3",
"EventCode": "0x2",
"EventName": "UNC_M_PRE_COUNT.PAGE_MISS",
......@@ -69,7 +72,7 @@
"Unit": "iMC"
},
{
"BriefDescription": "Occupancy counter for memory read queue. Derived from unc_m_rpq_occupancy",
"BriefDescription": "Occupancy counter for memory read queue",
"Counter": "0,1,2,3",
"EventCode": "0x80",
"EventName": "UNC_M_RPQ_OCCUPANCY",
......
......@@ -291,7 +291,9 @@ static void print_events_table_prefix(FILE *fp, const char *tblname)
static int print_events_table_entry(void *data, char *name, char *event,
char *desc, char *long_desc,
char *pmu, char *unit, char *perpkg)
char *pmu, char *unit, char *perpkg,
char *metric_expr,
char *metric_name)
{
struct perf_entry_data *pd = data;
FILE *outfp = pd->outfp;
......@@ -315,6 +317,10 @@ static int print_events_table_entry(void *data, char *name, char *event,
fprintf(outfp, "\t.unit = \"%s\",\n", unit);
if (perpkg)
fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg);
if (metric_expr)
fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr);
if (metric_name)
fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name);
fprintf(outfp, "},\n");
return 0;
......@@ -362,7 +368,9 @@ static char *real_event(const char *name, char *event)
int json_events(const char *fn,
int (*func)(void *data, char *name, char *event, char *desc,
char *long_desc,
char *pmu, char *unit, char *perpkg),
char *pmu, char *unit, char *perpkg,
char *metric_expr,
char *metric_name),
void *data)
{
int err = -EIO;
......@@ -388,6 +396,8 @@ int json_events(const char *fn,
char *filter = NULL;
char *perpkg = NULL;
char *unit = NULL;
char *metric_expr = NULL;
char *metric_name = NULL;
unsigned long long eventcode = 0;
struct msrmap *msr = NULL;
jsmntok_t *msrval = NULL;
......@@ -398,6 +408,7 @@ int json_events(const char *fn,
for (j = 0; j < obj->size; j += 2) {
jsmntok_t *field, *val;
int nz;
char *s;
field = tok + j;
EXPECT(field->type == JSMN_STRING, tok + j,
......@@ -444,7 +455,6 @@ int json_events(const char *fn,
NULL);
} else if (json_streq(map, field, "Unit")) {
const char *ppmu;
char *s;
ppmu = field_to_perf(unit_to_pmu, map, val);
if (ppmu) {
......@@ -464,6 +474,12 @@ int json_events(const char *fn,
addfield(map, &unit, "", "", val);
} else if (json_streq(map, field, "PerPkg")) {
addfield(map, &perpkg, "", "", val);
} else if (json_streq(map, field, "MetricName")) {
addfield(map, &metric_name, "", "", val);
} else if (json_streq(map, field, "MetricExpr")) {
addfield(map, &metric_expr, "", "", val);
for (s = metric_expr; *s; s++)
*s = tolower(*s);
}
/* ignore unknown fields */
}
......@@ -488,7 +504,7 @@ int json_events(const char *fn,
fixname(name);
err = func(data, name, real_event(name, event), desc, long_desc,
pmu, unit, perpkg);
pmu, unit, perpkg, metric_expr, metric_name);
free(event);
free(desc);
free(name);
......@@ -498,6 +514,8 @@ int json_events(const char *fn,
free(filter);
free(perpkg);
free(unit);
free(metric_expr);
free(metric_name);
if (err)
break;
tok += j;
......
......@@ -5,7 +5,8 @@ int json_events(const char *fn,
int (*func)(void *data, char *name, char *event, char *desc,
char *long_desc,
char *pmu,
char *unit, char *perpkg),
char *unit, char *perpkg, char *metric_expr,
char *metric_name),
void *data);
char *get_cpu_str(void);
......
......@@ -13,6 +13,8 @@ struct pmu_event {
const char *pmu;
const char *unit;
const char *perpkg;
const char *metric_expr;
const char *metric_name;
};
/*
......
......@@ -38,6 +38,7 @@ perf-y += cpumap.o
perf-y += stat.o
perf-y += event_update.o
perf-y += event-times.o
perf-y += expr.o
perf-y += backward-ring-buffer.o
perf-y += sdt.o
perf-y += is_printable_array.o
......
......@@ -43,6 +43,10 @@ static struct test generic_tests[] = {
.desc = "Parse event definition strings",
.func = test__parse_events,
},
{
.desc = "Simple expression parser",
.func = test__expr,
},
{
.desc = "PERF_RECORD_* events & perf_sample fields",
.func = test__PERF_RECORD,
......
#include "util/debug.h"
#include "util/expr.h"
#include "tests.h"
#include <stdlib.h>
static int test(struct parse_ctx *ctx, const char *e, double val2)
{
double val;
if (expr__parse(&val, ctx, &e))
TEST_ASSERT_VAL("parse test failed", 0);
TEST_ASSERT_VAL("unexpected value", val == val2);
return 0;
}
int test__expr(int subtest __maybe_unused)
{
const char *p;
const char **other;
double val;
int ret;
struct parse_ctx ctx;
int num_other;
expr__ctx_init(&ctx);
expr__add_id(&ctx, "FOO", 1);
expr__add_id(&ctx, "BAR", 2);
ret = test(&ctx, "1+1", 2);
ret |= test(&ctx, "FOO+BAR", 3);
ret |= test(&ctx, "(BAR/2)%2", 1);
ret |= test(&ctx, "1 - -4", 5);
ret |= test(&ctx, "(FOO-1)*2 + (BAR/2)%2 - -4", 5);
if (ret)
return ret;
p = "FOO/0";
ret = expr__parse(&val, &ctx, &p);
TEST_ASSERT_VAL("division by zero", ret == 1);
p = "BAR/";
ret = expr__parse(&val, &ctx, &p);
TEST_ASSERT_VAL("missing operand", ret == 1);
TEST_ASSERT_VAL("find other",
expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", &other, &num_other) == 0);
TEST_ASSERT_VAL("find other", num_other == 3);
TEST_ASSERT_VAL("find other", !strcmp(other[0], "BAR"));
TEST_ASSERT_VAL("find other", !strcmp(other[1], "BAZ"));
TEST_ASSERT_VAL("find other", !strcmp(other[2], "BOZO"));
TEST_ASSERT_VAL("find other", other[3] == NULL);
free((void *)other);
return 0;
}
......@@ -62,6 +62,7 @@ int test__sample_parsing(int subtest);
int test__keep_tracking(int subtest);
int test__parse_no_sample_id_all(int subtest);
int test__dwarf_unwind(int subtest);
int test__expr(int subtest);
int test__hists_filter(int subtest);
int test__mmap_thread_lookup(int subtest);
int test__thread_mg_share(int subtest);
......
......@@ -90,6 +90,7 @@ libperf-y += mem-events.o
libperf-y += vsprintf.o
libperf-y += drv_configs.o
libperf-y += time-utils.o
libperf-y += expr-bison.o
libperf-$(CONFIG_LIBBPF) += bpf-loader.o
libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
......@@ -142,6 +143,10 @@ $(OUTPUT)util/parse-events-bison.c: util/parse-events.y
$(call rule_mkdir)
$(Q)$(call echo-cmd,bison)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $@ -p parse_events_
$(OUTPUT)util/expr-bison.c: util/expr.y
$(call rule_mkdir)
$(Q)$(call echo-cmd,bison)$(BISON) -v util/expr.y -d $(PARSER_DEBUG_BISON) -o $@ -p expr__
$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
$(call rule_mkdir)
$(Q)$(call echo-cmd,flex)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l
......@@ -154,6 +159,7 @@ CFLAGS_parse-events-flex.o += -w
CFLAGS_pmu-flex.o += -w
CFLAGS_parse-events-bison.o += -DYYENABLE_NLS=0 -w
CFLAGS_pmu-bison.o += -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w
CFLAGS_expr-bison.o += -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w
$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
......
......@@ -1435,7 +1435,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
snprintf(command, sizeof(command),
"%s %s%s --start-address=0x%016" PRIx64
" --stop-address=0x%016" PRIx64
" -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand",
" -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand",
objdump_path ? objdump_path : "objdump",
disassembler_style ? "-M " : "",
disassembler_style ? disassembler_style : "",
......@@ -1482,6 +1482,12 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
nline = 0;
while (!feof(file)) {
/*
* The source code line number (lineno) needs to be kept in
* accross calls to symbol__parse_objdump_line(), so that it
* can associate it with the instructions till the next one.
* See disasm_line__new() and struct disasm_line::line_nr.
*/
if (symbol__parse_objdump_line(sym, map, arch, file, privsize,
&lineno) < 0)
break;
......
......@@ -236,6 +236,10 @@ void perf_evsel__init(struct perf_evsel *evsel,
evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
perf_evsel__calc_id_pos(evsel);
evsel->cmdline_group_boundary = false;
evsel->metric_expr = NULL;
evsel->metric_name = NULL;
evsel->metric_events = NULL;
evsel->collect_stat = false;
}
struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
......
......@@ -131,6 +131,11 @@ struct perf_evsel {
bool cmdline_group_boundary;
struct list_head config_terms;
int bpf_fd;
bool merged_stat;
const char * metric_expr;
const char * metric_name;
struct perf_evsel **metric_events;
bool collect_stat;
};
union u64_swap {
......
#ifndef PARSE_CTX_H
#define PARSE_CTX_H 1
#define EXPR_MAX_OTHER 8
#define MAX_PARSE_ID EXPR_MAX_OTHER
struct parse_id {
const char *name;
double val;
};
struct parse_ctx {
int num_ids;
struct parse_id ids[MAX_PARSE_ID];
};
void expr__ctx_init(struct parse_ctx *ctx);
void expr__add_id(struct parse_ctx *ctx, const char *id, double val);
#ifndef IN_EXPR_Y
int expr__parse(double *final_val, struct parse_ctx *ctx, const char **pp);
#endif
int expr__find_other(const char *p, const char *one, const char ***other,
int *num_other);
#endif
/* Simple expression parser */
%{
#include "util.h"
#include "util/debug.h"
#define IN_EXPR_Y 1
#include "expr.h"
#include <string.h>
#define MAXIDLEN 256
%}
%pure-parser
%parse-param { double *final_val }
%parse-param { struct parse_ctx *ctx }
%parse-param { const char **pp }
%lex-param { const char **pp }
%union {
double num;
char id[MAXIDLEN+1];
}
%token <num> NUMBER
%token <id> ID
%left '|'
%left '^'
%left '&'
%left '-' '+'
%left '*' '/' '%'
%left NEG NOT
%type <num> expr
%{
static int expr__lex(YYSTYPE *res, const char **pp);
static void expr__error(double *final_val __maybe_unused,
struct parse_ctx *ctx __maybe_unused,
const char **pp __maybe_unused,
const char *s)
{
pr_debug("%s\n", s);
}
static int lookup_id(struct parse_ctx *ctx, char *id, double *val)
{
int i;
for (i = 0; i < ctx->num_ids; i++) {
if (!strcasecmp(ctx->ids[i].name, id)) {
*val = ctx->ids[i].val;
return 0;
}
}
return -1;
}
%}
%%
all_expr: expr { *final_val = $1; }
;
expr: NUMBER
| ID { if (lookup_id(ctx, $1, &$$) < 0) {
pr_debug("%s not found", $1);
YYABORT;
}
}
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { if ($3 == 0) YYABORT; $$ = $1 / $3; }
| expr '%' expr { if ((long)$3 == 0) YYABORT; $$ = (long)$1 % (long)$3; }
| '-' expr %prec NEG { $$ = -$2; }
| '(' expr ')' { $$ = $2; }
;
%%
static int expr__symbol(YYSTYPE *res, const char *p, const char **pp)
{
char *dst = res->id;
const char *s = p;
while (isalnum(*p) || *p == '_' || *p == '.') {
if (p - s >= MAXIDLEN)
return -1;
*dst++ = *p++;
}
*dst = 0;
*pp = p;
return ID;
}
static int expr__lex(YYSTYPE *res, const char **pp)
{
int tok;
const char *s;
const char *p = *pp;
while (isspace(*p))
p++;
s = p;
switch (*p++) {
case 'a' ... 'z':
case 'A' ... 'Z':
return expr__symbol(res, p - 1, pp);
case '0' ... '9': case '.':
res->num = strtod(s, (char **)&p);
tok = NUMBER;
break;
default:
tok = *s;
break;
}
*pp = p;
return tok;
}
/* Caller must make sure id is allocated */
void expr__add_id(struct parse_ctx *ctx, const char *name, double val)
{
int idx;
assert(ctx->num_ids < MAX_PARSE_ID);
idx = ctx->num_ids++;
ctx->ids[idx].name = name;
ctx->ids[idx].val = val;
}
void expr__ctx_init(struct parse_ctx *ctx)
{
ctx->num_ids = 0;
}
int expr__find_other(const char *p, const char *one, const char ***other,
int *num_otherp)
{
const char *orig = p;
int err = -1;
int num_other;
*other = malloc((EXPR_MAX_OTHER + 1) * sizeof(char *));
if (!*other)
return -1;
num_other = 0;
for (;;) {
YYSTYPE val;
int tok = expr__lex(&val, &p);
if (tok == 0) {
err = 0;
break;
}
if (tok == ID && strcasecmp(one, val.id)) {
if (num_other >= EXPR_MAX_OTHER - 1) {
pr_debug("Too many extra events in %s\n", orig);
break;
}
(*other)[num_other] = strdup(val.id);
if (!(*other)[num_other])
return -1;
num_other++;
}
}
(*other)[num_other] = NULL;
*num_otherp = num_other;
if (err) {
*num_otherp = 0;
free(*other);
*other = NULL;
}
return err;
}
......@@ -1255,11 +1255,59 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
evsel->scale = info.scale;
evsel->per_pkg = info.per_pkg;
evsel->snapshot = info.snapshot;
evsel->metric_expr = info.metric_expr;
evsel->metric_name = info.metric_name;
}
return evsel ? 0 : -ENOMEM;
}
int parse_events_multi_pmu_add(struct parse_events_evlist *data,
char *str, struct list_head **listp)
{
struct list_head *head;
struct parse_events_term *term;
struct list_head *list;
struct perf_pmu *pmu = NULL;
int ok = 0;
*listp = NULL;
/* Add it for all PMUs that support the alias */
list = malloc(sizeof(struct list_head));
if (!list)
return -1;
INIT_LIST_HEAD(list);
while ((pmu = perf_pmu__scan(pmu)) != NULL) {
struct perf_pmu_alias *alias;
list_for_each_entry(alias, &pmu->aliases, list) {
if (!strcasecmp(alias->name, str)) {
head = malloc(sizeof(struct list_head));
if (!head)
return -1;
INIT_LIST_HEAD(head);
if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
str, 1, false, &str, NULL) < 0)
return -1;
list_add_tail(&term->list, head);
if (!parse_events_add_pmu(data, list,
pmu->name, head)) {
pr_debug("%s -> %s/%s/\n", str,
pmu->name, alias->str);
ok++;
}
parse_events_terms__delete(head);
}
}
}
if (!ok)
return -1;
*listp = list;
return 0;
}
int parse_events__modifier_group(struct list_head *list,
char *event_mod)
{
......@@ -2277,7 +2325,7 @@ void print_symbol_events(const char *event_glob, unsigned type,
* Print the help text for the event symbols:
*/
void print_events(const char *event_glob, bool name_only, bool quiet_flag,
bool long_desc)
bool long_desc, bool details_flag)
{
print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
......@@ -2287,7 +2335,8 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
print_hwcache_events(event_glob, name_only);
print_pmu_events(event_glob, name_only, quiet_flag, long_desc);
print_pmu_events(event_glob, name_only, quiet_flag, long_desc,
details_flag);
if (event_glob != NULL)
return;
......@@ -2416,6 +2465,31 @@ int parse_events_term__clone(struct parse_events_term **new,
return new_term(new, &temp, term->val.str, term->val.num);
}
int parse_events_copy_term_list(struct list_head *old,
struct list_head **new)
{
struct parse_events_term *term, *n;
int ret;
if (!old) {
*new = NULL;
return 0;
}
*new = malloc(sizeof(struct list_head));
if (!*new)
return -ENOMEM;
INIT_LIST_HEAD(*new);
list_for_each_entry (term, old, list) {
ret = parse_events_term__clone(&n, term);
if (ret)
return ret;
list_add_tail(&n->list, *new);
}
return 0;
}
void parse_events_terms__purge(struct list_head *terms)
{
struct parse_events_term *term, *h;
......
......@@ -167,6 +167,14 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
int parse_events_add_pmu(struct parse_events_evlist *data,
struct list_head *list, char *name,
struct list_head *head_config);
int parse_events_multi_pmu_add(struct parse_events_evlist *data,
char *str,
struct list_head **listp);
int parse_events_copy_term_list(struct list_head *old,
struct list_head **new);
enum perf_pmu_event_symbol_type
perf_pmu__parse_check(const char *name);
void parse_events__set_leader(char *name, struct list_head *list);
......@@ -176,7 +184,7 @@ void parse_events_evlist_error(struct parse_events_evlist *data,
int idx, const char *str);
void print_events(const char *event_glob, bool name_only, bool quiet,
bool long_desc);
bool long_desc, bool details_flag);
struct event_symbol {
const char *symbol;
......
......@@ -226,68 +226,55 @@ event_pmu:
PE_NAME opt_event_config
{
struct parse_events_evlist *data = _data;
struct list_head *list;
struct list_head *list, *orig_terms, *terms;
if (parse_events_copy_term_list($2, &orig_terms))
YYABORT;
ALLOC_LIST(list);
ABORT_ON(parse_events_add_pmu(data, list, $1, $2));
parse_events_terms__delete($2);
$$ = list;
}
|
PE_KERNEL_PMU_EVENT sep_dc
{
struct parse_events_evlist *data = _data;
struct list_head *head;
struct parse_events_term *term;
struct list_head *list;
if (parse_events_add_pmu(data, list, $1, $2)) {
struct perf_pmu *pmu = NULL;
int ok = 0;
/* Add it for all PMUs that support the alias */
ALLOC_LIST(list);
while ((pmu = perf_pmu__scan(pmu)) != NULL) {
struct perf_pmu_alias *alias;
list_for_each_entry(alias, &pmu->aliases, list) {
if (!strcasecmp(alias->name, $1)) {
ALLOC_LIST(head);
ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
$1, 1, false, &@1, NULL));
list_add_tail(&term->list, head);
char *name = pmu->name;
if (!parse_events_add_pmu(data, list,
pmu->name, head)) {
pr_debug("%s -> %s/%s/\n", $1,
pmu->name, alias->str);
if (!strncmp(name, "uncore_", 7) &&
strncmp($1, "uncore_", 7))
name += 7;
if (!strncmp($1, name, strlen($1))) {
if (parse_events_copy_term_list(orig_terms, &terms))
YYABORT;
if (!parse_events_add_pmu(data, list, pmu->name, terms))
ok++;
}
parse_events_terms__delete(head);
}
parse_events_terms__delete(terms);
}
}
if (!ok)
YYABORT;
}
parse_events_terms__delete($2);
parse_events_terms__delete(orig_terms);
$$ = list;
}
|
PE_KERNEL_PMU_EVENT sep_dc
{
struct list_head *list;
if (parse_events_multi_pmu_add(_data, $1, &list) < 0)
YYABORT;
$$ = list;
}
|
PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
{
struct parse_events_evlist *data = _data;
struct list_head *head;
struct parse_events_term *term;
struct list_head *list;
char pmu_name[128];
snprintf(&pmu_name, 128, "%s-%s", $1, $3);
ALLOC_LIST(head);
ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
&pmu_name, 1, false, &@1, NULL));
list_add_tail(&term->list, head);
ALLOC_LIST(list);
ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
parse_events_terms__delete(head);
snprintf(&pmu_name, 128, "%s-%s", $1, $3);
if (parse_events_multi_pmu_add(_data, pmu_name, &list) < 0)
YYABORT;
$$ = list;
}
......
......@@ -6,6 +6,12 @@ const struct sample_reg __weak sample_reg_masks[] = {
SMPL_REG_END
};
int __weak sdt_rename_register(char **pdesc __maybe_unused,
char *old_name __maybe_unused)
{
return 0;
}
#ifdef HAVE_PERF_REGS_SUPPORT
int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
{
......
......@@ -15,6 +15,12 @@ struct sample_reg {
extern const struct sample_reg sample_reg_masks[];
/*
* The table sdt_reg_renamings is used for adjusting gcc/gas-generated
* registers before filling the uprobe tracer interface.
*/
int sdt_rename_register(char **pdesc, char *old_name);
#ifdef HAVE_PERF_REGS_SUPPORT
#include <perf_regs.h>
......
......@@ -231,7 +231,9 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
char *desc, char *val,
char *long_desc, char *topic,
char *unit, char *perpkg)
char *unit, char *perpkg,
char *metric_expr,
char *metric_name)
{
struct perf_pmu_alias *alias;
int ret;
......@@ -265,6 +267,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
perf_pmu__parse_snapshot(alias, dir, name);
}
alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL;
alias->metric_name = metric_name ? strdup(metric_name): NULL;
alias->desc = desc ? strdup(desc) : NULL;
alias->long_desc = long_desc ? strdup(long_desc) :
desc ? strdup(desc) : NULL;
......@@ -294,7 +298,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
buf[ret] = 0;
return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
NULL);
NULL, NULL, NULL);
}
static inline bool pmu_alias_info_file(char *name)
......@@ -564,7 +568,9 @@ static void pmu_add_cpu_aliases(struct list_head *head, const char *name)
__perf_pmu__new_alias(head, NULL, (char *)pe->name,
(char *)pe->desc, (char *)pe->event,
(char *)pe->long_desc, (char *)pe->topic,
(char *)pe->unit, (char *)pe->perpkg);
(char *)pe->unit, (char *)pe->perpkg,
(char *)pe->metric_expr,
(char *)pe->metric_name);
}
out:
......@@ -991,6 +997,8 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
info->unit = NULL;
info->scale = 0.0;
info->snapshot = false;
info->metric_expr = NULL;
info->metric_name = NULL;
list_for_each_entry_safe(term, h, head_terms, list) {
alias = pmu_find_alias(pmu, term);
......@@ -1006,6 +1014,8 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
if (alias->per_pkg)
info->per_pkg = true;
info->metric_expr = alias->metric_expr;
info->metric_name = alias->metric_name;
list_del(&term->list);
free(term);
......@@ -1100,6 +1110,8 @@ struct sevent {
char *topic;
char *str;
char *pmu;
char *metric_expr;
char *metric_name;
};
static int cmp_sevent(const void *a, const void *b)
......@@ -1142,7 +1154,7 @@ static void wordwrap(char *s, int start, int max, int corr)
}
void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
bool long_desc)
bool long_desc, bool details_flag)
{
struct perf_pmu *pmu;
struct perf_pmu_alias *alias;
......@@ -1198,6 +1210,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
aliases[j].topic = alias->topic;
aliases[j].str = alias->str;
aliases[j].pmu = pmu->name;
aliases[j].metric_expr = alias->metric_expr;
aliases[j].metric_name = alias->metric_name;
j++;
}
if (pmu->selectable &&
......@@ -1232,8 +1246,14 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
printf("%*s", 8, "[");
wordwrap(aliases[j].desc, 8, columns, 0);
printf("]\n");
if (verbose > 0)
printf("%*s%s/%s/\n", 8, "", aliases[j].pmu, aliases[j].str);
if (details_flag) {
printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
if (aliases[j].metric_name)
printf(" MetricName: %s", aliases[j].metric_name);
if (aliases[j].metric_expr)
printf(" MetricExpr: %s", aliases[j].metric_expr);
putchar('\n');
}
} else
printf(" %-50s [Kernel PMU event]\n", aliases[j].name);
printed++;
......
......@@ -31,6 +31,8 @@ struct perf_pmu {
struct perf_pmu_info {
const char *unit;
const char *metric_expr;
const char *metric_name;
double scale;
bool per_pkg;
bool snapshot;
......@@ -50,6 +52,8 @@ struct perf_pmu_alias {
double scale;
bool per_pkg;
bool snapshot;
char *metric_expr;
char *metric_name;
};
struct perf_pmu *perf_pmu__find(const char *name);
......@@ -76,7 +80,7 @@ int perf_pmu__format_parse(char *dir, struct list_head *head);
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
void print_pmu_events(const char *event_glob, bool name_only, bool quiet,
bool long_desc);
bool long_desc, bool details_flag);
bool pmu_have_event(const char *pname, const char *name);
int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
......
......@@ -47,7 +47,6 @@
#include "probe-file.h"
#include "session.h"
#define MAX_CMDLEN 256
#define PERFPROBE_GROUP "probe"
bool probe_event_dry_run; /* Dry run flag */
......
......@@ -27,8 +27,10 @@
#include "probe-event.h"
#include "probe-file.h"
#include "session.h"
#include "perf_regs.h"
#define MAX_CMDLEN 256
/* 4096 - 2 ('\n' + '\0') */
#define MAX_CMDLEN 4094
static void print_open_warning(int err, bool uprobe)
{
......@@ -687,6 +689,166 @@ static unsigned long long sdt_note__get_addr(struct sdt_note *note)
: (unsigned long long)note->addr.a64[0];
}
static const char * const type_to_suffix[] = {
":s64", "", "", "", ":s32", "", ":s16", ":s8",
"", ":u8", ":u16", "", ":u32", "", "", "", ":u64"
};
static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg)
{
char *tmp, *desc = strdup(arg);
const char *prefix = "", *suffix = "";
int ret = -1;
if (desc == NULL) {
pr_debug4("Allocation error\n");
return ret;
}
tmp = strchr(desc, '@');
if (tmp) {
long type_idx;
/*
* Isolate the string number and convert it into a
* binary value; this will be an index to get suffix
* of the uprobe name (defining the type)
*/
tmp[0] = '\0';
type_idx = strtol(desc, NULL, 10);
/* Check that the conversion went OK */
if (type_idx == LONG_MIN || type_idx == LONG_MAX) {
pr_debug4("Failed to parse sdt type\n");
goto error;
}
/* Check that the converted value is OK */
if (type_idx < -8 || type_idx > 8) {
pr_debug4("Failed to get a valid sdt type\n");
goto error;
}
suffix = type_to_suffix[type_idx + 8];
/* Get rid of the sdt prefix which is now useless */
tmp++;
memmove(desc, tmp, strlen(tmp) + 1);
}
/*
* The uprobe tracer format does not support all the
* addressing modes (notably: in x86 the scaled mode); so, we
* detect ',' characters, if there is just one, there is no
* use converting the sdt arg into a uprobe one.
*/
if (strchr(desc, ',')) {
pr_debug4("Skipping unsupported SDT argument; %s\n", desc);
goto out;
}
/*
* If the argument addressing mode is indirect, we must check
* a few things...
*/
tmp = strchr(desc, '(');
if (tmp) {
int j;
/*
* ...if the addressing mode is indirect with a
* positive offset (ex.: "1608(%ax)"), we need to add
* a '+' prefix so as to be compliant with uprobe
* format.
*/
if (desc[0] != '+' && desc[0] != '-')
prefix = "+";
/*
* ...or if the addressing mode is indirect with a symbol
* as offset, the argument will not be supported by
* the uprobe tracer format; so, let's skip this one.
*/
for (j = 0; j < tmp - desc; j++) {
if (desc[j] != '+' && desc[j] != '-' &&
!isdigit(desc[j])) {
pr_debug4("Skipping unsupported SDT argument; "
"%s\n", desc);
goto out;
}
}
}
/*
* The uprobe tracer format does not support constants; if we
* find one in the current argument, let's skip the argument.
*/
if (strchr(desc, '$')) {
pr_debug4("Skipping unsupported SDT argument; %s\n", desc);
goto out;
}
/*
* The uprobe parser does not support all gas register names;
* so, we have to replace them (ex. for x86_64: %rax -> %ax);
* the loop below looks for the register names (starting with
* a '%' and tries to perform the needed renamings.
*/
tmp = strchr(desc, '%');
while (tmp) {
size_t offset = tmp - desc;
ret = sdt_rename_register(&desc, desc + offset);
if (ret < 0)
goto error;
/*
* The desc pointer might have changed; so, let's not
* try to reuse tmp for next lookup
*/
tmp = strchr(desc + offset + 1, '%');
}
if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0)
goto error;
out:
ret = 0;
error:
free(desc);
return ret;
}
static char *synthesize_sdt_probe_command(struct sdt_note *note,
const char *pathname,
const char *sdtgrp)
{
struct strbuf buf;
char *ret = NULL, **args;
int i, args_count;
if (strbuf_init(&buf, 32) < 0)
return NULL;
if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
sdtgrp, note->name, pathname,
sdt_note__get_addr(note)) < 0)
goto error;
if (!note->args)
goto out;
if (note->args) {
args = argv_split(note->args, &args_count);
for (i = 0; i < args_count; ++i) {
if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0)
goto error;
}
}
out:
ret = strbuf_detach(&buf, NULL);
error:
strbuf_release(&buf);
return ret;
}
int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
{
struct probe_cache_entry *entry = NULL;
......@@ -723,11 +885,12 @@ int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
entry->pev.group = strdup(sdtgrp);
list_add_tail(&entry->node, &pcache->entries);
}
ret = asprintf(&buf, "p:%s/%s %s:0x%llx",
sdtgrp, note->name, pathname,
sdt_note__get_addr(note));
if (ret < 0)
buf = synthesize_sdt_probe_command(note, pathname, sdtgrp);
if (!buf) {
ret = -ENOMEM;
break;
}
strlist__add(entry->tevlist, buf);
free(buf);
entry = NULL;
......
......@@ -3,6 +3,9 @@
#include "stat.h"
#include "color.h"
#include "pmu.h"
#include "rblist.h"
#include "evlist.h"
#include "expr.h"
enum {
CTX_BIT_USER = 1 << 0,
......@@ -41,13 +44,73 @@ static struct stats runtime_topdown_slots_issued[NUM_CTX][MAX_NR_CPUS];
static struct stats runtime_topdown_slots_retired[NUM_CTX][MAX_NR_CPUS];
static struct stats runtime_topdown_fetch_bubbles[NUM_CTX][MAX_NR_CPUS];
static struct stats runtime_topdown_recovery_bubbles[NUM_CTX][MAX_NR_CPUS];
static struct rblist runtime_saved_values;
static bool have_frontend_stalled;
struct stats walltime_nsecs_stats;
struct saved_value {
struct rb_node rb_node;
struct perf_evsel *evsel;
int cpu;
int ctx;
struct stats stats;
};
static int saved_value_cmp(struct rb_node *rb_node, const void *entry)
{
struct saved_value *a = container_of(rb_node,
struct saved_value,
rb_node);
const struct saved_value *b = entry;
if (a->ctx != b->ctx)
return a->ctx - b->ctx;
if (a->cpu != b->cpu)
return a->cpu - b->cpu;
return a->evsel - b->evsel;
}
static struct rb_node *saved_value_new(struct rblist *rblist __maybe_unused,
const void *entry)
{
struct saved_value *nd = malloc(sizeof(struct saved_value));
if (!nd)
return NULL;
memcpy(nd, entry, sizeof(struct saved_value));
return &nd->rb_node;
}
static struct saved_value *saved_value_lookup(struct perf_evsel *evsel,
int cpu, int ctx,
bool create)
{
struct rb_node *nd;
struct saved_value dm = {
.cpu = cpu,
.ctx = ctx,
.evsel = evsel,
};
nd = rblist__find(&runtime_saved_values, &dm);
if (nd)
return container_of(nd, struct saved_value, rb_node);
if (create) {
rblist__add_node(&runtime_saved_values, &dm);
nd = rblist__find(&runtime_saved_values, &dm);
if (nd)
return container_of(nd, struct saved_value, rb_node);
}
return NULL;
}
void perf_stat__init_shadow_stats(void)
{
have_frontend_stalled = pmu_have_event("cpu", "stalled-cycles-frontend");
rblist__init(&runtime_saved_values);
runtime_saved_values.node_cmp = saved_value_cmp;
runtime_saved_values.node_new = saved_value_new;
/* No delete for now */
}
static int evsel_context(struct perf_evsel *evsel)
......@@ -70,6 +133,8 @@ static int evsel_context(struct perf_evsel *evsel)
void perf_stat__reset_shadow_stats(void)
{
struct rb_node *pos, *next;
memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
......@@ -92,6 +157,15 @@ void perf_stat__reset_shadow_stats(void)
memset(runtime_topdown_slots_issued, 0, sizeof(runtime_topdown_slots_issued));
memset(runtime_topdown_fetch_bubbles, 0, sizeof(runtime_topdown_fetch_bubbles));
memset(runtime_topdown_recovery_bubbles, 0, sizeof(runtime_topdown_recovery_bubbles));
next = rb_first(&runtime_saved_values.entries);
while (next) {
pos = next;
next = rb_next(pos);
memset(&container_of(pos, struct saved_value, rb_node)->stats,
0,
sizeof(struct stats));
}
}
/*
......@@ -143,6 +217,12 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]);
else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]);
if (counter->collect_stat) {
struct saved_value *v = saved_value_lookup(counter, cpu, ctx,
true);
update_stats(&v->stats, count[0]);
}
}
/* used for get_ratio_color() */
......@@ -172,6 +252,95 @@ static const char *get_ratio_color(enum grc_type type, double ratio)
return color;
}
static struct perf_evsel *perf_stat__find_event(struct perf_evlist *evsel_list,
const char *name)
{
struct perf_evsel *c2;
evlist__for_each_entry (evsel_list, c2) {
if (!strcasecmp(c2->name, name))
return c2;
}
return NULL;
}
/* Mark MetricExpr target events and link events using them to them. */
void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list)
{
struct perf_evsel *counter, *leader, **metric_events, *oc;
bool found;
const char **metric_names;
int i;
int num_metric_names;
evlist__for_each_entry(evsel_list, counter) {
bool invalid = false;
leader = counter->leader;
if (!counter->metric_expr)
continue;
metric_events = counter->metric_events;
if (!metric_events) {
if (expr__find_other(counter->metric_expr, counter->name,
&metric_names, &num_metric_names) < 0)
continue;
metric_events = calloc(sizeof(struct perf_evsel *),
num_metric_names + 1);
if (!metric_events)
return;
counter->metric_events = metric_events;
}
for (i = 0; i < num_metric_names; i++) {
found = false;
if (leader) {
/* Search in group */
for_each_group_member (oc, leader) {
if (!strcasecmp(oc->name, metric_names[i])) {
found = true;
break;
}
}
}
if (!found) {
/* Search ignoring groups */
oc = perf_stat__find_event(evsel_list, metric_names[i]);
}
if (!oc) {
/* Deduping one is good enough to handle duplicated PMUs. */
static char *printed;
/*
* Adding events automatically would be difficult, because
* it would risk creating groups that are not schedulable.
* perf stat doesn't understand all the scheduling constraints
* of events. So we ask the user instead to add the missing
* events.
*/
if (!printed || strcasecmp(printed, metric_names[i])) {
fprintf(stderr,
"Add %s event to groups to get metric expression for %s\n",
metric_names[i],
counter->name);
printed = strdup(metric_names[i]);
}
invalid = true;
continue;
}
metric_events[i] = oc;
oc->collect_stat = true;
}
metric_events[i] = NULL;
free(metric_names);
if (invalid) {
free(metric_events);
counter->metric_events = NULL;
counter->metric_expr = NULL;
}
}
}
static void print_stalled_cycles_frontend(int cpu,
struct perf_evsel *evsel, double avg,
struct perf_stat_output_ctx *out)
......@@ -614,6 +783,34 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
be_bound * 100.);
else
print_metric(ctxp, NULL, NULL, name, 0);
} else if (evsel->metric_expr) {
struct parse_ctx pctx;
int i;
expr__ctx_init(&pctx);
expr__add_id(&pctx, evsel->name, avg);
for (i = 0; evsel->metric_events[i]; i++) {
struct saved_value *v;
v = saved_value_lookup(evsel->metric_events[i], cpu, ctx, false);
if (!v)
break;
expr__add_id(&pctx, evsel->metric_events[i]->name,
avg_stats(&v->stats));
}
if (!evsel->metric_events[i]) {
const char *p = evsel->metric_expr;
if (expr__parse(&ratio, &pctx, &p) == 0)
print_metric(ctxp, NULL, "%8.1f",
evsel->metric_name ?
evsel->metric_name :
out->force_header ? evsel->name : "",
ratio);
else
print_metric(ctxp, NULL, NULL, "", 0);
} else
print_metric(ctxp, NULL, NULL, "", 0);
} else if (runtime_nsecs_stats[cpu].n != 0) {
char unit = 'M';
char unit_buf[10];
......
......@@ -85,11 +85,13 @@ struct perf_stat_output_ctx {
void *ctx;
print_metric_t print_metric;
new_line_t new_line;
bool force_header;
};
void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
double avg, int cpu,
struct perf_stat_output_ctx *out);
void perf_stat__collect_metric_expr(struct perf_evlist *);
int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
void perf_evlist__free_stats(struct perf_evlist *evlist);
......
......@@ -1828,7 +1828,7 @@ void kcore_extract__delete(struct kcore_extract *kce)
static int populate_sdt_note(Elf **elf, const char *data, size_t len,
struct list_head *sdt_notes)
{
const char *provider, *name;
const char *provider, *name, *args;
struct sdt_note *tmp = NULL;
GElf_Ehdr ehdr;
GElf_Addr base_off = 0;
......@@ -1887,6 +1887,25 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
goto out_free_prov;
}
args = memchr(name, '\0', data + len - name);
/*
* There is no argument if:
* - We reached the end of the note;
* - There is not enough room to hold a potential string;
* - The argument string is empty or just contains ':'.
*/
if (args == NULL || data + len - args < 2 ||
args[1] == ':' || args[1] == '\0')
tmp->args = NULL;
else {
tmp->args = strdup(++args);
if (!tmp->args) {
ret = -ENOMEM;
goto out_free_name;
}
}
if (gelf_getclass(*elf) == ELFCLASS32) {
memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr));
tmp->bit32 = true;
......@@ -1898,7 +1917,7 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
if (!gelf_getehdr(*elf, &ehdr)) {
pr_debug("%s : cannot get elf header.\n", __func__);
ret = -EBADF;
goto out_free_name;
goto out_free_args;
}
/* Adjust the prelink effect :
......@@ -1923,6 +1942,8 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
list_add_tail(&tmp->note_list, sdt_notes);
return 0;
out_free_args:
free(tmp->args);
out_free_name:
free(tmp->name);
out_free_prov:
......
......@@ -351,6 +351,7 @@ int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb);
struct sdt_note {
char *name; /* name of the note*/
char *provider; /* provider name */
char *args;
bool bit32; /* whether the location is 32 bits? */
union { /* location, base and semaphore addrs */
Elf64_Addr a64[3];
......
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