mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-13 02:25:36 -04:00
Merge tag 'perf-tools-fixes-for-v5.9-2020-09-16' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
Pull perf tools fixes from Arnaldo Carvalho de Melo: - Set PERF_SAMPLE_PERIOD if attr->freq is set. - Remove trailing commas from AMD JSON vendor event files. - Don't clear event's period if set by a event definition term. - Leader sampling shouldn't clear sample period in 'perf test'. - Fix the "signal" test inline assembly when built with DEBUG=1. - Fix memory leaks detected by ASAN, some in normal paths, some in error paths. - Fix 2 memory sanitizer warnings in 'perf bench'. - Fix the ratio comments of miss-events in 'perf stat'. - Prevent override of attr->sample_period for libpfm4 events. - Sync kvm.h and in.h headers with the kernel sources. * tag 'perf-tools-fixes-for-v5.9-2020-09-16' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: perf stat: Fix the ratio comments of miss-events perf test: Free formats for perf pmu parse test perf metric: Do not free metric when failed to resolve perf metric: Free metric when it failed to resolve perf metric: Release expr_parse_ctx after testing perf test: Fix memory leaks in parse-metric test perf parse-event: Fix memory leak in evsel->unit perf evlist: Fix cpu/thread map leak perf metric: Fix some memory leaks - part 2 perf metric: Fix some memory leaks perf test: Free aliases for PMU event map aliases test perf vendor events amd: Remove trailing commas perf test: Leader sampling shouldn't clear sample period perf record: Don't clear event's period if set by a term tools headers UAPI: update linux/in.h copy tools headers UAPI: Sync kvm.h headers with the kernel sources perf record: Prevent override of attr->sample_period for libpfm4 events perf record: Set PERF_RECORD_PERIOD if attr->freq is set. perf bench: Fix 2 memory sanitizer warnings perf test: Fix the "signal" test inline assembly
This commit is contained in:
@@ -135,7 +135,7 @@ struct in_addr {
|
||||
* this socket to prevent accepting spoofed ones.
|
||||
*/
|
||||
#define IP_PMTUDISC_INTERFACE 4
|
||||
/* weaker version of IP_PMTUDISC_INTERFACE, which allos packets to get
|
||||
/* weaker version of IP_PMTUDISC_INTERFACE, which allows packets to get
|
||||
* fragmented if they exeed the interface mtu
|
||||
*/
|
||||
#define IP_PMTUDISC_OMIT 5
|
||||
|
||||
@@ -790,9 +790,10 @@ struct kvm_ppc_resize_hpt {
|
||||
#define KVM_VM_PPC_HV 1
|
||||
#define KVM_VM_PPC_PR 2
|
||||
|
||||
/* on MIPS, 0 forces trap & emulate, 1 forces VZ ASE */
|
||||
#define KVM_VM_MIPS_TE 0
|
||||
/* on MIPS, 0 indicates auto, 1 forces VZ ASE, 2 forces trap & emulate */
|
||||
#define KVM_VM_MIPS_AUTO 0
|
||||
#define KVM_VM_MIPS_VZ 1
|
||||
#define KVM_VM_MIPS_TE 2
|
||||
|
||||
#define KVM_S390_SIE_PAGE_OFFSET 1
|
||||
|
||||
@@ -1035,6 +1036,7 @@ struct kvm_ppc_resize_hpt {
|
||||
#define KVM_CAP_LAST_CPU 184
|
||||
#define KVM_CAP_SMALLER_MAXPHYADDR 185
|
||||
#define KVM_CAP_S390_DIAG318 186
|
||||
#define KVM_CAP_STEAL_TIME 187
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
|
||||
@@ -66,11 +66,10 @@ static void fdpair(int fds[2])
|
||||
/* Block until we're ready to go */
|
||||
static void ready(int ready_out, int wakefd)
|
||||
{
|
||||
char dummy;
|
||||
struct pollfd pollfd = { .fd = wakefd, .events = POLLIN };
|
||||
|
||||
/* Tell them we're ready. */
|
||||
if (write(ready_out, &dummy, 1) != 1)
|
||||
if (write(ready_out, "R", 1) != 1)
|
||||
err(EXIT_FAILURE, "CLIENT: ready write");
|
||||
|
||||
/* Wait for "GO" signal */
|
||||
@@ -85,6 +84,7 @@ static void *sender(struct sender_context *ctx)
|
||||
unsigned int i, j;
|
||||
|
||||
ready(ctx->ready_out, ctx->wakefd);
|
||||
memset(data, 'S', sizeof(data));
|
||||
|
||||
/* Now pump to every receiver. */
|
||||
for (i = 0; i < nr_loops; i++) {
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
{
|
||||
"EventName": "ex_ret_brn_ind_misp",
|
||||
"EventCode": "0xca",
|
||||
"BriefDescription": "Retired Indirect Branch Instructions Mispredicted.",
|
||||
"BriefDescription": "Retired Indirect Branch Instructions Mispredicted."
|
||||
},
|
||||
{
|
||||
"EventName": "ex_ret_mmx_fp_instr.sse_instr",
|
||||
|
||||
@@ -125,6 +125,6 @@
|
||||
{
|
||||
"EventName": "ex_ret_fus_brnch_inst",
|
||||
"EventCode": "0x1d0",
|
||||
"BriefDescription": "Retired Fused Instructions. The number of fuse-branch instructions retired per cycle. The number of events logged per cycle can vary from 0-8.",
|
||||
"BriefDescription": "Retired Fused Instructions. The number of fuse-branch instructions retired per cycle. The number of events logged per cycle can vary from 0-8."
|
||||
}
|
||||
]
|
||||
|
||||
@@ -49,6 +49,7 @@ Following tests are defined (with perf commands):
|
||||
perf record --call-graph fp kill (test-record-graph-fp)
|
||||
perf record --group -e cycles,instructions kill (test-record-group)
|
||||
perf record -e '{cycles,instructions}' kill (test-record-group1)
|
||||
perf record -e '{cycles/period=1/,instructions/period=2/}:S' kill (test-record-group2)
|
||||
perf record -D kill (test-record-no-delay)
|
||||
perf record -i kill (test-record-no-inherit)
|
||||
perf record -n kill (test-record-no-samples)
|
||||
|
||||
29
tools/perf/tests/attr/test-record-group2
Normal file
29
tools/perf/tests/attr/test-record-group2
Normal file
@@ -0,0 +1,29 @@
|
||||
[config]
|
||||
command = record
|
||||
args = --no-bpf-event -e '{cycles/period=1234000/,instructions/period=6789000/}:S' kill >/dev/null 2>&1
|
||||
ret = 1
|
||||
|
||||
[event-1:base-record]
|
||||
fd=1
|
||||
group_fd=-1
|
||||
config=0|1
|
||||
sample_period=1234000
|
||||
sample_type=87
|
||||
read_format=12
|
||||
inherit=0
|
||||
freq=0
|
||||
|
||||
[event-2:base-record]
|
||||
fd=2
|
||||
group_fd=1
|
||||
config=0|1
|
||||
sample_period=6789000
|
||||
sample_type=87
|
||||
read_format=12
|
||||
disabled=0
|
||||
inherit=0
|
||||
mmap=0
|
||||
comm=0
|
||||
freq=0
|
||||
enable_on_exec=0
|
||||
task=0
|
||||
@@ -45,10 +45,13 @@ volatile long the_var;
|
||||
#if defined (__x86_64__)
|
||||
extern void __test_function(volatile long *ptr);
|
||||
asm (
|
||||
".pushsection .text;"
|
||||
".globl __test_function\n"
|
||||
".type __test_function, @function;"
|
||||
"__test_function:\n"
|
||||
"incq (%rdi)\n"
|
||||
"ret\n");
|
||||
"ret\n"
|
||||
".popsection\n");
|
||||
#else
|
||||
static void __test_function(volatile long *ptr)
|
||||
{
|
||||
|
||||
@@ -153,8 +153,10 @@ static int __compute_metric(const char *name, struct value *vals,
|
||||
return -ENOMEM;
|
||||
|
||||
cpus = perf_cpu_map__new("0");
|
||||
if (!cpus)
|
||||
if (!cpus) {
|
||||
evlist__delete(evlist);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
perf_evlist__set_maps(&evlist->core, cpus, NULL);
|
||||
|
||||
@@ -163,10 +165,11 @@ static int __compute_metric(const char *name, struct value *vals,
|
||||
false, false,
|
||||
&metric_events);
|
||||
if (err)
|
||||
return err;
|
||||
goto out;
|
||||
|
||||
if (perf_evlist__alloc_stats(evlist, false))
|
||||
return -1;
|
||||
err = perf_evlist__alloc_stats(evlist, false);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/* Load the runtime stats with given numbers for events. */
|
||||
runtime_stat__init(&st);
|
||||
@@ -178,13 +181,14 @@ static int __compute_metric(const char *name, struct value *vals,
|
||||
if (name2 && ratio2)
|
||||
*ratio2 = compute_single(&metric_events, evlist, &st, name2);
|
||||
|
||||
out:
|
||||
/* ... clenup. */
|
||||
metricgroup__rblist_exit(&metric_events);
|
||||
runtime_stat__exit(&st);
|
||||
perf_evlist__free_stats(evlist);
|
||||
perf_cpu_map__put(cpus);
|
||||
evlist__delete(evlist);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compute_metric(const char *name, struct value *vals, double *ratio)
|
||||
|
||||
@@ -274,6 +274,7 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count)
|
||||
int res = 0;
|
||||
bool use_uncore_table;
|
||||
struct pmu_events_map *map = __test_pmu_get_events_map();
|
||||
struct perf_pmu_alias *a, *tmp;
|
||||
|
||||
if (!map)
|
||||
return -1;
|
||||
@@ -347,6 +348,10 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count)
|
||||
pmu_name, alias->name);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(a, tmp, &aliases, list) {
|
||||
list_del(&a->list);
|
||||
perf_pmu_free_alias(a);
|
||||
}
|
||||
free(pmu);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -173,6 +173,7 @@ int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused)
|
||||
ret = 0;
|
||||
} while (0);
|
||||
|
||||
perf_pmu__del_formats(&formats);
|
||||
test_format_dir_put(format);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -946,6 +946,10 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target)
|
||||
|
||||
perf_evlist__set_maps(&evlist->core, cpus, threads);
|
||||
|
||||
/* as evlist now has references, put count here */
|
||||
perf_cpu_map__put(cpus);
|
||||
perf_thread_map__put(threads);
|
||||
|
||||
return 0;
|
||||
|
||||
out_delete_threads:
|
||||
@@ -1273,11 +1277,12 @@ static int perf_evlist__create_syswide_maps(struct evlist *evlist)
|
||||
goto out_put;
|
||||
|
||||
perf_evlist__set_maps(&evlist->core, cpus, threads);
|
||||
out:
|
||||
return err;
|
||||
|
||||
perf_thread_map__put(threads);
|
||||
out_put:
|
||||
perf_cpu_map__put(cpus);
|
||||
goto out;
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int evlist__open(struct evlist *evlist)
|
||||
|
||||
@@ -976,16 +976,20 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts,
|
||||
* We default some events to have a default interval. But keep
|
||||
* it a weak assumption overridable by the user.
|
||||
*/
|
||||
if (!attr->sample_period || (opts->user_freq != UINT_MAX ||
|
||||
opts->user_interval != ULLONG_MAX)) {
|
||||
if (!attr->sample_period) {
|
||||
if (opts->freq) {
|
||||
evsel__set_sample_bit(evsel, PERIOD);
|
||||
attr->freq = 1;
|
||||
attr->sample_freq = opts->freq;
|
||||
} else {
|
||||
attr->sample_period = opts->default_interval;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If attr->freq was set (here or earlier), ask for period
|
||||
* to be sampled.
|
||||
*/
|
||||
if (attr->freq)
|
||||
evsel__set_sample_bit(evsel, PERIOD);
|
||||
|
||||
if (opts->no_samples)
|
||||
attr->sample_freq = 0;
|
||||
|
||||
@@ -85,6 +85,7 @@ static void metric_event_delete(struct rblist *rblist __maybe_unused,
|
||||
|
||||
list_for_each_entry_safe(expr, tmp, &me->head, nd) {
|
||||
free(expr->metric_refs);
|
||||
free(expr->metric_events);
|
||||
free(expr);
|
||||
}
|
||||
|
||||
@@ -316,6 +317,7 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
if (!metric_refs) {
|
||||
ret = -ENOMEM;
|
||||
free(metric_events);
|
||||
free(expr);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -530,6 +532,9 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
|
||||
continue;
|
||||
strlist__add(me->metrics, s);
|
||||
}
|
||||
|
||||
if (!raw)
|
||||
free(s);
|
||||
}
|
||||
free(omg);
|
||||
}
|
||||
@@ -667,7 +672,6 @@ static int __add_metric(struct list_head *metric_list,
|
||||
m->has_constraint = metric_no_group || metricgroup__has_constraint(pe);
|
||||
INIT_LIST_HEAD(&m->metric_refs);
|
||||
m->metric_refs_cnt = 0;
|
||||
*mp = m;
|
||||
|
||||
parent = expr_ids__alloc(ids);
|
||||
if (!parent) {
|
||||
@@ -680,6 +684,7 @@ static int __add_metric(struct list_head *metric_list,
|
||||
free(m);
|
||||
return -ENOMEM;
|
||||
}
|
||||
*mp = m;
|
||||
} else {
|
||||
/*
|
||||
* We got here for the referenced metric, via the
|
||||
@@ -714,8 +719,11 @@ static int __add_metric(struct list_head *metric_list,
|
||||
* all the metric's IDs and add it to the parent context.
|
||||
*/
|
||||
if (expr__find_other(pe->metric_expr, NULL, &m->pctx, runtime) < 0) {
|
||||
expr__ctx_clear(&m->pctx);
|
||||
free(m);
|
||||
if (m->metric_refs_cnt == 0) {
|
||||
expr__ctx_clear(&m->pctx);
|
||||
free(m);
|
||||
*mp = NULL;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -934,7 +942,7 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
|
||||
|
||||
ret = add_metric(&list, pe, metric_no_group, &m, NULL, &ids);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Process any possible referenced metrics
|
||||
@@ -943,12 +951,14 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
|
||||
ret = resolve_metric(metric_no_group,
|
||||
&list, map, &ids);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* End of pmu events. */
|
||||
if (!has_match)
|
||||
return -EINVAL;
|
||||
if (!has_match) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each_entry(m, &list, nd) {
|
||||
if (events->len > 0)
|
||||
@@ -963,9 +973,14 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* add to metric_list so that they can be released
|
||||
* even if it's failed
|
||||
*/
|
||||
list_splice(&list, metric_list);
|
||||
expr_ids__exit(&ids);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
|
||||
@@ -1040,7 +1055,7 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,
|
||||
ret = metricgroup__add_metric_list(str, metric_no_group,
|
||||
&extra_events, &metric_list, map);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
pr_debug("adding %s\n", extra_events.buf);
|
||||
bzero(&parse_error, sizeof(parse_error));
|
||||
ret = __parse_events(perf_evlist, extra_events.buf, &parse_error, fake_pmu);
|
||||
@@ -1048,11 +1063,11 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,
|
||||
parse_events_print_error(&parse_error, extra_events.buf);
|
||||
goto out;
|
||||
}
|
||||
strbuf_release(&extra_events);
|
||||
ret = metricgroup__setup_events(&metric_list, metric_no_merge,
|
||||
perf_evlist, metric_events);
|
||||
out:
|
||||
metricgroup__free_metrics(&metric_list);
|
||||
strbuf_release(&extra_events);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -411,7 +411,7 @@ static int add_event_tool(struct list_head *list, int *idx,
|
||||
return -ENOMEM;
|
||||
evsel->tool_event = tool_event;
|
||||
if (tool_event == PERF_TOOL_DURATION_TIME)
|
||||
evsel->unit = strdup("ns");
|
||||
evsel->unit = "ns";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ static void perf_pmu_update_alias(struct perf_pmu_alias *old,
|
||||
}
|
||||
|
||||
/* Delete an alias entry. */
|
||||
static void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
|
||||
void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
|
||||
{
|
||||
zfree(&newalias->name);
|
||||
zfree(&newalias->desc);
|
||||
@@ -1354,6 +1354,17 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to)
|
||||
set_bit(b, bits);
|
||||
}
|
||||
|
||||
void perf_pmu__del_formats(struct list_head *formats)
|
||||
{
|
||||
struct perf_pmu_format *fmt, *tmp;
|
||||
|
||||
list_for_each_entry_safe(fmt, tmp, formats, list) {
|
||||
list_del(&fmt->list);
|
||||
free(fmt->name);
|
||||
free(fmt);
|
||||
}
|
||||
}
|
||||
|
||||
static int sub_non_neg(int a, int b)
|
||||
{
|
||||
if (b > a)
|
||||
|
||||
@@ -94,6 +94,7 @@ int perf_pmu__new_format(struct list_head *list, char *name,
|
||||
int config, unsigned long *bits);
|
||||
void perf_pmu__set_format(unsigned long *bits, long from, long to);
|
||||
int perf_pmu__format_parse(char *dir, struct list_head *head);
|
||||
void perf_pmu__del_formats(struct list_head *formats);
|
||||
|
||||
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
|
||||
|
||||
@@ -113,6 +114,7 @@ void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu,
|
||||
|
||||
struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu);
|
||||
bool pmu_uncore_alias_match(const char *pmu_name, const char *name);
|
||||
void perf_pmu_free_alias(struct perf_pmu_alias *alias);
|
||||
|
||||
int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "debug.h"
|
||||
#include "evlist.h"
|
||||
#include "evsel.h"
|
||||
#include "evsel_config.h"
|
||||
#include "parse-events.h"
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
@@ -33,11 +34,24 @@ static struct evsel *evsel__read_sampler(struct evsel *evsel, struct evlist *evl
|
||||
return leader;
|
||||
}
|
||||
|
||||
static u64 evsel__config_term_mask(struct evsel *evsel)
|
||||
{
|
||||
struct evsel_config_term *term;
|
||||
struct list_head *config_terms = &evsel->config_terms;
|
||||
u64 term_types = 0;
|
||||
|
||||
list_for_each_entry(term, config_terms, list) {
|
||||
term_types |= 1 << term->type;
|
||||
}
|
||||
return term_types;
|
||||
}
|
||||
|
||||
static void evsel__config_leader_sampling(struct evsel *evsel, struct evlist *evlist)
|
||||
{
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
struct evsel *leader = evsel->leader;
|
||||
struct evsel *read_sampler;
|
||||
u64 term_types, freq_mask;
|
||||
|
||||
if (!leader->sample_read)
|
||||
return;
|
||||
@@ -47,16 +61,20 @@ static void evsel__config_leader_sampling(struct evsel *evsel, struct evlist *ev
|
||||
if (evsel == read_sampler)
|
||||
return;
|
||||
|
||||
term_types = evsel__config_term_mask(evsel);
|
||||
/*
|
||||
* Disable sampling for all group members other than the leader in
|
||||
* case the leader 'leads' the sampling, except when the leader is an
|
||||
* AUX area event, in which case the 2nd event in the group is the one
|
||||
* that 'leads' the sampling.
|
||||
* Disable sampling for all group members except those with explicit
|
||||
* config terms or the leader. In the case of an AUX area event, the 2nd
|
||||
* event in the group is the one that 'leads' the sampling.
|
||||
*/
|
||||
attr->freq = 0;
|
||||
attr->sample_freq = 0;
|
||||
attr->sample_period = 0;
|
||||
attr->write_backward = 0;
|
||||
freq_mask = (1 << EVSEL__CONFIG_TERM_FREQ) | (1 << EVSEL__CONFIG_TERM_PERIOD);
|
||||
if ((term_types & freq_mask) == 0) {
|
||||
attr->freq = 0;
|
||||
attr->sample_freq = 0;
|
||||
attr->sample_period = 0;
|
||||
}
|
||||
if ((term_types & (1 << EVSEL__CONFIG_TERM_OVERWRITE)) == 0)
|
||||
attr->write_backward = 0;
|
||||
|
||||
/*
|
||||
* We don't get a sample for slave events, we make them when delivering
|
||||
|
||||
@@ -517,7 +517,7 @@ static void print_l1_dcache_misses(struct perf_stat_config *config,
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-dcache hits", ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-dcache accesses", ratio);
|
||||
}
|
||||
|
||||
static void print_l1_icache_misses(struct perf_stat_config *config,
|
||||
@@ -538,7 +538,7 @@ static void print_l1_icache_misses(struct perf_stat_config *config,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-icache hits", ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-icache accesses", ratio);
|
||||
}
|
||||
|
||||
static void print_dtlb_cache_misses(struct perf_stat_config *config,
|
||||
@@ -558,7 +558,7 @@ static void print_dtlb_cache_misses(struct perf_stat_config *config,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all dTLB cache hits", ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all dTLB cache accesses", ratio);
|
||||
}
|
||||
|
||||
static void print_itlb_cache_misses(struct perf_stat_config *config,
|
||||
@@ -578,7 +578,7 @@ static void print_itlb_cache_misses(struct perf_stat_config *config,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all iTLB cache hits", ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all iTLB cache accesses", ratio);
|
||||
}
|
||||
|
||||
static void print_ll_cache_misses(struct perf_stat_config *config,
|
||||
@@ -598,7 +598,7 @@ static void print_ll_cache_misses(struct perf_stat_config *config,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all LL-cache hits", ratio);
|
||||
out->print_metric(config, out->ctx, color, "%7.2f%%", "of all LL-cache accesses", ratio);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -853,14 +853,16 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
double test_generic_metric(struct metric_expr *mexp, int cpu, struct runtime_stat *st)
|
||||
{
|
||||
struct expr_parse_ctx pctx;
|
||||
double ratio;
|
||||
double ratio = 0.0;
|
||||
|
||||
if (prepare_metric(mexp->metric_events, mexp->metric_refs, &pctx, cpu, st) < 0)
|
||||
return 0.;
|
||||
goto out;
|
||||
|
||||
if (expr__parse(&ratio, &pctx, mexp->metric_expr, 1))
|
||||
return 0.;
|
||||
ratio = 0.0;
|
||||
|
||||
out:
|
||||
expr__ctx_clear(&pctx);
|
||||
return ratio;
|
||||
}
|
||||
|
||||
@@ -918,7 +920,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
if (runtime_stat_n(st, STAT_L1_DCACHE, ctx, cpu) != 0)
|
||||
print_l1_dcache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
print_metric(config, ctxp, NULL, NULL, "of all L1-dcache hits", 0);
|
||||
print_metric(config, ctxp, NULL, NULL, "of all L1-dcache accesses", 0);
|
||||
} else if (
|
||||
evsel->core.attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_L1I |
|
||||
@@ -928,7 +930,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
if (runtime_stat_n(st, STAT_L1_ICACHE, ctx, cpu) != 0)
|
||||
print_l1_icache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
print_metric(config, ctxp, NULL, NULL, "of all L1-icache hits", 0);
|
||||
print_metric(config, ctxp, NULL, NULL, "of all L1-icache accesses", 0);
|
||||
} else if (
|
||||
evsel->core.attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_DTLB |
|
||||
@@ -938,7 +940,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
if (runtime_stat_n(st, STAT_DTLB_CACHE, ctx, cpu) != 0)
|
||||
print_dtlb_cache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
print_metric(config, ctxp, NULL, NULL, "of all dTLB cache hits", 0);
|
||||
print_metric(config, ctxp, NULL, NULL, "of all dTLB cache accesses", 0);
|
||||
} else if (
|
||||
evsel->core.attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_ITLB |
|
||||
@@ -948,7 +950,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
if (runtime_stat_n(st, STAT_ITLB_CACHE, ctx, cpu) != 0)
|
||||
print_itlb_cache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
print_metric(config, ctxp, NULL, NULL, "of all iTLB cache hits", 0);
|
||||
print_metric(config, ctxp, NULL, NULL, "of all iTLB cache accesses", 0);
|
||||
} else if (
|
||||
evsel->core.attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_LL |
|
||||
@@ -958,7 +960,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
if (runtime_stat_n(st, STAT_LL_CACHE, ctx, cpu) != 0)
|
||||
print_ll_cache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
print_metric(config, ctxp, NULL, NULL, "of all LL-cache hits", 0);
|
||||
print_metric(config, ctxp, NULL, NULL, "of all LL-cache accesses", 0);
|
||||
} else if (evsel__match(evsel, HARDWARE, HW_CACHE_MISSES)) {
|
||||
total = runtime_stat_avg(st, STAT_CACHEREFS, ctx, cpu);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user