!1274 [openEuler-1.0-LTS]perf tool:Perf tool add Hip09 json support
From: @barbo Reviewed-by: @Lostwayzxc, @young1c, @xukuohai Signed-off-by: @Lostwayzxc
This commit is contained in:
commit
389a52fdae
207
kernel.spec
207
kernel.spec
@ -32,7 +32,7 @@
|
||||
|
||||
Name: kernel
|
||||
Version: 4.19.90
|
||||
Release: %{hulkrelease}.0238
|
||||
Release: %{hulkrelease}.0239
|
||||
Summary: Linux Kernel
|
||||
License: GPLv2
|
||||
URL: http://www.kernel.org/
|
||||
@ -836,6 +836,211 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
|
||||
* Fri Nov 10 2023 hongrongxuan <hongrongxuan@huawei.com> - 4.19.90-2311.1.0.0239
|
||||
- perf metricgroup: Fix find_evsel_group() event selector
|
||||
- perf metricgroup: Fix for metrics containing duration_time
|
||||
- perf metricgroup: Fix system PMU metrics
|
||||
- perf metricgroup: Return error code from metricgroup__add_metric_sys_event_iter()
|
||||
- perf vendor events arm64: Fix incorrect Hisi hip08 L3 metrics
|
||||
- perf test: Fix metric parsing test
|
||||
- perf test: Fix msan uninitialized use.
|
||||
- perf test: Set NULL sentinel in pmu_events table in "Parse and process metrics" test
|
||||
- perf expr: Allow numbers to be followed by a dot
|
||||
- perf expr: Test parsing of floating point numbers
|
||||
- perf jevents: Add support for HiSilicon PA PMU aliasing
|
||||
- perf jevents: Add support for HiSilicon SLLC PMU aliasing
|
||||
- perf jevents: Add support for HiSilicon HHA PMU aliasing
|
||||
- perf jevents: Add support for HiSilicon DDRC PMU aliasing
|
||||
- perf jevents: Add support for HiSilicon L3C PMU aliasing
|
||||
- perf test: Add pmu-events test for aliases of hip09 ddrc pmu
|
||||
- perf vendor events arm64: Revise hip08 uncore events
|
||||
- perf test: Verify more event members in pmu-events test
|
||||
- perf jevents: Support ConfigCode
|
||||
- perf parse-events: Set numeric term config
|
||||
- perf test: Add pmu-events sys event support
|
||||
- perf jevents: Print SoC name per system event table
|
||||
- perf pmu: Make pmu_add_sys_aliases() public
|
||||
- perf test: Add more pmu-events uncore aliases
|
||||
- perf test: Re-add pmu-event uncore PMU alias test
|
||||
- perf pmu: Check .is_uncore field in pmu_add_cpu_aliases_map()
|
||||
- perf test: Test pmu-events core aliases separately
|
||||
- perf test: Factor out pmu-events alias comparison
|
||||
- perf test: Declare pmu-events test events separately
|
||||
- perf jevents: Relocate test events to cpu folder
|
||||
- perf test: Factor out pmu-events event comparison
|
||||
- perf jevents: Make build dependency on test JSONs
|
||||
- perf pmu: Save pmu name
|
||||
- perf pmu: Simplify arguments of __perf_pmu__new_alias
|
||||
- perf pmu: Add alias match method to fit pmu_name of HiSilicon DDRC
|
||||
- perf pmu: Fix alias matching
|
||||
- perf tools: Fix pattern matching for same substring in different PMU type
|
||||
- perf jevents: Add test for arch std events
|
||||
- perf metricgroup: Support adding metrics for system PMUs
|
||||
- perf metricgroup: Support printing metric groups for system PMUs
|
||||
- perf metricgroup: Split up metricgroup__print()
|
||||
- perf metricgroup: Fix metrics using aliases covering multiple PMUs
|
||||
- perf evlist: Change evlist__splice_list_tail() ordering
|
||||
- perf pmu: Add pmu_add_sys_aliases()
|
||||
- perf pmu: Add pmu_id()
|
||||
- perf jevents: Add support for system events tables
|
||||
- perf jevents: Add support for an extra directory level
|
||||
- perf jevents: Tidy error handling
|
||||
- perf jevents: Fix event syntax error caused by ExtSel
|
||||
- perf jevents: Fix getting maximum number of fds
|
||||
- perf jevents: Fix event code for events referencing std arch events
|
||||
- perf vendor events arm64: Add Hisi hip08 L3 metrics
|
||||
- perf vendor events arm64: Add Hisi hip08 L2 metrics
|
||||
- perf vendor events arm64: Add Hisi hip08 L1 metrics
|
||||
- perf pmu: Add pmu_events_map__find() function to find the common PMU map for the system
|
||||
- perf test: Handle metric reuse in pmu-events parsing test
|
||||
- perf metricgroup: Make find_metric() public with name change
|
||||
- perf metricgroup: Fix uncore metric expressions
|
||||
- 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 metricgroup: Fix typo in comment.
|
||||
- perf list: Do not print 'Metric Groups:' unnecessarily
|
||||
- perf metricgroup: Pass pmu_event structure as a parameter for arch_get_runtimeparam()
|
||||
- perf jevents: Add support for parsing perchip/percore events
|
||||
- perf jevents: Add new structure to pass json fields.
|
||||
- perf jevents: Make json_events() static and ditch jevents.h file
|
||||
- perf metric: Rename group_list to metric_list
|
||||
- perf metric: Rename struct egroup to metric
|
||||
- perf metric: Add metric group test
|
||||
- perf metric: Make compute_single function more precise
|
||||
- perf metric: Add recursion check when processing nested metrics
|
||||
- perf metric: Add DCache_L2 to metric parse test
|
||||
- perf metric: Add cache_miss_cycles to metric parse test
|
||||
- perf tests: Add parse metric test for frontend metric
|
||||
- perf tests: Add parse metric test for ipc metric
|
||||
- perf metric: Add events for the current list
|
||||
- perf metric: Compute referenced metrics
|
||||
- perf metric: Add referenced metrics to hash data
|
||||
- perf metric: Collect referenced metrics in struct metric_expr
|
||||
- perf metric: Collect referenced metrics in struct metric_ref_node
|
||||
- perf metric: Rename __metricgroup__add_metric to __add_metric
|
||||
- perf metric: Add add_metric function
|
||||
- perf metric: Add macros for iterating map events
|
||||
- perf metric: Add expr__del_id function
|
||||
- perf metric: Change expr__get_id to return struct expr_id_data
|
||||
- perf metric: Add expr__add_id function
|
||||
- perf metric: Fix memory leak in expr__add_id function
|
||||
- perf metric: Add 'struct expr_id_data' to keep expr value
|
||||
- perf metric: Rename expr__add_id() to expr__add_val()
|
||||
- perf pmu: Improve CPU core PMU HW event list ordering
|
||||
- perf pmu: List kernel supplied event aliases for arm64
|
||||
- perf tools: Add test_generic_metric function
|
||||
- perf tools: Release metric_events rblist
|
||||
- perf tools: Factor out prepare_metric function
|
||||
- perf tools: Add metricgroup__parse_groups_test function
|
||||
- perf tools: Add fake_pmu to parse_group() function
|
||||
- perf parse: Factor out parse_groups() function
|
||||
- perf tests: Add another metric parsing test
|
||||
- perf pmu: Add a perf_pmu__fake object to use with __parse_events()
|
||||
- perf parse: Provide a way to pass a fake_pmu to parse_events()
|
||||
- perf tests: Factor check_parse_id function
|
||||
- perf tools: Add fake pmu support
|
||||
- perf tools: Fix term parsing for raw syntax
|
||||
- perf parse: Add 'struct parse_events_state' pointer to scanner
|
||||
- perf stat: Do not pass avg to generic_metric
|
||||
- perf tools: Allow r0x<HEX> event syntax
|
||||
- perf parser: Add support to specify rXXX event with pmu
|
||||
- perf metricgroup: Remove unnecessary ',' from events
|
||||
- perf metricgroup: Add options to not group or merge
|
||||
- perf metricgroup: Remove duped metric group events
|
||||
- perf metricgroup: Order event groups by size
|
||||
- perf metricgroup: Delay events string creation
|
||||
- perf metricgroup: Use early return in add_metric
|
||||
- perf metricgroup: Always place duration_time last
|
||||
- perf metricgroup: Make 'evlist_used' variable a bitmap instead of array of bools
|
||||
- perf expr: Migrate expr ids table to a hashmap
|
||||
- perf test: Provide a subtest callback to ask for the reason for skipping a subtest
|
||||
- perf test: Improve pmu event metric testing
|
||||
- perf expr: Parse numbers as doubles
|
||||
- perf expr: Increase max other
|
||||
- perf expr: Allow ',' to be an other token
|
||||
- perf expr: Allow for unlimited escaped characters in a symbol
|
||||
- perf test: Test pmu-events aliases
|
||||
- perf pmu: Make pmu_uncore_alias_match() public
|
||||
- perf pmu: Add is_pmu_core()
|
||||
- perf test: Add pmu-events test
|
||||
- perf pmu: Refactor pmu_add_cpu_aliases()
|
||||
- perf jevents: Support test events folder
|
||||
- perf jevents: Add some test events
|
||||
- perf tests expr: Added test for runtime param in metric expression
|
||||
- perf metricgroups: Enhance JSON/metric infrastructure to handle "?"
|
||||
- perf metrictroup: Split the metricgroup__add_metric function
|
||||
- perf expr: Add expr_scanner_ctx object
|
||||
- perf expr: Add expr_ prefix for parse_ctx and parse_id
|
||||
- perf expr: Fix copy/paste mistake
|
||||
- perf expr: Fix memory leaks in metric bison
|
||||
- perf expr: Make expr__parse() return -1 on error
|
||||
- perf expr: Straighten expr__parse()/expr__find_other() interface
|
||||
- perf expr: Increase EXPR_MAX_OTHER to support metrics with more than 15 variables
|
||||
- perf expr: Move expr lexer to flex
|
||||
- perf expr: Add expr.c object
|
||||
- perf vendor events intel: Add NO_NMI_WATCHDOG metric constraint
|
||||
- perf metricgroup: Support metric constraint
|
||||
- perf util: Factor out sysctl__nmi_watchdog_enabled()
|
||||
- perf metricgroup: Factor out metricgroup__add_metric_weak_group()
|
||||
- perf jevents: Support metric constraint
|
||||
- perf tools: Update copy of libbpf's hashmap.c
|
||||
- perf tools: Sync hashmap.h with libbpf's
|
||||
- perf tools: Grab a copy of libbpf's hashmap
|
||||
- libbpf, hashmap: Fix undefined behavior in hash_bits
|
||||
- libbpf: Fix libbpf hashmap on (I)LP32 architectures
|
||||
- libbpf: Define __WORDSIZE if not available
|
||||
- libbpf, hashmap: Remove unused #include
|
||||
- libbpf: fix missing __WORDSIZE definition
|
||||
- perf parse-events: Fix an old style declaration
|
||||
- perf metricgroup: Fix printing event names of metric group with multiple events incase of overlapping events
|
||||
- tools bitmap: Implement bitmap_equal() operation at bitmap API
|
||||
- perf metricgroup: Fix printing event names of metric group with multiple events
|
||||
- perf list: Hide deprecated events by default
|
||||
- perf tools: Move ALLOC_LIST into a function
|
||||
- perf stat: Fix free memory access / memory leaks in metrics
|
||||
- perf vendor events arm64: Add some missing events for Hisi hip08 HHA PMU
|
||||
- perf vendor events arm64: Add some missing events for Hisi hip08 L3C PMU
|
||||
- perf vendor events arm64: Add some missing events for Hisi hip08 DDRC PMU
|
||||
- perf vendor events arm64: Fix Hisi hip08 DDRC PMU eventname
|
||||
- perf jevents: Add support for Hisi hip08 L3C PMU aliasing
|
||||
- perf jevents: Add support for Hisi hip08 HHA PMU aliasing
|
||||
- perf jevents: Add support for Hisi hip08 DDRC PMU aliasing
|
||||
- perf pmu: Support more complex PMU event aliasing
|
||||
- perf metricgroup: Support multiple events for metricgroup
|
||||
- perf metricgroup: Scale the metric result
|
||||
- perf pmu: Change convert_scale from static to global
|
||||
- perf metricgroup: Remove needless includes from metricgroup.h
|
||||
- perf metricgroup: Add missing list_del_init() when flushing egroups list
|
||||
- perf tools metric: Don't include duration_time in group
|
||||
- perf list: Avoid extra : for --raw metrics
|
||||
- perf jevents: Use nonlocal include statements in pmu-events.c
|
||||
- perf jevents: Remove unused variable
|
||||
- perf stat: Fix metrics with --no-merge
|
||||
- libbpf: add resizable non-thread safe internal hashmap
|
||||
- perf list: Output tool events
|
||||
- perf evsel: Support printing evsel name for 'duration_time'
|
||||
- perf stat: Implement duration_time as a proper event
|
||||
- perf stat: Revert checks for duration_time
|
||||
- perf stat: Implement duration_time as a proper event
|
||||
- perf stat: Revert checks for duration_time
|
||||
- perf tools: Fix legacy events symbol separator parsing
|
||||
- perf list: Display metric expressions for --details option
|
||||
- perf stat: Move 'metric_events' to 'struct perf_stat_config'
|
||||
- perf stat: Pass a 'struct perf_stat_config' argument to global print functions
|
||||
- perf stat: Pass 'struct perf_stat_config' argument to local print functions
|
||||
- perf stat: Add 'struct perf_stat_config' argument to perf_evlist__print_counters()
|
||||
- perf stat: Move STAT_RECORD out of perf_evlist__print_counters()
|
||||
- perf stat: Introduce perf_evlist__print_counters()
|
||||
|
||||
* Thu Nov 9 2023 Kunkun Jiang <jiangkunkun@huawei.com> - 4.19.90-2311.1.0.0238
|
||||
- scsi: virtio_scsi: limit number of hw queues by nr_cpu_ids
|
||||
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
From f58c620c83b508633e9e532906cb52fb54555e2a Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 30 Aug 2018 08:32:24 +0200
|
||||
Subject: [PATCH 001/201] perf stat: Introduce perf_evlist__print_counters()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v4.20-rc1
|
||||
commit a5a9eac1a018ad3bfcf9a3ec11eae99fd35f466b
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5a9eac1a018ad3bfcf9a3ec11eae99fd35f466b
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
To be in charge of printing out the stat output. It will be moved out of
|
||||
the 'perf stat' command in the following patches.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20180830063252.23729-16-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-stat.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index adabe9d4dc86..48327256f0bf 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -1827,7 +1827,10 @@ static void print_footer(void)
|
||||
"the same PMU. Try reorganizing the group.\n");
|
||||
}
|
||||
|
||||
-static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
+static void
|
||||
+perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
+ struct timespec *ts,
|
||||
+ int argc, const char **argv)
|
||||
{
|
||||
int interval = stat_config.interval;
|
||||
struct perf_evsel *counter;
|
||||
@@ -1859,14 +1862,14 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
print_aggr(prefix);
|
||||
break;
|
||||
case AGGR_THREAD:
|
||||
- evlist__for_each_entry(evsel_list, counter) {
|
||||
+ evlist__for_each_entry(evlist, counter) {
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
print_aggr_thread(counter, prefix);
|
||||
}
|
||||
break;
|
||||
case AGGR_GLOBAL:
|
||||
- evlist__for_each_entry(evsel_list, counter) {
|
||||
+ evlist__for_each_entry(evlist, counter) {
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
print_counter_aggr(counter, prefix);
|
||||
@@ -1878,7 +1881,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
if (metric_only)
|
||||
print_no_aggr_metric(prefix);
|
||||
else {
|
||||
- evlist__for_each_entry(evsel_list, counter) {
|
||||
+ evlist__for_each_entry(evlist, counter) {
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
print_counter(counter, prefix);
|
||||
@@ -1896,6 +1899,11 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
fflush(stat_config.output);
|
||||
}
|
||||
|
||||
+static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
+{
|
||||
+ perf_evlist__print_counters(evsel_list, ts, argc, argv);
|
||||
+}
|
||||
+
|
||||
static volatile int signr = -1;
|
||||
|
||||
static void skip_signal(int signo)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
From 0a0a381759790e5b2b961837faccd6c8aeefb038 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 30 Aug 2018 08:32:25 +0200
|
||||
Subject: [PATCH 002/201] perf stat: Move STAT_RECORD out of
|
||||
perf_evlist__print_counters()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v4.20-rc1
|
||||
commit 0174820a8ba108f2e72dac5caaea3500c8ca6323
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0174820a8ba108f2e72dac5caaea3500c8ca6323
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
It's stat related and should stay in the 'perf stat' command. The
|
||||
perf_evlist__print_counters function will be moved out in the following
|
||||
patches.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20180830063252.23729-17-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-stat.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index 48327256f0bf..78dfefd6f49a 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -1836,10 +1836,6 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
struct perf_evsel *counter;
|
||||
char buf[64], *prefix = NULL;
|
||||
|
||||
- /* Do not print anything if we record to the pipe. */
|
||||
- if (STAT_RECORD && perf_stat.data.is_pipe)
|
||||
- return;
|
||||
-
|
||||
if (interval)
|
||||
print_interval(prefix = buf, ts);
|
||||
else
|
||||
@@ -1901,6 +1897,10 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
|
||||
static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
{
|
||||
+ /* Do not print anything if we record to the pipe. */
|
||||
+ if (STAT_RECORD && perf_stat.data.is_pipe)
|
||||
+ return;
|
||||
+
|
||||
perf_evlist__print_counters(evsel_list, ts, argc, argv);
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
From 36827ecfdf56b255245f4ed510b2d2b2fdba0ddf Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 30 Aug 2018 08:32:26 +0200
|
||||
Subject: [PATCH 003/201] perf stat: Add 'struct perf_stat_config' argument to
|
||||
perf_evlist__print_counters()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v4.20-rc1
|
||||
commit b64df7f33743cd6095b4a007f5f15ff4432fbcf5
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b64df7f33743cd6095b4a007f5f15ff4432fbcf5
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Add a 'struct perf_stat_config' argument to perf_evlist__print_counters(),
|
||||
so that it can be moved out of the 'perf stat' command to generic object
|
||||
in the following patches.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20180830063252.23729-18-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-stat.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index 78dfefd6f49a..c35307ea6110 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -1829,10 +1829,11 @@ static void print_footer(void)
|
||||
|
||||
static void
|
||||
perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
+ struct perf_stat_config *config,
|
||||
struct timespec *ts,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
- int interval = stat_config.interval;
|
||||
+ int interval = config->interval;
|
||||
struct perf_evsel *counter;
|
||||
char buf[64], *prefix = NULL;
|
||||
|
||||
@@ -1848,11 +1849,11 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
print_metric_headers(prefix, false);
|
||||
if (num_print_iv++ == 25)
|
||||
num_print_iv = 0;
|
||||
- if (stat_config.aggr_mode == AGGR_GLOBAL && prefix)
|
||||
- fprintf(stat_config.output, "%s", prefix);
|
||||
+ if (config->aggr_mode == AGGR_GLOBAL && prefix)
|
||||
+ fprintf(config->output, "%s", prefix);
|
||||
}
|
||||
|
||||
- switch (stat_config.aggr_mode) {
|
||||
+ switch (config->aggr_mode) {
|
||||
case AGGR_CORE:
|
||||
case AGGR_SOCKET:
|
||||
print_aggr(prefix);
|
||||
@@ -1871,7 +1872,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
print_counter_aggr(counter, prefix);
|
||||
}
|
||||
if (metric_only)
|
||||
- fputc('\n', stat_config.output);
|
||||
+ fputc('\n', config->output);
|
||||
break;
|
||||
case AGGR_NONE:
|
||||
if (metric_only)
|
||||
@@ -1892,7 +1893,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
if (!interval && !csv_output)
|
||||
print_footer();
|
||||
|
||||
- fflush(stat_config.output);
|
||||
+ fflush(config->output);
|
||||
}
|
||||
|
||||
static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
@@ -1901,7 +1902,8 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
if (STAT_RECORD && perf_stat.data.is_pipe)
|
||||
return;
|
||||
|
||||
- perf_evlist__print_counters(evsel_list, ts, argc, argv);
|
||||
+ perf_evlist__print_counters(evsel_list, &stat_config,
|
||||
+ ts, argc, argv);
|
||||
}
|
||||
|
||||
static volatile int signr = -1;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,471 @@
|
||||
From bf2703eb25ea734092e4749e7723f3d6a635bb7d Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 30 Aug 2018 08:32:27 +0200
|
||||
Subject: [PATCH 004/201] perf stat: Pass 'struct perf_stat_config' argument to
|
||||
local print functions
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v4.20-rc1
|
||||
commit f3ca50e61ff4aebfbefc666be2e064d277ad524c
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f3ca50e61ff4aebfbefc666be2e064d277ad524c
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Add 'struct perf_stat_config' argument to print functions, so that those
|
||||
functions can be moved out of the 'perf stat' command to a generic class
|
||||
in the following patches.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20180830063252.23729-19-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-stat.c | 149 ++++++++++++++++++++------------------
|
||||
1 file changed, 80 insertions(+), 69 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index c35307ea6110..267b2cc9e73a 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -795,30 +795,33 @@ static int run_perf_stat(int argc, const char **argv, int run_idx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void print_running(u64 run, u64 ena)
|
||||
+static void print_running(struct perf_stat_config *config,
|
||||
+ u64 run, u64 ena)
|
||||
{
|
||||
if (csv_output) {
|
||||
- fprintf(stat_config.output, "%s%" PRIu64 "%s%.2f",
|
||||
+ fprintf(config->output, "%s%" PRIu64 "%s%.2f",
|
||||
csv_sep,
|
||||
run,
|
||||
csv_sep,
|
||||
ena ? 100.0 * run / ena : 100.0);
|
||||
} else if (run != ena) {
|
||||
- fprintf(stat_config.output, " (%.2f%%)", 100.0 * run / ena);
|
||||
+ fprintf(config->output, " (%.2f%%)", 100.0 * run / ena);
|
||||
}
|
||||
}
|
||||
|
||||
-static void print_noise_pct(double total, double avg)
|
||||
+static void print_noise_pct(struct perf_stat_config *config,
|
||||
+ double total, double avg)
|
||||
{
|
||||
double pct = rel_stddev_stats(total, avg);
|
||||
|
||||
if (csv_output)
|
||||
- fprintf(stat_config.output, "%s%.2f%%", csv_sep, pct);
|
||||
+ fprintf(config->output, "%s%.2f%%", csv_sep, pct);
|
||||
else if (pct)
|
||||
- fprintf(stat_config.output, " ( +-%6.2f%% )", pct);
|
||||
+ fprintf(config->output, " ( +-%6.2f%% )", pct);
|
||||
}
|
||||
|
||||
-static void print_noise(struct perf_evsel *evsel, double avg)
|
||||
+static void print_noise(struct perf_stat_config *config,
|
||||
+ struct perf_evsel *evsel, double avg)
|
||||
{
|
||||
struct perf_stat_evsel *ps;
|
||||
|
||||
@@ -826,7 +829,7 @@ static void print_noise(struct perf_evsel *evsel, double avg)
|
||||
return;
|
||||
|
||||
ps = evsel->stats;
|
||||
- print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
|
||||
+ print_noise_pct(config, stddev_stats(&ps->res_stats[0]), avg);
|
||||
}
|
||||
|
||||
static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
|
||||
@@ -1122,13 +1125,14 @@ static bool is_mixed_hw_group(struct perf_evsel *counter)
|
||||
return false;
|
||||
}
|
||||
|
||||
-static void printout(int id, int nr, struct perf_evsel *counter, double uval,
|
||||
+static void printout(struct perf_stat_config *config, int id, int nr,
|
||||
+ struct perf_evsel *counter, double uval,
|
||||
char *prefix, u64 run, u64 ena, double noise,
|
||||
struct runtime_stat *st)
|
||||
{
|
||||
struct perf_stat_output_ctx out;
|
||||
struct outstate os = {
|
||||
- .fh = stat_config.output,
|
||||
+ .fh = config->output,
|
||||
.prefix = prefix ? prefix : "",
|
||||
.id = id,
|
||||
.nr = nr,
|
||||
@@ -1158,7 +1162,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
|
||||
pm = print_metric_csv;
|
||||
nl = new_line_csv;
|
||||
os.nfields = 3;
|
||||
- os.nfields += aggr_fields[stat_config.aggr_mode];
|
||||
+ os.nfields += aggr_fields[config->aggr_mode];
|
||||
if (counter->cgrp)
|
||||
os.nfields++;
|
||||
}
|
||||
@@ -1169,7 +1173,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
|
||||
}
|
||||
aggr_printout(counter, id, nr);
|
||||
|
||||
- fprintf(stat_config.output, "%*s%s",
|
||||
+ fprintf(config->output, "%*s%s",
|
||||
csv_output ? 0 : 18,
|
||||
counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
|
||||
csv_sep);
|
||||
@@ -1180,22 +1184,22 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
|
||||
print_mixed_hw_group_error = 1;
|
||||
}
|
||||
|
||||
- fprintf(stat_config.output, "%-*s%s",
|
||||
+ fprintf(config->output, "%-*s%s",
|
||||
csv_output ? 0 : unit_width,
|
||||
counter->unit, csv_sep);
|
||||
|
||||
- fprintf(stat_config.output, "%*s",
|
||||
+ fprintf(config->output, "%*s",
|
||||
csv_output ? 0 : -25,
|
||||
perf_evsel__name(counter));
|
||||
|
||||
if (counter->cgrp)
|
||||
- fprintf(stat_config.output, "%s%s",
|
||||
+ fprintf(config->output, "%s%s",
|
||||
csv_sep, counter->cgrp->name);
|
||||
|
||||
if (!csv_output)
|
||||
pm(&os, NULL, NULL, "", 0);
|
||||
- print_noise(counter, noise);
|
||||
- print_running(run, ena);
|
||||
+ print_noise(config, counter, noise);
|
||||
+ print_running(config, run, ena);
|
||||
if (csv_output)
|
||||
pm(&os, NULL, NULL, "", 0);
|
||||
return;
|
||||
@@ -1210,16 +1214,16 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
|
||||
out.force_header = false;
|
||||
|
||||
if (csv_output && !metric_only) {
|
||||
- print_noise(counter, noise);
|
||||
- print_running(run, ena);
|
||||
+ print_noise(config, counter, noise);
|
||||
+ print_running(config, run, ena);
|
||||
}
|
||||
|
||||
perf_stat__print_shadow_stats(counter, uval,
|
||||
first_shadow_cpu(counter, id),
|
||||
&out, &metric_events, st);
|
||||
if (!csv_output && !metric_only) {
|
||||
- print_noise(counter, noise);
|
||||
- print_running(run, ena);
|
||||
+ print_noise(config, counter, noise);
|
||||
+ print_running(config, run, ena);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1346,9 +1350,10 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first)
|
||||
}
|
||||
}
|
||||
|
||||
-static void print_aggr(char *prefix)
|
||||
+static void print_aggr(struct perf_stat_config *config,
|
||||
+ char *prefix)
|
||||
{
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
struct perf_evsel *counter;
|
||||
int s, id, nr;
|
||||
double uval;
|
||||
@@ -1391,8 +1396,8 @@ static void print_aggr(char *prefix)
|
||||
fprintf(output, "%s", prefix);
|
||||
|
||||
uval = val * counter->scale;
|
||||
- printout(id, nr, counter, uval, prefix, run, ena, 1.0,
|
||||
- &rt_stat);
|
||||
+ printout(config, id, nr, counter, uval, prefix,
|
||||
+ run, ena, 1.0, &rt_stat);
|
||||
if (!metric_only)
|
||||
fputc('\n', output);
|
||||
}
|
||||
@@ -1455,9 +1460,10 @@ static struct perf_aggr_thread_value *sort_aggr_thread(
|
||||
return buf;
|
||||
}
|
||||
|
||||
-static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
|
||||
+static void print_aggr_thread(struct perf_stat_config *config,
|
||||
+ struct perf_evsel *counter, char *prefix)
|
||||
{
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
int nthreads = thread_map__nr(counter->threads);
|
||||
int ncpus = cpu_map__nr(counter->cpus);
|
||||
int thread, sorted_threads, id;
|
||||
@@ -1474,12 +1480,12 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
|
||||
fprintf(output, "%s", prefix);
|
||||
|
||||
id = buf[thread].id;
|
||||
- if (stat_config.stats)
|
||||
- printout(id, 0, buf[thread].counter, buf[thread].uval,
|
||||
+ if (config->stats)
|
||||
+ printout(config, id, 0, buf[thread].counter, buf[thread].uval,
|
||||
prefix, buf[thread].run, buf[thread].ena, 1.0,
|
||||
- &stat_config.stats[id]);
|
||||
+ &config->stats[id]);
|
||||
else
|
||||
- printout(id, 0, buf[thread].counter, buf[thread].uval,
|
||||
+ printout(config, id, 0, buf[thread].counter, buf[thread].uval,
|
||||
prefix, buf[thread].run, buf[thread].ena, 1.0,
|
||||
&rt_stat);
|
||||
fputc('\n', output);
|
||||
@@ -1507,9 +1513,10 @@ static void counter_aggr_cb(struct perf_evsel *counter, void *data,
|
||||
* Print out the results of a single counter:
|
||||
* aggregated counts in system-wide mode
|
||||
*/
|
||||
-static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
|
||||
+static void print_counter_aggr(struct perf_stat_config *config,
|
||||
+ struct perf_evsel *counter, char *prefix)
|
||||
{
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
double uval;
|
||||
struct caggr_data cd = { .avg = 0.0 };
|
||||
|
||||
@@ -1520,7 +1527,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
|
||||
fprintf(output, "%s", prefix);
|
||||
|
||||
uval = cd.avg * counter->scale;
|
||||
- printout(-1, 0, counter, uval, prefix, cd.avg_running, cd.avg_enabled,
|
||||
+ printout(config, -1, 0, counter, uval, prefix, cd.avg_running, cd.avg_enabled,
|
||||
cd.avg, &rt_stat);
|
||||
if (!metric_only)
|
||||
fprintf(output, "\n");
|
||||
@@ -1540,9 +1547,10 @@ static void counter_cb(struct perf_evsel *counter, void *data,
|
||||
* Print out the results of a single counter:
|
||||
* does not use aggregated count in system-wide
|
||||
*/
|
||||
-static void print_counter(struct perf_evsel *counter, char *prefix)
|
||||
+static void print_counter(struct perf_stat_config *config,
|
||||
+ struct perf_evsel *counter, char *prefix)
|
||||
{
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
u64 ena, run, val;
|
||||
double uval;
|
||||
int cpu;
|
||||
@@ -1560,14 +1568,15 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
|
||||
fprintf(output, "%s", prefix);
|
||||
|
||||
uval = val * counter->scale;
|
||||
- printout(cpu, 0, counter, uval, prefix, run, ena, 1.0,
|
||||
+ printout(config, cpu, 0, counter, uval, prefix, run, ena, 1.0,
|
||||
&rt_stat);
|
||||
|
||||
fputc('\n', output);
|
||||
}
|
||||
}
|
||||
|
||||
-static void print_no_aggr_metric(char *prefix)
|
||||
+static void print_no_aggr_metric(struct perf_stat_config *config,
|
||||
+ char *prefix)
|
||||
{
|
||||
int cpu;
|
||||
int nrcpus = 0;
|
||||
@@ -1580,7 +1589,7 @@ static void print_no_aggr_metric(char *prefix)
|
||||
bool first = true;
|
||||
|
||||
if (prefix)
|
||||
- fputs(prefix, stat_config.output);
|
||||
+ fputs(prefix, config->output);
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
@@ -1593,10 +1602,10 @@ static void print_no_aggr_metric(char *prefix)
|
||||
run = perf_counts(counter->counts, cpu, 0)->run;
|
||||
|
||||
uval = val * counter->scale;
|
||||
- printout(cpu, 0, counter, uval, prefix, run, ena, 1.0,
|
||||
+ printout(config, cpu, 0, counter, uval, prefix, run, ena, 1.0,
|
||||
&rt_stat);
|
||||
}
|
||||
- fputc('\n', stat_config.output);
|
||||
+ fputc('\n', config->output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1616,25 +1625,25 @@ static const char *aggr_header_csv[] = {
|
||||
[AGGR_GLOBAL] = ""
|
||||
};
|
||||
|
||||
-static void print_metric_headers(const char *prefix, bool no_indent)
|
||||
+static void print_metric_headers(struct perf_stat_config *config,
|
||||
+ const char *prefix, bool no_indent)
|
||||
{
|
||||
struct perf_stat_output_ctx out;
|
||||
struct perf_evsel *counter;
|
||||
struct outstate os = {
|
||||
- .fh = stat_config.output
|
||||
+ .fh = config->output
|
||||
};
|
||||
|
||||
if (prefix)
|
||||
- fprintf(stat_config.output, "%s", prefix);
|
||||
+ fprintf(config->output, "%s", prefix);
|
||||
|
||||
if (!csv_output && !no_indent)
|
||||
- fprintf(stat_config.output, "%*s",
|
||||
- aggr_header_lens[stat_config.aggr_mode], "");
|
||||
+ fprintf(config->output, "%*s",
|
||||
+ aggr_header_lens[config->aggr_mode], "");
|
||||
if (csv_output) {
|
||||
- if (stat_config.interval)
|
||||
- fputs("time,", stat_config.output);
|
||||
- fputs(aggr_header_csv[stat_config.aggr_mode],
|
||||
- stat_config.output);
|
||||
+ if (config->interval)
|
||||
+ fputs("time,", config->output);
|
||||
+ fputs(aggr_header_csv[config->aggr_mode], config->output);
|
||||
}
|
||||
|
||||
/* Print metrics headers only */
|
||||
@@ -1653,12 +1662,13 @@ static void print_metric_headers(const char *prefix, bool no_indent)
|
||||
&metric_events,
|
||||
&rt_stat);
|
||||
}
|
||||
- fputc('\n', stat_config.output);
|
||||
+ fputc('\n', config->output);
|
||||
}
|
||||
|
||||
-static void print_interval(char *prefix, struct timespec *ts)
|
||||
+static void print_interval(struct perf_stat_config *config,
|
||||
+ char *prefix, struct timespec *ts)
|
||||
{
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
static int num_print_interval;
|
||||
|
||||
if (interval_clear)
|
||||
@@ -1667,7 +1677,7 @@ static void print_interval(char *prefix, struct timespec *ts)
|
||||
sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
|
||||
|
||||
if ((num_print_interval == 0 && !csv_output) || interval_clear) {
|
||||
- switch (stat_config.aggr_mode) {
|
||||
+ switch (config->aggr_mode) {
|
||||
case AGGR_SOCKET:
|
||||
fprintf(output, "# time socket cpus");
|
||||
if (!metric_only)
|
||||
@@ -1699,14 +1709,15 @@ static void print_interval(char *prefix, struct timespec *ts)
|
||||
}
|
||||
|
||||
if ((num_print_interval == 0 || interval_clear) && metric_only)
|
||||
- print_metric_headers(" ", true);
|
||||
+ print_metric_headers(config, " ", true);
|
||||
if (++num_print_interval == 25)
|
||||
num_print_interval = 0;
|
||||
}
|
||||
|
||||
-static void print_header(int argc, const char **argv)
|
||||
+static void print_header(struct perf_stat_config *config,
|
||||
+ int argc, const char **argv)
|
||||
{
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
int i;
|
||||
|
||||
fflush(stdout);
|
||||
@@ -1774,10 +1785,10 @@ static double timeval2double(struct timeval *t)
|
||||
return t->tv_sec + (double) t->tv_usec/USEC_PER_SEC;
|
||||
}
|
||||
|
||||
-static void print_footer(void)
|
||||
+static void print_footer(struct perf_stat_config *config)
|
||||
{
|
||||
double avg = avg_stats(&walltime_nsecs_stats) / NSEC_PER_SEC;
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
int n;
|
||||
|
||||
if (!null_run)
|
||||
@@ -1808,7 +1819,7 @@ static void print_footer(void)
|
||||
fprintf(output, " %17.*f +- %.*f seconds time elapsed",
|
||||
precision, avg, precision, sd);
|
||||
|
||||
- print_noise_pct(sd, avg);
|
||||
+ print_noise_pct(config, sd, avg);
|
||||
}
|
||||
fprintf(output, "\n\n");
|
||||
|
||||
@@ -1838,15 +1849,15 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
char buf[64], *prefix = NULL;
|
||||
|
||||
if (interval)
|
||||
- print_interval(prefix = buf, ts);
|
||||
+ print_interval(config, prefix = buf, ts);
|
||||
else
|
||||
- print_header(argc, argv);
|
||||
+ print_header(config, argc, argv);
|
||||
|
||||
if (metric_only) {
|
||||
static int num_print_iv;
|
||||
|
||||
if (num_print_iv == 0 && !interval)
|
||||
- print_metric_headers(prefix, false);
|
||||
+ print_metric_headers(config, prefix, false);
|
||||
if (num_print_iv++ == 25)
|
||||
num_print_iv = 0;
|
||||
if (config->aggr_mode == AGGR_GLOBAL && prefix)
|
||||
@@ -1856,32 +1867,32 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
switch (config->aggr_mode) {
|
||||
case AGGR_CORE:
|
||||
case AGGR_SOCKET:
|
||||
- print_aggr(prefix);
|
||||
+ print_aggr(config, prefix);
|
||||
break;
|
||||
case AGGR_THREAD:
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
- print_aggr_thread(counter, prefix);
|
||||
+ print_aggr_thread(config, counter, prefix);
|
||||
}
|
||||
break;
|
||||
case AGGR_GLOBAL:
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
- print_counter_aggr(counter, prefix);
|
||||
+ print_counter_aggr(config, counter, prefix);
|
||||
}
|
||||
if (metric_only)
|
||||
fputc('\n', config->output);
|
||||
break;
|
||||
case AGGR_NONE:
|
||||
if (metric_only)
|
||||
- print_no_aggr_metric(prefix);
|
||||
+ print_no_aggr_metric(config, prefix);
|
||||
else {
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
- print_counter(counter, prefix);
|
||||
+ print_counter(config, counter, prefix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1891,7 +1902,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
}
|
||||
|
||||
if (!interval && !csv_output)
|
||||
- print_footer();
|
||||
+ print_footer(config);
|
||||
|
||||
fflush(config->output);
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,772 @@
|
||||
From 3f9d26228fa45a37759308d29e22d64330a5e17c Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 30 Aug 2018 08:32:28 +0200
|
||||
Subject: [PATCH 005/201] perf stat: Pass a 'struct perf_stat_config' argument
|
||||
to global print functions
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v4.20-rc1
|
||||
commit 6ca9a082b1908ff7f8adedf08166043b83b266f6
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6ca9a082b1908ff7f8adedf08166043b83b266f6
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add 'struct perf_stat_config' argument to the global print functions, so
|
||||
that these functions can be used out of the 'perf stat' command code.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20180830063252.23729-20-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-script.c | 8 +-
|
||||
tools/perf/builtin-stat.c | 74 +++++++++--------
|
||||
tools/perf/util/stat-shadow.c | 147 ++++++++++++++++++----------------
|
||||
tools/perf/util/stat.h | 8 +-
|
||||
4 files changed, 131 insertions(+), 106 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
|
||||
index b8162ded720e..607dd95b5c34 100644
|
||||
--- a/tools/perf/builtin-script.c
|
||||
+++ b/tools/perf/builtin-script.c
|
||||
@@ -1548,7 +1548,8 @@ struct metric_ctx {
|
||||
FILE *fp;
|
||||
};
|
||||
|
||||
-static void script_print_metric(void *ctx, const char *color,
|
||||
+static void script_print_metric(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx, const char *color,
|
||||
const char *fmt,
|
||||
const char *unit, double val)
|
||||
{
|
||||
@@ -1566,7 +1567,8 @@ static void script_print_metric(void *ctx, const char *color,
|
||||
fprintf(mctx->fp, " %s\n", unit);
|
||||
}
|
||||
|
||||
-static void script_new_line(void *ctx)
|
||||
+static void script_new_line(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx)
|
||||
{
|
||||
struct metric_ctx *mctx = ctx;
|
||||
|
||||
@@ -1607,7 +1609,7 @@ static void perf_sample__fprint_metric(struct perf_script *script,
|
||||
evsel_script(evsel)->val = val;
|
||||
if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) {
|
||||
for_each_group_member (ev2, evsel->leader) {
|
||||
- perf_stat__print_shadow_stats(ev2,
|
||||
+ perf_stat__print_shadow_stats(&stat_config, ev2,
|
||||
evsel_script(ev2)->val,
|
||||
sample->cpu,
|
||||
&ctx,
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index 267b2cc9e73a..651fef3c92de 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -832,11 +832,12 @@ static void print_noise(struct perf_stat_config *config,
|
||||
print_noise_pct(config, stddev_stats(&ps->res_stats[0]), avg);
|
||||
}
|
||||
|
||||
-static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
|
||||
+static void aggr_printout(struct perf_stat_config *config,
|
||||
+ struct perf_evsel *evsel, int id, int nr)
|
||||
{
|
||||
- switch (stat_config.aggr_mode) {
|
||||
+ switch (config->aggr_mode) {
|
||||
case AGGR_CORE:
|
||||
- fprintf(stat_config.output, "S%d-C%*d%s%*d%s",
|
||||
+ fprintf(config->output, "S%d-C%*d%s%*d%s",
|
||||
cpu_map__id_to_socket(id),
|
||||
csv_output ? 0 : -8,
|
||||
cpu_map__id_to_cpu(id),
|
||||
@@ -846,7 +847,7 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
|
||||
csv_sep);
|
||||
break;
|
||||
case AGGR_SOCKET:
|
||||
- fprintf(stat_config.output, "S%*d%s%*d%s",
|
||||
+ fprintf(config->output, "S%*d%s%*d%s",
|
||||
csv_output ? 0 : -5,
|
||||
id,
|
||||
csv_sep,
|
||||
@@ -855,12 +856,12 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
|
||||
csv_sep);
|
||||
break;
|
||||
case AGGR_NONE:
|
||||
- fprintf(stat_config.output, "CPU%*d%s",
|
||||
+ fprintf(config->output, "CPU%*d%s",
|
||||
csv_output ? 0 : -4,
|
||||
perf_evsel__cpus(evsel)->map[id], csv_sep);
|
||||
break;
|
||||
case AGGR_THREAD:
|
||||
- fprintf(stat_config.output, "%*s-%*d%s",
|
||||
+ fprintf(config->output, "%*s-%*d%s",
|
||||
csv_output ? 0 : 16,
|
||||
thread_map__comm(evsel->threads, id),
|
||||
csv_output ? 0 : -8,
|
||||
@@ -885,24 +886,27 @@ struct outstate {
|
||||
|
||||
#define METRIC_LEN 35
|
||||
|
||||
-static void new_line_std(void *ctx)
|
||||
+static void new_line_std(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx)
|
||||
{
|
||||
struct outstate *os = ctx;
|
||||
|
||||
os->newline = true;
|
||||
}
|
||||
|
||||
-static void do_new_line_std(struct outstate *os)
|
||||
+static void do_new_line_std(struct perf_stat_config *config,
|
||||
+ struct outstate *os)
|
||||
{
|
||||
fputc('\n', os->fh);
|
||||
fputs(os->prefix, os->fh);
|
||||
- aggr_printout(os->evsel, os->id, os->nr);
|
||||
- if (stat_config.aggr_mode == AGGR_NONE)
|
||||
+ aggr_printout(config, os->evsel, os->id, os->nr);
|
||||
+ if (config->aggr_mode == AGGR_NONE)
|
||||
fprintf(os->fh, " ");
|
||||
fprintf(os->fh, " ");
|
||||
}
|
||||
|
||||
-static void print_metric_std(void *ctx, const char *color, const char *fmt,
|
||||
+static void print_metric_std(struct perf_stat_config *config,
|
||||
+ void *ctx, const char *color, const char *fmt,
|
||||
const char *unit, double val)
|
||||
{
|
||||
struct outstate *os = ctx;
|
||||
@@ -918,7 +922,7 @@ static void print_metric_std(void *ctx, const char *color, const char *fmt,
|
||||
}
|
||||
|
||||
if (newline)
|
||||
- do_new_line_std(os);
|
||||
+ do_new_line_std(config, os);
|
||||
|
||||
n = fprintf(out, " # ");
|
||||
if (color)
|
||||
@@ -928,7 +932,7 @@ static void print_metric_std(void *ctx, const char *color, const char *fmt,
|
||||
fprintf(out, " %-*s", METRIC_LEN - n - 1, unit);
|
||||
}
|
||||
|
||||
-static void new_line_csv(void *ctx)
|
||||
+static void new_line_csv(struct perf_stat_config *config, void *ctx)
|
||||
{
|
||||
struct outstate *os = ctx;
|
||||
int i;
|
||||
@@ -936,12 +940,13 @@ static void new_line_csv(void *ctx)
|
||||
fputc('\n', os->fh);
|
||||
if (os->prefix)
|
||||
fprintf(os->fh, "%s%s", os->prefix, csv_sep);
|
||||
- aggr_printout(os->evsel, os->id, os->nr);
|
||||
+ aggr_printout(config, os->evsel, os->id, os->nr);
|
||||
for (i = 0; i < os->nfields; i++)
|
||||
fputs(csv_sep, os->fh);
|
||||
}
|
||||
|
||||
-static void print_metric_csv(void *ctx,
|
||||
+static void print_metric_csv(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx,
|
||||
const char *color __maybe_unused,
|
||||
const char *fmt, const char *unit, double val)
|
||||
{
|
||||
@@ -988,7 +993,8 @@ static const char *fixunit(char *buf, struct perf_evsel *evsel,
|
||||
return unit;
|
||||
}
|
||||
|
||||
-static void print_metric_only(void *ctx, const char *color, const char *fmt,
|
||||
+static void print_metric_only(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx, const char *color, const char *fmt,
|
||||
const char *unit, double val)
|
||||
{
|
||||
struct outstate *os = ctx;
|
||||
@@ -1009,7 +1015,8 @@ static void print_metric_only(void *ctx, const char *color, const char *fmt,
|
||||
fprintf(out, "%*s ", mlen, str);
|
||||
}
|
||||
|
||||
-static void print_metric_only_csv(void *ctx, const char *color __maybe_unused,
|
||||
+static void print_metric_only_csv(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx, const char *color __maybe_unused,
|
||||
const char *fmt,
|
||||
const char *unit, double val)
|
||||
{
|
||||
@@ -1029,11 +1036,13 @@ static void print_metric_only_csv(void *ctx, const char *color __maybe_unused,
|
||||
fprintf(out, "%s%s", vals, csv_sep);
|
||||
}
|
||||
|
||||
-static void new_line_metric(void *ctx __maybe_unused)
|
||||
+static void new_line_metric(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx __maybe_unused)
|
||||
{
|
||||
}
|
||||
|
||||
-static void print_metric_header(void *ctx, const char *color __maybe_unused,
|
||||
+static void print_metric_header(struct perf_stat_config *config __maybe_unused,
|
||||
+ void *ctx, const char *color __maybe_unused,
|
||||
const char *fmt __maybe_unused,
|
||||
const char *unit, double val __maybe_unused)
|
||||
{
|
||||
@@ -1071,9 +1080,10 @@ static int first_shadow_cpu(struct perf_evsel *evsel, int id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
|
||||
+static void abs_printout(struct perf_stat_config *config,
|
||||
+ int id, int nr, struct perf_evsel *evsel, double avg)
|
||||
{
|
||||
- FILE *output = stat_config.output;
|
||||
+ FILE *output = config->output;
|
||||
double sc = evsel->scale;
|
||||
const char *fmt;
|
||||
|
||||
@@ -1086,7 +1096,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
|
||||
fmt = floor(sc) != sc ? "%18.2f%s" : "%18.0f%s";
|
||||
}
|
||||
|
||||
- aggr_printout(evsel, id, nr);
|
||||
+ aggr_printout(config, evsel, id, nr);
|
||||
|
||||
fprintf(output, fmt, avg, csv_sep);
|
||||
|
||||
@@ -1139,7 +1149,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,
|
||||
.evsel = counter,
|
||||
};
|
||||
print_metric_t pm = print_metric_std;
|
||||
- void (*nl)(void *);
|
||||
+ new_line_t nl;
|
||||
|
||||
if (metric_only) {
|
||||
nl = new_line_metric;
|
||||
@@ -1168,10 +1178,10 @@ static void printout(struct perf_stat_config *config, int id, int nr,
|
||||
}
|
||||
if (run == 0 || ena == 0 || counter->counts->scaled == -1) {
|
||||
if (metric_only) {
|
||||
- pm(&os, NULL, "", "", 0);
|
||||
+ pm(config, &os, NULL, "", "", 0);
|
||||
return;
|
||||
}
|
||||
- aggr_printout(counter, id, nr);
|
||||
+ aggr_printout(config, counter, id, nr);
|
||||
|
||||
fprintf(config->output, "%*s%s",
|
||||
csv_output ? 0 : 18,
|
||||
@@ -1197,16 +1207,16 @@ static void printout(struct perf_stat_config *config, int id, int nr,
|
||||
csv_sep, counter->cgrp->name);
|
||||
|
||||
if (!csv_output)
|
||||
- pm(&os, NULL, NULL, "", 0);
|
||||
+ pm(config, &os, NULL, NULL, "", 0);
|
||||
print_noise(config, counter, noise);
|
||||
print_running(config, run, ena);
|
||||
if (csv_output)
|
||||
- pm(&os, NULL, NULL, "", 0);
|
||||
+ pm(config, &os, NULL, NULL, "", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!metric_only)
|
||||
- abs_printout(id, nr, counter, uval);
|
||||
+ abs_printout(config, id, nr, counter, uval);
|
||||
|
||||
out.print_metric = pm;
|
||||
out.new_line = nl;
|
||||
@@ -1218,7 +1228,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,
|
||||
print_running(config, run, ena);
|
||||
}
|
||||
|
||||
- perf_stat__print_shadow_stats(counter, uval,
|
||||
+ perf_stat__print_shadow_stats(config, counter, uval,
|
||||
first_shadow_cpu(counter, id),
|
||||
&out, &metric_events, st);
|
||||
if (!csv_output && !metric_only) {
|
||||
@@ -1390,7 +1400,7 @@ static void print_aggr(struct perf_stat_config *config,
|
||||
val = ad.val;
|
||||
if (first && metric_only) {
|
||||
first = false;
|
||||
- aggr_printout(counter, id, nr);
|
||||
+ aggr_printout(config, counter, id, nr);
|
||||
}
|
||||
if (prefix && !metric_only)
|
||||
fprintf(output, "%s", prefix);
|
||||
@@ -1594,7 +1604,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
|
||||
if (is_duration_time(counter))
|
||||
continue;
|
||||
if (first) {
|
||||
- aggr_printout(counter, cpu, 0);
|
||||
+ aggr_printout(config, counter, cpu, 0);
|
||||
first = false;
|
||||
}
|
||||
val = perf_counts(counter->counts, cpu, 0)->val;
|
||||
@@ -1656,7 +1666,7 @@ static void print_metric_headers(struct perf_stat_config *config,
|
||||
out.new_line = new_line_metric;
|
||||
out.force_header = true;
|
||||
os.evsel = counter;
|
||||
- perf_stat__print_shadow_stats(counter, 0,
|
||||
+ perf_stat__print_shadow_stats(config, counter, 0,
|
||||
0,
|
||||
&out,
|
||||
&metric_events,
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index 59475287e2e1..93c075ddc717 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -411,7 +411,8 @@ static double runtime_stat_n(struct runtime_stat *st,
|
||||
return v->stats.n;
|
||||
}
|
||||
|
||||
-static void print_stalled_cycles_frontend(int cpu,
|
||||
+static void print_stalled_cycles_frontend(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel, double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
struct runtime_stat *st)
|
||||
@@ -428,13 +429,14 @@ static void print_stalled_cycles_frontend(int cpu,
|
||||
color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
|
||||
|
||||
if (ratio)
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "frontend cycles idle",
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "frontend cycles idle",
|
||||
ratio);
|
||||
else
|
||||
- out->print_metric(out->ctx, NULL, NULL, "frontend cycles idle", 0);
|
||||
+ out->print_metric(config, out->ctx, NULL, NULL, "frontend cycles idle", 0);
|
||||
}
|
||||
|
||||
-static void print_stalled_cycles_backend(int cpu,
|
||||
+static void print_stalled_cycles_backend(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel, double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
struct runtime_stat *st)
|
||||
@@ -450,10 +452,11 @@ static void print_stalled_cycles_backend(int cpu,
|
||||
|
||||
color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
|
||||
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "backend cycles idle", ratio);
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "backend cycles idle", ratio);
|
||||
}
|
||||
|
||||
-static void print_branch_misses(int cpu,
|
||||
+static void print_branch_misses(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel,
|
||||
double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -470,10 +473,11 @@ static void print_branch_misses(int cpu,
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "of all branches", ratio);
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "of all branches", ratio);
|
||||
}
|
||||
|
||||
-static void print_l1_dcache_misses(int cpu,
|
||||
+static void print_l1_dcache_misses(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel,
|
||||
double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -491,10 +495,11 @@ static void print_l1_dcache_misses(int cpu,
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "of all L1-dcache hits", ratio);
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-dcache hits", ratio);
|
||||
}
|
||||
|
||||
-static void print_l1_icache_misses(int cpu,
|
||||
+static void print_l1_icache_misses(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel,
|
||||
double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -511,10 +516,11 @@ static void print_l1_icache_misses(int cpu,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "of all L1-icache hits", ratio);
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-icache hits", ratio);
|
||||
}
|
||||
|
||||
-static void print_dtlb_cache_misses(int cpu,
|
||||
+static void print_dtlb_cache_misses(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel,
|
||||
double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -530,10 +536,11 @@ static void print_dtlb_cache_misses(int cpu,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "of all dTLB cache hits", ratio);
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "of all dTLB cache hits", ratio);
|
||||
}
|
||||
|
||||
-static void print_itlb_cache_misses(int cpu,
|
||||
+static void print_itlb_cache_misses(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel,
|
||||
double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -549,10 +556,11 @@ static void print_itlb_cache_misses(int cpu,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "of all iTLB cache hits", ratio);
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "of all iTLB cache hits", ratio);
|
||||
}
|
||||
|
||||
-static void print_ll_cache_misses(int cpu,
|
||||
+static void print_ll_cache_misses(struct perf_stat_config *config,
|
||||
+ int cpu,
|
||||
struct perf_evsel *evsel,
|
||||
double avg,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -568,7 +576,7 @@ static void print_ll_cache_misses(int cpu,
|
||||
ratio = avg / total * 100.0;
|
||||
|
||||
color = get_ratio_color(GRC_CACHE_MISSES, ratio);
|
||||
- out->print_metric(out->ctx, color, "%7.2f%%", "of all LL-cache hits", ratio);
|
||||
+ out->print_metric(config, out->ctx, color, "%7.2f%%", "of all LL-cache hits", ratio);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -675,7 +683,8 @@ static double td_be_bound(int ctx, int cpu, struct runtime_stat *st)
|
||||
return sanitize_val(1.0 - sum);
|
||||
}
|
||||
|
||||
-static void print_smi_cost(int cpu, struct perf_evsel *evsel,
|
||||
+static void print_smi_cost(struct perf_stat_config *config,
|
||||
+ int cpu, struct perf_evsel *evsel,
|
||||
struct perf_stat_output_ctx *out,
|
||||
struct runtime_stat *st)
|
||||
{
|
||||
@@ -695,11 +704,12 @@ static void print_smi_cost(int cpu, struct perf_evsel *evsel,
|
||||
|
||||
if (cost > 10)
|
||||
color = PERF_COLOR_RED;
|
||||
- out->print_metric(out->ctx, color, "%8.1f%%", "SMI cycles%", cost);
|
||||
- out->print_metric(out->ctx, NULL, "%4.0f", "SMI#", smi_num);
|
||||
+ out->print_metric(config, out->ctx, color, "%8.1f%%", "SMI cycles%", cost);
|
||||
+ out->print_metric(config, out->ctx, NULL, "%4.0f", "SMI#", smi_num);
|
||||
}
|
||||
|
||||
-static void generic_metric(const char *metric_expr,
|
||||
+static void generic_metric(struct perf_stat_config *config,
|
||||
+ const char *metric_expr,
|
||||
struct perf_evsel **metric_events,
|
||||
char *name,
|
||||
const char *metric_name,
|
||||
@@ -738,20 +748,21 @@ static void generic_metric(const char *metric_expr,
|
||||
const char *p = metric_expr;
|
||||
|
||||
if (expr__parse(&ratio, &pctx, &p) == 0)
|
||||
- print_metric(ctxp, NULL, "%8.1f",
|
||||
+ print_metric(config, ctxp, NULL, "%8.1f",
|
||||
metric_name ?
|
||||
metric_name :
|
||||
out->force_header ? name : "",
|
||||
ratio);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL,
|
||||
+ print_metric(config, ctxp, NULL, NULL,
|
||||
out->force_header ?
|
||||
(metric_name ? metric_name : name) : "", 0);
|
||||
} else
|
||||
- print_metric(ctxp, NULL, NULL, "", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "", 0);
|
||||
}
|
||||
|
||||
-void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
+void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
+ struct perf_evsel *evsel,
|
||||
double avg, int cpu,
|
||||
struct perf_stat_output_ctx *out,
|
||||
struct rblist *metric_events,
|
||||
@@ -770,10 +781,10 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
|
||||
if (total) {
|
||||
ratio = avg / total;
|
||||
- print_metric(ctxp, NULL, "%7.2f ",
|
||||
+ print_metric(config, ctxp, NULL, "%7.2f ",
|
||||
"insn per cycle", ratio);
|
||||
} else {
|
||||
- print_metric(ctxp, NULL, NULL, "insn per cycle", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "insn per cycle", 0);
|
||||
}
|
||||
|
||||
total = runtime_stat_avg(st, STAT_STALLED_CYCLES_FRONT,
|
||||
@@ -784,20 +795,20 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
ctx, cpu));
|
||||
|
||||
if (total && avg) {
|
||||
- out->new_line(ctxp);
|
||||
+ out->new_line(config, ctxp);
|
||||
ratio = total / avg;
|
||||
- print_metric(ctxp, NULL, "%7.2f ",
|
||||
+ print_metric(config, ctxp, NULL, "%7.2f ",
|
||||
"stalled cycles per insn",
|
||||
ratio);
|
||||
} else if (have_frontend_stalled) {
|
||||
- print_metric(ctxp, NULL, NULL,
|
||||
+ print_metric(config, ctxp, NULL, NULL,
|
||||
"stalled cycles per insn", 0);
|
||||
}
|
||||
} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES)) {
|
||||
if (runtime_stat_n(st, STAT_BRANCHES, ctx, cpu) != 0)
|
||||
- print_branch_misses(cpu, evsel, avg, out, st);
|
||||
+ print_branch_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "of all branches", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "of all branches", 0);
|
||||
} else if (
|
||||
evsel->attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D |
|
||||
@@ -805,9 +816,9 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
|
||||
|
||||
if (runtime_stat_n(st, STAT_L1_DCACHE, ctx, cpu) != 0)
|
||||
- print_l1_dcache_misses(cpu, evsel, avg, out, st);
|
||||
+ print_l1_dcache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "of all L1-dcache hits", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "of all L1-dcache hits", 0);
|
||||
} else if (
|
||||
evsel->attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I |
|
||||
@@ -815,9 +826,9 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
|
||||
|
||||
if (runtime_stat_n(st, STAT_L1_ICACHE, ctx, cpu) != 0)
|
||||
- print_l1_icache_misses(cpu, evsel, avg, out, st);
|
||||
+ print_l1_icache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "of all L1-icache hits", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "of all L1-icache hits", 0);
|
||||
} else if (
|
||||
evsel->attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB |
|
||||
@@ -825,9 +836,9 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
|
||||
|
||||
if (runtime_stat_n(st, STAT_DTLB_CACHE, ctx, cpu) != 0)
|
||||
- print_dtlb_cache_misses(cpu, evsel, avg, out, st);
|
||||
+ print_dtlb_cache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "of all dTLB cache hits", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "of all dTLB cache hits", 0);
|
||||
} else if (
|
||||
evsel->attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB |
|
||||
@@ -835,9 +846,9 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
|
||||
|
||||
if (runtime_stat_n(st, STAT_ITLB_CACHE, ctx, cpu) != 0)
|
||||
- print_itlb_cache_misses(cpu, evsel, avg, out, st);
|
||||
+ print_itlb_cache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "of all iTLB cache hits", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "of all iTLB cache hits", 0);
|
||||
} else if (
|
||||
evsel->attr.type == PERF_TYPE_HW_CACHE &&
|
||||
evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL |
|
||||
@@ -845,9 +856,9 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
|
||||
|
||||
if (runtime_stat_n(st, STAT_LL_CACHE, ctx, cpu) != 0)
|
||||
- print_ll_cache_misses(cpu, evsel, avg, out, st);
|
||||
+ print_ll_cache_misses(config, cpu, evsel, avg, out, st);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "of all LL-cache hits", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "of all LL-cache hits", 0);
|
||||
} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES)) {
|
||||
total = runtime_stat_avg(st, STAT_CACHEREFS, ctx, cpu);
|
||||
|
||||
@@ -855,32 +866,32 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
ratio = avg * 100 / total;
|
||||
|
||||
if (runtime_stat_n(st, STAT_CACHEREFS, ctx, cpu) != 0)
|
||||
- print_metric(ctxp, NULL, "%8.3f %%",
|
||||
+ print_metric(config, ctxp, NULL, "%8.3f %%",
|
||||
"of all cache refs", ratio);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "of all cache refs", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "of all cache refs", 0);
|
||||
} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
|
||||
- print_stalled_cycles_frontend(cpu, evsel, avg, out, st);
|
||||
+ print_stalled_cycles_frontend(config, cpu, evsel, avg, out, st);
|
||||
} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
|
||||
- print_stalled_cycles_backend(cpu, evsel, avg, out, st);
|
||||
+ print_stalled_cycles_backend(config, cpu, evsel, avg, out, st);
|
||||
} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
|
||||
total = runtime_stat_avg(st, STAT_NSECS, 0, cpu);
|
||||
|
||||
if (total) {
|
||||
ratio = avg / total;
|
||||
- print_metric(ctxp, NULL, "%8.3f", "GHz", ratio);
|
||||
+ print_metric(config, ctxp, NULL, "%8.3f", "GHz", ratio);
|
||||
} else {
|
||||
- print_metric(ctxp, NULL, NULL, "Ghz", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "Ghz", 0);
|
||||
}
|
||||
} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
|
||||
total = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu);
|
||||
|
||||
if (total)
|
||||
- print_metric(ctxp, NULL,
|
||||
+ print_metric(config, ctxp, NULL,
|
||||
"%7.2f%%", "transactional cycles",
|
||||
100.0 * (avg / total));
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "transactional cycles",
|
||||
+ print_metric(config, ctxp, NULL, NULL, "transactional cycles",
|
||||
0);
|
||||
} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
|
||||
total = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu);
|
||||
@@ -889,10 +900,10 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
if (total2 < avg)
|
||||
total2 = avg;
|
||||
if (total)
|
||||
- print_metric(ctxp, NULL, "%7.2f%%", "aborted cycles",
|
||||
+ print_metric(config, ctxp, NULL, "%7.2f%%", "aborted cycles",
|
||||
100.0 * ((total2-avg) / total));
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "aborted cycles", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "aborted cycles", 0);
|
||||
} else if (perf_stat_evsel__is(evsel, TRANSACTION_START)) {
|
||||
total = runtime_stat_avg(st, STAT_CYCLES_IN_TX,
|
||||
ctx, cpu);
|
||||
@@ -901,10 +912,10 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
ratio = total / avg;
|
||||
|
||||
if (runtime_stat_n(st, STAT_CYCLES_IN_TX, ctx, cpu) != 0)
|
||||
- print_metric(ctxp, NULL, "%8.0f",
|
||||
+ print_metric(config, ctxp, NULL, "%8.0f",
|
||||
"cycles / transaction", ratio);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "cycles / transaction",
|
||||
+ print_metric(config, ctxp, NULL, NULL, "cycles / transaction",
|
||||
0);
|
||||
} else if (perf_stat_evsel__is(evsel, ELISION_START)) {
|
||||
total = runtime_stat_avg(st, STAT_CYCLES_IN_TX,
|
||||
@@ -913,33 +924,33 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
if (avg)
|
||||
ratio = total / avg;
|
||||
|
||||
- print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio);
|
||||
+ print_metric(config, ctxp, NULL, "%8.0f", "cycles / elision", ratio);
|
||||
} else if (perf_evsel__is_clock(evsel)) {
|
||||
if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0)
|
||||
- print_metric(ctxp, NULL, "%8.3f", "CPUs utilized",
|
||||
+ print_metric(config, ctxp, NULL, "%8.3f", "CPUs utilized",
|
||||
avg / (ratio * evsel->scale));
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, "CPUs utilized", 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, "CPUs utilized", 0);
|
||||
} else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) {
|
||||
double fe_bound = td_fe_bound(ctx, cpu, st);
|
||||
|
||||
if (fe_bound > 0.2)
|
||||
color = PERF_COLOR_RED;
|
||||
- print_metric(ctxp, color, "%8.1f%%", "frontend bound",
|
||||
+ print_metric(config, ctxp, color, "%8.1f%%", "frontend bound",
|
||||
fe_bound * 100.);
|
||||
} else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_RETIRED)) {
|
||||
double retiring = td_retiring(ctx, cpu, st);
|
||||
|
||||
if (retiring > 0.7)
|
||||
color = PERF_COLOR_GREEN;
|
||||
- print_metric(ctxp, color, "%8.1f%%", "retiring",
|
||||
+ print_metric(config, ctxp, color, "%8.1f%%", "retiring",
|
||||
retiring * 100.);
|
||||
} else if (perf_stat_evsel__is(evsel, TOPDOWN_RECOVERY_BUBBLES)) {
|
||||
double bad_spec = td_bad_spec(ctx, cpu, st);
|
||||
|
||||
if (bad_spec > 0.1)
|
||||
color = PERF_COLOR_RED;
|
||||
- print_metric(ctxp, color, "%8.1f%%", "bad speculation",
|
||||
+ print_metric(config, ctxp, color, "%8.1f%%", "bad speculation",
|
||||
bad_spec * 100.);
|
||||
} else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_ISSUED)) {
|
||||
double be_bound = td_be_bound(ctx, cpu, st);
|
||||
@@ -956,12 +967,12 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
if (be_bound > 0.2)
|
||||
color = PERF_COLOR_RED;
|
||||
if (td_total_slots(ctx, cpu, st) > 0)
|
||||
- print_metric(ctxp, color, "%8.1f%%", name,
|
||||
+ print_metric(config, ctxp, color, "%8.1f%%", name,
|
||||
be_bound * 100.);
|
||||
else
|
||||
- print_metric(ctxp, NULL, NULL, name, 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, name, 0);
|
||||
} else if (evsel->metric_expr) {
|
||||
- generic_metric(evsel->metric_expr, evsel->metric_events, evsel->name,
|
||||
+ generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name,
|
||||
evsel->metric_name, avg, cpu, out, st);
|
||||
} else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) {
|
||||
char unit = 'M';
|
||||
@@ -976,9 +987,9 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
unit = 'K';
|
||||
}
|
||||
snprintf(unit_buf, sizeof(unit_buf), "%c/sec", unit);
|
||||
- print_metric(ctxp, NULL, "%8.3f", unit_buf, ratio);
|
||||
+ print_metric(config, ctxp, NULL, "%8.3f", unit_buf, ratio);
|
||||
} else if (perf_stat_evsel__is(evsel, SMI_NUM)) {
|
||||
- print_smi_cost(cpu, evsel, out, st);
|
||||
+ print_smi_cost(config, cpu, evsel, out, st);
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
@@ -988,12 +999,12 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
|
||||
list_for_each_entry (mexp, &me->head, nd) {
|
||||
if (num++ > 0)
|
||||
- out->new_line(ctxp);
|
||||
- generic_metric(mexp->metric_expr, mexp->metric_events,
|
||||
+ out->new_line(config, ctxp);
|
||||
+ generic_metric(config, mexp->metric_expr, mexp->metric_events,
|
||||
evsel->name, mexp->metric_name,
|
||||
avg, cpu, out, st);
|
||||
}
|
||||
}
|
||||
if (num == 0)
|
||||
- print_metric(ctxp, NULL, NULL, NULL, 0);
|
||||
+ print_metric(config, ctxp, NULL, NULL, NULL, 0);
|
||||
}
|
||||
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
|
||||
index e19abb1635c4..c223bbb81d13 100644
|
||||
--- a/tools/perf/util/stat.h
|
||||
+++ b/tools/perf/util/stat.h
|
||||
@@ -130,9 +130,10 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,
|
||||
extern struct runtime_stat rt_stat;
|
||||
extern struct stats walltime_nsecs_stats;
|
||||
|
||||
-typedef void (*print_metric_t)(void *ctx, const char *color, const char *unit,
|
||||
+typedef void (*print_metric_t)(struct perf_stat_config *config,
|
||||
+ void *ctx, const char *color, const char *unit,
|
||||
const char *fmt, double val);
|
||||
-typedef void (*new_line_t )(void *ctx);
|
||||
+typedef void (*new_line_t)(struct perf_stat_config *config, void *ctx);
|
||||
|
||||
void runtime_stat__init(struct runtime_stat *st);
|
||||
void runtime_stat__exit(struct runtime_stat *st);
|
||||
@@ -148,7 +149,8 @@ struct perf_stat_output_ctx {
|
||||
bool force_header;
|
||||
};
|
||||
|
||||
-void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
|
||||
+void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
+ struct perf_evsel *evsel,
|
||||
double avg, int cpu,
|
||||
struct perf_stat_output_ctx *out,
|
||||
struct rblist *metric_events,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,117 @@
|
||||
From 4eb984aff402a0421d7656d7c81d3c83d82521d3 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 30 Aug 2018 08:32:51 +0200
|
||||
Subject: [PATCH 006/201] perf stat: Move 'metric_events' to 'struct
|
||||
perf_stat_config'
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v4.20-rc1
|
||||
commit d0192fdba09a8901db133fe5a1fcd22d40fcf545
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d0192fdba09a8901db133fe5a1fcd22d40fcf545
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Move the static variable 'metric_events' to 'struct perf_stat_config',
|
||||
so that it can be passed around and used outside 'perf stat' command.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <andi@firstfloor.org>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20180830063252.23729-43-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflict:
|
||||
tools/perf/builtin-stat.c
|
||||
tools/perf/util/stat.h
|
||||
---
|
||||
tools/perf/builtin-stat.c | 10 ++++------
|
||||
tools/perf/util/stat.h | 17 +++++++++--------
|
||||
2 files changed, 13 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index 651fef3c92de..da1e60029ff1 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -137,8 +137,6 @@ static const char *smi_cost_attrs = {
|
||||
|
||||
static struct perf_evlist *evsel_list;
|
||||
|
||||
-static struct rblist metric_events;
|
||||
-
|
||||
static struct target target = {
|
||||
.uid = UINT_MAX,
|
||||
};
|
||||
@@ -1230,7 +1228,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,
|
||||
|
||||
perf_stat__print_shadow_stats(config, counter, uval,
|
||||
first_shadow_cpu(counter, id),
|
||||
- &out, &metric_events, st);
|
||||
+ &out, &config->metric_events, st);
|
||||
if (!csv_output && !metric_only) {
|
||||
print_noise(config, counter, noise);
|
||||
print_running(config, run, ena);
|
||||
@@ -1669,7 +1667,7 @@ static void print_metric_headers(struct perf_stat_config *config,
|
||||
perf_stat__print_shadow_stats(config, counter, 0,
|
||||
0,
|
||||
&out,
|
||||
- &metric_events,
|
||||
+ &config->metric_events,
|
||||
&rt_stat);
|
||||
}
|
||||
fputc('\n', config->output);
|
||||
@@ -1989,7 +1987,7 @@ static int parse_metric_groups(const struct option *opt,
|
||||
const char *str,
|
||||
int unset __maybe_unused)
|
||||
{
|
||||
- return metricgroup__parse_groups(opt, str, &metric_events);
|
||||
+ return metricgroup__parse_groups(opt, str, &stat_config.metric_events);
|
||||
}
|
||||
|
||||
static struct option stat_options[] = {
|
||||
@@ -2445,7 +2443,7 @@ static int add_default_attributes(void)
|
||||
struct option opt = { .value = &evsel_list };
|
||||
|
||||
return metricgroup__parse_groups(&opt, "transaction",
|
||||
- &metric_events);
|
||||
+ &stat_config.metric_events);
|
||||
}
|
||||
|
||||
if (pmu_have_event("cpu", "cycles-ct") &&
|
||||
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
|
||||
index c223bbb81d13..8a7d8425acf8 100644
|
||||
--- a/tools/perf/util/stat.h
|
||||
+++ b/tools/perf/util/stat.h
|
||||
@@ -85,14 +85,15 @@ struct runtime_stat {
|
||||
};
|
||||
|
||||
struct perf_stat_config {
|
||||
- enum aggr_mode aggr_mode;
|
||||
- bool scale;
|
||||
- FILE *output;
|
||||
- unsigned int interval;
|
||||
- unsigned int timeout;
|
||||
- int times;
|
||||
- struct runtime_stat *stats;
|
||||
- int stats_num;
|
||||
+ enum aggr_mode aggr_mode;
|
||||
+ bool scale;
|
||||
+ FILE *output;
|
||||
+ unsigned int interval;
|
||||
+ unsigned int timeout;
|
||||
+ int times;
|
||||
+ struct runtime_stat *stats;
|
||||
+ int stats_num;
|
||||
+ struct rblist metric_events;
|
||||
};
|
||||
|
||||
void update_stats(struct stats *stats, u64 val);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,145 @@
|
||||
From 16055ffe7f4937ac992b9e84f120ad3128b23352 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Wed, 13 Feb 2019 13:32:41 +0100
|
||||
Subject: [PATCH 007/201] perf list: Display metric expressions for --details
|
||||
option
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.1-rc1
|
||||
commit 33bbc571ed79cace481fae4031b80a51d93ae997
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=33bbc571ed79cace481fae4031b80a51d93ae997
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
Display metric expression itself when --details is specified.
|
||||
|
||||
Current list with no details:
|
||||
|
||||
# perf list metrics
|
||||
...
|
||||
TopDownL1:
|
||||
IPC
|
||||
[Instructions Per Cycle (per logical thread)]
|
||||
SLOTS
|
||||
[Total issue-pipeline slots]
|
||||
...
|
||||
|
||||
Detailed output with metric formula:
|
||||
|
||||
# perf list --details metrics
|
||||
...
|
||||
TopDownL1:
|
||||
IPC
|
||||
[Instructions Per Cycle (per logical thread)]
|
||||
[inst_retired.any / cpu_clk_unhalted.thread]
|
||||
SLOTS
|
||||
[Total issue-pipeline slots]
|
||||
[4*(( cpu_clk_unhalted.thread_any / 2 ) if #smt_on else cycles)]
|
||||
...
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20190213123246.4015-6-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-list.c | 8 ++++----
|
||||
tools/perf/util/metricgroup.c | 8 +++++++-
|
||||
tools/perf/util/metricgroup.h | 3 ++-
|
||||
tools/perf/util/parse-events.c | 2 +-
|
||||
4 files changed, 14 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
|
||||
index ead221e49f00..c9f98d00c0e9 100644
|
||||
--- a/tools/perf/builtin-list.c
|
||||
+++ b/tools/perf/builtin-list.c
|
||||
@@ -82,9 +82,9 @@ int cmd_list(int argc, const char **argv)
|
||||
else if (strcmp(argv[i], "sdt") == 0)
|
||||
print_sdt_events(NULL, NULL, raw_dump);
|
||||
else if (strcmp(argv[i], "metric") == 0)
|
||||
- metricgroup__print(true, false, NULL, raw_dump);
|
||||
+ metricgroup__print(true, false, NULL, raw_dump, details_flag);
|
||||
else if (strcmp(argv[i], "metricgroup") == 0)
|
||||
- metricgroup__print(false, true, NULL, raw_dump);
|
||||
+ metricgroup__print(false, true, NULL, raw_dump, details_flag);
|
||||
else if ((sep = strchr(argv[i], ':')) != NULL) {
|
||||
int sep_idx;
|
||||
|
||||
@@ -102,7 +102,7 @@ int cmd_list(int argc, const char **argv)
|
||||
s[sep_idx] = '\0';
|
||||
print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
|
||||
print_sdt_events(s, s + sep_idx + 1, raw_dump);
|
||||
- metricgroup__print(true, true, s, raw_dump);
|
||||
+ metricgroup__print(true, true, s, raw_dump, details_flag);
|
||||
free(s);
|
||||
} else {
|
||||
if (asprintf(&s, "*%s*", argv[i]) < 0) {
|
||||
@@ -119,7 +119,7 @@ int cmd_list(int argc, const char **argv)
|
||||
details_flag);
|
||||
print_tracepoint_events(NULL, s, raw_dump);
|
||||
print_sdt_events(NULL, s, raw_dump);
|
||||
- metricgroup__print(true, true, NULL, raw_dump);
|
||||
+ metricgroup__print(true, true, NULL, raw_dump, details_flag);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 6dcc6e1182a5..27552a0b990a 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -296,7 +296,7 @@ static void metricgroup__print_strlist(struct strlist *metrics, bool raw)
|
||||
}
|
||||
|
||||
void metricgroup__print(bool metrics, bool metricgroups, char *filter,
|
||||
- bool raw)
|
||||
+ bool raw, bool details)
|
||||
{
|
||||
struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
struct pmu_event *pe;
|
||||
@@ -355,6 +355,12 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
|
||||
if (asprintf(&s, "%s\n%*s%s]",
|
||||
pe->metric_name, 8, "[", pe->desc) < 0)
|
||||
return;
|
||||
+
|
||||
+ if (details) {
|
||||
+ if (asprintf(&s, "%s\n%*s%s]",
|
||||
+ s, 8, "[", pe->metric_expr) < 0)
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!s)
|
||||
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
|
||||
index 8a155dba0581..5c52097a5c63 100644
|
||||
--- a/tools/perf/util/metricgroup.h
|
||||
+++ b/tools/perf/util/metricgroup.h
|
||||
@@ -27,6 +27,7 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
const char *str,
|
||||
struct rblist *metric_events);
|
||||
|
||||
-void metricgroup__print(bool metrics, bool groups, char *filter, bool raw);
|
||||
+void metricgroup__print(bool metrics, bool groups, char *filter,
|
||||
+ bool raw, bool details);
|
||||
bool metricgroup__has_metric(const char *metric);
|
||||
#endif
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index 0eff0c3ba9ee..f5a7d42b0928 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -2545,7 +2545,7 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
|
||||
|
||||
print_sdt_events(NULL, NULL, name_only);
|
||||
|
||||
- metricgroup__print(true, true, NULL, name_only);
|
||||
+ metricgroup__print(true, true, NULL, name_only, details_flag);
|
||||
}
|
||||
|
||||
int parse_events__is_hardcoded_term(struct parse_events_term *term)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,112 @@
|
||||
From 8d49212ae241e5352ea7fca8a14be4a34da70060 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Wed, 13 Feb 2019 13:32:40 +0100
|
||||
Subject: [PATCH 008/201] perf tools: Fix legacy events symbol separator
|
||||
parsing
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.1-rc1
|
||||
commit 714a92d83fd1e20461f53549cfbee77b20be5032
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=714a92d83fd1e20461f53549cfbee77b20be5032
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
Fixing legacy symbol events parsing. We can't support single slash
|
||||
separator, like 'cycles/u', because it conflicts with non empty terms,
|
||||
like 'cycles/period/u'.
|
||||
|
||||
Keeping only '//' and ':' separator for these events:
|
||||
cycles//u
|
||||
cycles:k
|
||||
|
||||
And removing '/' separator support, which is not working
|
||||
anymore. Also adding automated tests for above events.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lkml.kernel.org/r/20190213123246.4015-5-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/parse-events.c | 30 ++++++++++++++++++++++++++++++
|
||||
tools/perf/util/parse-events.y | 4 ++--
|
||||
2 files changed, 32 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
|
||||
index 532c95e8fa6b..8f3c80e13584 100644
|
||||
--- a/tools/perf/tests/parse-events.c
|
||||
+++ b/tools/perf/tests/parse-events.c
|
||||
@@ -1356,6 +1356,26 @@ static int test__checkevent_complex_name(struct perf_evlist *evlist)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int test__sym_event_slash(struct perf_evlist *evlist)
|
||||
+{
|
||||
+ struct perf_evsel *evsel = perf_evlist__first(evlist);
|
||||
+
|
||||
+ TEST_ASSERT_VAL("wrong type", evsel->attr.type == PERF_TYPE_HARDWARE);
|
||||
+ TEST_ASSERT_VAL("wrong config", evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES);
|
||||
+ TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int test__sym_event_dc(struct perf_evlist *evlist)
|
||||
+{
|
||||
+ struct perf_evsel *evsel = perf_evlist__first(evlist);
|
||||
+
|
||||
+ TEST_ASSERT_VAL("wrong type", evsel->attr.type == PERF_TYPE_HARDWARE);
|
||||
+ TEST_ASSERT_VAL("wrong config", evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES);
|
||||
+ TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int count_tracepoints(void)
|
||||
{
|
||||
struct dirent *events_ent;
|
||||
@@ -1697,6 +1717,16 @@ static struct evlist_test test__events[] = {
|
||||
.name = "cycles/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks'/Duk",
|
||||
.check = test__checkevent_complex_name,
|
||||
.id = 53
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "cycles//u",
|
||||
+ .check = test__sym_event_slash,
|
||||
+ .id = 54,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "cycles:k",
|
||||
+ .check = test__sym_event_dc,
|
||||
+ .id = 55,
|
||||
}
|
||||
};
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
|
||||
index 8d7578be708a..5d5413c21b64 100644
|
||||
--- a/tools/perf/util/parse-events.y
|
||||
+++ b/tools/perf/util/parse-events.y
|
||||
@@ -311,7 +311,7 @@ value_sym '/' event_config '/'
|
||||
$$ = list;
|
||||
}
|
||||
|
|
||||
-value_sym sep_slash_dc
|
||||
+value_sym sep_slash_slash_dc
|
||||
{
|
||||
struct list_head *list;
|
||||
int type = $1 >> 16;
|
||||
@@ -702,7 +702,7 @@ PE_VALUE PE_ARRAY_RANGE PE_VALUE
|
||||
|
||||
sep_dc: ':' |
|
||||
|
||||
-sep_slash_dc: '/' | ':' |
|
||||
+sep_slash_slash_dc: '/' '/' | ':' |
|
||||
|
||||
%%
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
105
patches/0126-perf-stat-Revert-checks-for-duration_time.patch
Normal file
105
patches/0126-perf-stat-Revert-checks-for-duration_time.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 744525c9170deae41ba87831a8288f84041b1625 Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Tue, 26 Mar 2019 15:18:20 -0700
|
||||
Subject: [PATCH 009/201] perf stat: Revert checks for duration_time
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.2-rc1
|
||||
commit c2b3c170db610896e4e633cba2135045333811c2
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c2b3c170db610896e4e633cba2135045333811c2
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This reverts e864c5ca145e ("perf stat: Hide internal duration_time
|
||||
counter") but doing it manually since the code has now moved to a
|
||||
different file.
|
||||
|
||||
The next patch will properly implement duration_time as a full event, so
|
||||
no need to hide it anymore.
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Link: http://lkml.kernel.org/r/20190326221823.11518-2-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/builtin-stat.c
|
||||
---
|
||||
tools/perf/builtin-stat.c | 17 -----------------
|
||||
1 file changed, 17 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index da1e60029ff1..e45fc66426e2 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -206,11 +206,6 @@ static struct perf_stat_config stat_config = {
|
||||
.scale = true,
|
||||
};
|
||||
|
||||
-static bool is_duration_time(struct perf_evsel *evsel)
|
||||
-{
|
||||
- return !strcmp(evsel->name, "duration_time");
|
||||
-}
|
||||
-
|
||||
static inline void diff_timespec(struct timespec *r, struct timespec *a,
|
||||
struct timespec *b)
|
||||
{
|
||||
@@ -1385,8 +1380,6 @@ static void print_aggr(struct perf_stat_config *config,
|
||||
ad.id = id = aggr_map->map[s];
|
||||
first = true;
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
- if (is_duration_time(counter))
|
||||
- continue;
|
||||
|
||||
ad.val = ad.ena = ad.run = 0;
|
||||
ad.nr = 0;
|
||||
@@ -1599,8 +1592,6 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
|
||||
if (prefix)
|
||||
fputs(prefix, config->output);
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
- if (is_duration_time(counter))
|
||||
- continue;
|
||||
if (first) {
|
||||
aggr_printout(config, counter, cpu, 0);
|
||||
first = false;
|
||||
@@ -1656,8 +1647,6 @@ static void print_metric_headers(struct perf_stat_config *config,
|
||||
|
||||
/* Print metrics headers only */
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
- if (is_duration_time(counter))
|
||||
- continue;
|
||||
os.evsel = counter;
|
||||
out.ctx = &os;
|
||||
out.print_metric = print_metric_header;
|
||||
@@ -1879,15 +1868,11 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
break;
|
||||
case AGGR_THREAD:
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
- if (is_duration_time(counter))
|
||||
- continue;
|
||||
print_aggr_thread(config, counter, prefix);
|
||||
}
|
||||
break;
|
||||
case AGGR_GLOBAL:
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
- if (is_duration_time(counter))
|
||||
- continue;
|
||||
print_counter_aggr(config, counter, prefix);
|
||||
}
|
||||
if (metric_only)
|
||||
@@ -1898,8 +1883,6 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
|
||||
print_no_aggr_metric(config, prefix);
|
||||
else {
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
- if (is_duration_time(counter))
|
||||
- continue;
|
||||
print_counter(config, counter, prefix);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,343 @@
|
||||
From 4de09fdfa20b9de2c79c9b370dee3771e104cbe8 Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Tue, 26 Mar 2019 15:18:21 -0700
|
||||
Subject: [PATCH 010/201] perf stat: Implement duration_time as a proper event
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.2-rc1
|
||||
commit f0fbb114e3025f3f737a1e1c5c39c5b2b2e671bd
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f0fbb114e3025f3f737a1e1c5c39c5b2b2e671bd
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The perf metric expression use 'duration_time' internally to normalize
|
||||
events. Normal 'perf stat' without -x also prints the duration time.
|
||||
But when using -x, the interval is not output anywhere, which is
|
||||
inconvenient for any post processing which often wants to normalize
|
||||
values to time.
|
||||
|
||||
So implement 'duration_time' as a proper perf event that can be
|
||||
specified explicitely with -e.
|
||||
|
||||
The previous implementation of 'duration_time' only worked for metric
|
||||
processing. This adds the concept of a tool event that is handled by the
|
||||
tool. On the kernel level it is still mapped to the dummy software
|
||||
event, but the values are not read anymore, but instead computed by the
|
||||
tool.
|
||||
|
||||
Add proper plumbing to handle this in the event parser, and display it
|
||||
in 'perf stat'. We don't want 'duration_time' to be added up, so it's
|
||||
only printed for the first CPU.
|
||||
|
||||
% perf stat -e duration_time,cycles true
|
||||
|
||||
Performance counter stats for 'true':
|
||||
|
||||
555,476 ns duration_time
|
||||
771,958 cycles
|
||||
|
||||
0.000555476 seconds time elapsed
|
||||
|
||||
0.000644000 seconds user
|
||||
0.000000000 seconds sys
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Link: http://lkml.kernel.org/r/20190326221823.11518-3-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflict:
|
||||
tools/perf/util/evsel.h
|
||||
---
|
||||
tools/perf/builtin-stat.c | 28 ++++++++++++++++++-------
|
||||
tools/perf/util/evsel.h | 6 ++++++
|
||||
tools/perf/util/parse-events.c | 38 +++++++++++++++++++++++++++++-----
|
||||
tools/perf/util/parse-events.h | 4 ++++
|
||||
tools/perf/util/parse-events.l | 11 +++++++++-
|
||||
tools/perf/util/parse-events.y | 12 +++++++++++
|
||||
6 files changed, 86 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index e45fc66426e2..c96c0715171f 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -325,11 +325,25 @@ perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread,
|
||||
process_synthesized_event, NULL);
|
||||
}
|
||||
|
||||
+static int read_single_counter(struct perf_evsel *counter, int cpu,
|
||||
+ int thread, struct timespec *rs)
|
||||
+{
|
||||
+ if (counter->tool_event == PERF_TOOL_DURATION_TIME) {
|
||||
+ u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL;
|
||||
+ struct perf_counts_values *count =
|
||||
+ perf_counts(counter->counts, cpu, thread);
|
||||
+ count->ena = count->run = val;
|
||||
+ count->val = val;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return perf_evsel__read_counter(counter, cpu, thread);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Read out the results of a single counter:
|
||||
* do not aggregate counts across CPUs in system-wide mode
|
||||
*/
|
||||
-static int read_counter(struct perf_evsel *counter)
|
||||
+static int read_counter(struct perf_evsel *counter, struct timespec *rs)
|
||||
{
|
||||
int nthreads = thread_map__nr(evsel_list->threads);
|
||||
int ncpus, cpu, thread;
|
||||
@@ -356,7 +370,7 @@ static int read_counter(struct perf_evsel *counter)
|
||||
* (via perf_evsel__read_counter) and sets threir count->loaded.
|
||||
*/
|
||||
if (!count->loaded &&
|
||||
- perf_evsel__read_counter(counter, cpu, thread)) {
|
||||
+ read_single_counter(counter, cpu, thread, rs)) {
|
||||
counter->counts->scaled = -1;
|
||||
perf_counts(counter->counts, cpu, thread)->ena = 0;
|
||||
perf_counts(counter->counts, cpu, thread)->run = 0;
|
||||
@@ -385,13 +399,13 @@ static int read_counter(struct perf_evsel *counter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void read_counters(void)
|
||||
+static void read_counters(struct timespec *rs)
|
||||
{
|
||||
struct perf_evsel *counter;
|
||||
int ret;
|
||||
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
- ret = read_counter(counter);
|
||||
+ ret = read_counter(counter, rs);
|
||||
if (ret)
|
||||
pr_debug("failed to read counter %s\n", counter->name);
|
||||
|
||||
@@ -404,11 +418,11 @@ static void process_interval(void)
|
||||
{
|
||||
struct timespec ts, rs;
|
||||
|
||||
- read_counters();
|
||||
-
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
diff_timespec(&rs, &ts, &ref_time);
|
||||
|
||||
+ read_counters(&rs);
|
||||
+
|
||||
if (STAT_RECORD) {
|
||||
if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL))
|
||||
pr_err("failed to write stat round event\n");
|
||||
@@ -756,7 +770,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
|
||||
* avoid arbitrary skew, we must read all counters before closing any
|
||||
* group leaders.
|
||||
*/
|
||||
- read_counters();
|
||||
+ read_counters(&(struct timespec) { .tv_nsec = t1-t0 });
|
||||
perf_evlist__close(evsel_list);
|
||||
|
||||
return WEXITSTATUS(status);
|
||||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
|
||||
index feec6bf22a40..dab3930e2a8c 100644
|
||||
--- a/tools/perf/util/evsel.h
|
||||
+++ b/tools/perf/util/evsel.h
|
||||
@@ -71,6 +71,11 @@ struct perf_evsel_config_term {
|
||||
|
||||
struct perf_stat_evsel;
|
||||
|
||||
+enum perf_tool_event {
|
||||
+ PERF_TOOL_NONE = 0,
|
||||
+ PERF_TOOL_DURATION_TIME = 1,
|
||||
+};
|
||||
+
|
||||
/** struct perf_evsel - event selector
|
||||
*
|
||||
* @evlist - evlist this evsel is in, if it is in one.
|
||||
@@ -115,6 +120,7 @@ struct perf_evsel {
|
||||
unsigned int sample_size;
|
||||
int id_pos;
|
||||
int is_pos;
|
||||
+ enum perf_tool_event tool_event;
|
||||
bool uniquified_name;
|
||||
bool snapshot;
|
||||
bool supported;
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index f5a7d42b0928..36d0851c452b 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -317,10 +317,12 @@ static struct perf_evsel *
|
||||
__add_event(struct list_head *list, int *idx,
|
||||
struct perf_event_attr *attr,
|
||||
char *name, struct perf_pmu *pmu,
|
||||
- struct list_head *config_terms, bool auto_merge_stats)
|
||||
+ struct list_head *config_terms, bool auto_merge_stats,
|
||||
+ const char *cpu_list)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
- struct cpu_map *cpus = pmu ? pmu->cpus : NULL;
|
||||
+ struct cpu_map *cpus = pmu ? pmu->cpus :
|
||||
+ cpu_list ? cpu_map__new(cpu_list) : NULL;
|
||||
|
||||
event_attr_init(attr);
|
||||
|
||||
@@ -348,7 +350,25 @@ static int add_event(struct list_head *list, int *idx,
|
||||
struct perf_event_attr *attr, char *name,
|
||||
struct list_head *config_terms)
|
||||
{
|
||||
- return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM;
|
||||
+ return __add_event(list, idx, attr, name, NULL, config_terms, false, NULL) ? 0 : -ENOMEM;
|
||||
+}
|
||||
+
|
||||
+static int add_event_tool(struct list_head *list, int *idx,
|
||||
+ enum perf_tool_event tool_event)
|
||||
+{
|
||||
+ struct perf_evsel *evsel;
|
||||
+ struct perf_event_attr attr = {
|
||||
+ .type = PERF_TYPE_SOFTWARE,
|
||||
+ .config = PERF_COUNT_SW_DUMMY,
|
||||
+ };
|
||||
+
|
||||
+ evsel = __add_event(list, idx, &attr, NULL, NULL, NULL, false, "0");
|
||||
+ if (!evsel)
|
||||
+ return -ENOMEM;
|
||||
+ evsel->tool_event = tool_event;
|
||||
+ if (tool_event == PERF_TOOL_DURATION_TIME)
|
||||
+ evsel->unit = strdup("ns");
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
|
||||
@@ -1225,6 +1245,13 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
|
||||
get_config_name(head_config), &config_terms);
|
||||
}
|
||||
|
||||
+int parse_events_add_tool(struct parse_events_state *parse_state,
|
||||
+ struct list_head *list,
|
||||
+ enum perf_tool_event tool_event)
|
||||
+{
|
||||
+ return add_event_tool(list, &parse_state->idx, tool_event);
|
||||
+}
|
||||
+
|
||||
int parse_events_add_pmu(struct parse_events_state *parse_state,
|
||||
struct list_head *list, char *name,
|
||||
struct list_head *head_config,
|
||||
@@ -1259,7 +1286,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
||||
|
||||
if (!head_config) {
|
||||
attr.type = pmu->type;
|
||||
- evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats);
|
||||
+ evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL,
|
||||
+ auto_merge_stats, NULL);
|
||||
if (evsel) {
|
||||
evsel->pmu_name = name ? strdup(name) : NULL;
|
||||
evsel->use_uncore_alias = use_uncore_alias;
|
||||
@@ -1294,7 +1322,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
||||
|
||||
evsel = __add_event(list, &parse_state->idx, &attr,
|
||||
get_config_name(head_config), pmu,
|
||||
- &config_terms, auto_merge_stats);
|
||||
+ &config_terms, auto_merge_stats, NULL);
|
||||
if (evsel) {
|
||||
evsel->unit = info.unit;
|
||||
evsel->scale = info.scale;
|
||||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
||||
index 4473dac27aee..638e2a0bec35 100644
|
||||
--- a/tools/perf/util/parse-events.h
|
||||
+++ b/tools/perf/util/parse-events.h
|
||||
@@ -159,6 +159,10 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
|
||||
struct list_head *list,
|
||||
u32 type, u64 config,
|
||||
struct list_head *head_config);
|
||||
+enum perf_tool_event;
|
||||
+int parse_events_add_tool(struct parse_events_state *parse_state,
|
||||
+ struct list_head *list,
|
||||
+ enum perf_tool_event tool_event);
|
||||
int parse_events_add_cache(struct list_head *list, int *idx,
|
||||
char *type, char *op_result1, char *op_result2,
|
||||
struct parse_events_error *error,
|
||||
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
|
||||
index 5f761f3ed0f3..d8c82cd8d610 100644
|
||||
--- a/tools/perf/util/parse-events.l
|
||||
+++ b/tools/perf/util/parse-events.l
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "../perf.h"
|
||||
#include "parse-events.h"
|
||||
#include "parse-events-bison.h"
|
||||
+#include "evsel.h"
|
||||
|
||||
char *parse_events_get_text(yyscan_t yyscanner);
|
||||
YYSTYPE *parse_events_get_lval(yyscan_t yyscanner);
|
||||
@@ -154,6 +155,14 @@ static int sym(yyscan_t scanner, int type, int config)
|
||||
return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
|
||||
}
|
||||
|
||||
+static int tool(yyscan_t scanner, enum perf_tool_event event)
|
||||
+{
|
||||
+ YYSTYPE *yylval = parse_events_get_lval(scanner);
|
||||
+
|
||||
+ yylval->num = event;
|
||||
+ return PE_VALUE_SYM_TOOL;
|
||||
+}
|
||||
+
|
||||
static int term(yyscan_t scanner, int type)
|
||||
{
|
||||
YYSTYPE *yylval = parse_events_get_lval(scanner);
|
||||
@@ -321,7 +330,7 @@ cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COU
|
||||
alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
|
||||
emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
|
||||
dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
|
||||
-duration_time { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
|
||||
+duration_time { return tool(yyscanner, PERF_TOOL_DURATION_TIME); }
|
||||
bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUTPUT); }
|
||||
|
||||
/*
|
||||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
|
||||
index 5d5413c21b64..a2c7b6fb1fd5 100644
|
||||
--- a/tools/perf/util/parse-events.y
|
||||
+++ b/tools/perf/util/parse-events.y
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/types.h>
|
||||
#include "util.h"
|
||||
#include "pmu.h"
|
||||
+#include "evsel.h"
|
||||
#include "debug.h"
|
||||
#include "parse-events.h"
|
||||
#include "parse-events-bison.h"
|
||||
@@ -45,6 +46,7 @@ static void inc_group_count(struct list_head *list,
|
||||
|
||||
%token PE_START_EVENTS PE_START_TERMS
|
||||
%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
|
||||
+%token PE_VALUE_SYM_TOOL
|
||||
%token PE_EVENT_NAME
|
||||
%token PE_NAME
|
||||
%token PE_BPF_OBJECT PE_BPF_SOURCE
|
||||
@@ -58,6 +60,7 @@ static void inc_group_count(struct list_head *list,
|
||||
%type <num> PE_VALUE
|
||||
%type <num> PE_VALUE_SYM_HW
|
||||
%type <num> PE_VALUE_SYM_SW
|
||||
+%type <num> PE_VALUE_SYM_TOOL
|
||||
%type <num> PE_RAW
|
||||
%type <num> PE_TERM
|
||||
%type <str> PE_NAME
|
||||
@@ -321,6 +324,15 @@ value_sym sep_slash_slash_dc
|
||||
ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
|
||||
$$ = list;
|
||||
}
|
||||
+|
|
||||
+PE_VALUE_SYM_TOOL sep_slash_slash_dc
|
||||
+{
|
||||
+ struct list_head *list;
|
||||
+
|
||||
+ ALLOC_LIST(list);
|
||||
+ ABORT_ON(parse_events_add_tool(_parse_state, list, $1));
|
||||
+ $$ = list;
|
||||
+}
|
||||
|
||||
event_legacy_cache:
|
||||
PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
From f20b39339978d851d7a44972d3c7974a3acdc6fa Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Tue, 26 Mar 2019 15:18:22 -0700
|
||||
Subject: [PATCH 011/201] perf evsel: Support printing evsel name for
|
||||
'duration_time'
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.2-rc1
|
||||
commit 3371f389e4be6efc496ca395b21911a8f2c2d23f
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3371f389e4be6efc496ca395b21911a8f2c2d23f
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Implement printing the correct name for duration_time
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Link: http://lkml.kernel.org/r/20190326221823.11518-4-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/evsel.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
|
||||
index 4390a8d8ba0b..e0fb67670e03 100644
|
||||
--- a/tools/perf/util/evsel.c
|
||||
+++ b/tools/perf/util/evsel.c
|
||||
@@ -586,6 +586,12 @@ static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size)
|
||||
return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
|
||||
}
|
||||
|
||||
+static int perf_evsel__tool_name(char *bf, size_t size)
|
||||
+{
|
||||
+ int ret = scnprintf(bf, size, "duration_time");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
const char *perf_evsel__name(struct perf_evsel *evsel)
|
||||
{
|
||||
char bf[128];
|
||||
@@ -610,7 +616,10 @@ const char *perf_evsel__name(struct perf_evsel *evsel)
|
||||
break;
|
||||
|
||||
case PERF_TYPE_SOFTWARE:
|
||||
- perf_evsel__sw_name(evsel, bf, sizeof(bf));
|
||||
+ if (evsel->tool_event)
|
||||
+ perf_evsel__tool_name(bf, sizeof(bf));
|
||||
+ else
|
||||
+ perf_evsel__sw_name(evsel, bf, sizeof(bf));
|
||||
break;
|
||||
|
||||
case PERF_TYPE_TRACEPOINT:
|
||||
--
|
||||
2.27.0
|
||||
|
||||
148
patches/0129-perf-list-Output-tool-events.patch
Normal file
148
patches/0129-perf-list-Output-tool-events.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From e61fd6e1d87c9ff8d33b5b07e4be63440bece6eb Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Tue, 26 Mar 2019 15:18:23 -0700
|
||||
Subject: [PATCH 012/201] perf list: Output tool events
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.2-rc1
|
||||
commit 5e0861baa3fa73e8bd861a4b7ba7fa992b1dff82
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5e0861baa3fa73e8bd861a4b7ba7fa992b1dff82
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add support in 'perf list' to output tool internal events, currently
|
||||
only 'duration_time'.
|
||||
|
||||
Committer testing:
|
||||
|
||||
$ perf list dur*
|
||||
|
||||
List of pre-defined events (to be used in -e):
|
||||
|
||||
duration_time [Tool event]
|
||||
|
||||
Metric Groups:
|
||||
|
||||
$ perf list sw
|
||||
|
||||
List of pre-defined events (to be used in -e):
|
||||
|
||||
alignment-faults [Software event]
|
||||
bpf-output [Software event]
|
||||
context-switches OR cs [Software event]
|
||||
cpu-clock [Software event]
|
||||
cpu-migrations OR migrations [Software event]
|
||||
dummy [Software event]
|
||||
emulation-faults [Software event]
|
||||
major-faults [Software event]
|
||||
minor-faults [Software event]
|
||||
page-faults OR faults [Software event]
|
||||
task-clock [Software event]
|
||||
|
||||
duration_time [Tool event]
|
||||
|
||||
$ perf list | grep duration
|
||||
duration_time [Tool event]
|
||||
[L1D miss outstandings duration in cycles]
|
||||
page walk duration are excluded in Skylake]
|
||||
load. EPT page walk duration are excluded in Skylake]
|
||||
page walk duration are excluded in Skylake]
|
||||
store. EPT page walk duration are excluded in Skylake]
|
||||
(instruction fetch) request. EPT page walk duration are excluded in
|
||||
instruction fetch request. EPT page walk duration are excluded in
|
||||
$
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Link: http://lkml.kernel.org/r/20190326221823.11518-5-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-list.c | 6 ++++--
|
||||
tools/perf/util/parse-events.c | 20 ++++++++++++++++++++
|
||||
tools/perf/util/parse-events.h | 1 +
|
||||
3 files changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
|
||||
index c9f98d00c0e9..e4606919bda9 100644
|
||||
--- a/tools/perf/builtin-list.c
|
||||
+++ b/tools/perf/builtin-list.c
|
||||
@@ -70,10 +70,11 @@ int cmd_list(int argc, const char **argv)
|
||||
print_symbol_events(NULL, PERF_TYPE_HARDWARE,
|
||||
event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump);
|
||||
else if (strcmp(argv[i], "sw") == 0 ||
|
||||
- strcmp(argv[i], "software") == 0)
|
||||
+ strcmp(argv[i], "software") == 0) {
|
||||
print_symbol_events(NULL, PERF_TYPE_SOFTWARE,
|
||||
event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
|
||||
- else if (strcmp(argv[i], "cache") == 0 ||
|
||||
+ print_tool_events(NULL, raw_dump);
|
||||
+ } else if (strcmp(argv[i], "cache") == 0 ||
|
||||
strcmp(argv[i], "hwcache") == 0)
|
||||
print_hwcache_events(NULL, raw_dump);
|
||||
else if (strcmp(argv[i], "pmu") == 0)
|
||||
@@ -113,6 +114,7 @@ int cmd_list(int argc, const char **argv)
|
||||
event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump);
|
||||
print_symbol_events(s, PERF_TYPE_SOFTWARE,
|
||||
event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
|
||||
+ print_tool_events(s, raw_dump);
|
||||
print_hwcache_events(s, raw_dump);
|
||||
print_pmu_events(s, raw_dump, !desc_flag,
|
||||
long_desc_flag,
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index 36d0851c452b..c0a13cf41ef6 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -2460,6 +2460,25 @@ int print_hwcache_events(const char *event_glob, bool name_only)
|
||||
return evt_num;
|
||||
}
|
||||
|
||||
+static void print_tool_event(const char *name, const char *event_glob,
|
||||
+ bool name_only)
|
||||
+{
|
||||
+ if (event_glob && !strglobmatch(name, event_glob))
|
||||
+ return;
|
||||
+ if (name_only)
|
||||
+ printf("%s ", name);
|
||||
+ else
|
||||
+ printf(" %-50s [%s]\n", name, "Tool event");
|
||||
+
|
||||
+}
|
||||
+
|
||||
+void print_tool_events(const char *event_glob, bool name_only)
|
||||
+{
|
||||
+ print_tool_event("duration_time", event_glob, name_only);
|
||||
+ if (pager_in_use())
|
||||
+ printf("\n");
|
||||
+}
|
||||
+
|
||||
void print_symbol_events(const char *event_glob, unsigned type,
|
||||
struct event_symbol *syms, unsigned max,
|
||||
bool name_only)
|
||||
@@ -2543,6 +2562,7 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
|
||||
|
||||
print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
|
||||
event_symbols_sw, PERF_COUNT_SW_MAX, name_only);
|
||||
+ print_tool_events(event_glob, name_only);
|
||||
|
||||
print_hwcache_events(event_glob, name_only);
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
||||
index 638e2a0bec35..58c6730526f9 100644
|
||||
--- a/tools/perf/util/parse-events.h
|
||||
+++ b/tools/perf/util/parse-events.h
|
||||
@@ -203,6 +203,7 @@ extern struct event_symbol event_symbols_sw[];
|
||||
void print_symbol_events(const char *event_glob, unsigned type,
|
||||
struct event_symbol *syms, unsigned max,
|
||||
bool name_only);
|
||||
+void print_tool_events(const char *event_glob, bool name_only);
|
||||
void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
|
||||
bool name_only);
|
||||
int print_hwcache_events(const char *event_glob, bool name_only);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,476 @@
|
||||
From b1161e911d8edf2a5235b8419886018ff4ee0d64 Mon Sep 17 00:00:00 2001
|
||||
From: Andrii Nakryiko <andriin@fb.com>
|
||||
Date: Fri, 24 May 2019 11:59:00 -0700
|
||||
Subject: [PATCH 013/201] libbpf: add resizable non-thread safe internal
|
||||
hashmap
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit e3b924224028c6fc31545e3812eecbe2ddbf35f6
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e3b924224028c6fc31545e3812eecbe2ddbf35f6
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
There is a need for fast point lookups inside libbpf for multiple use
|
||||
cases (e.g., name resolution for BTF-to-C conversion, by-name lookups in
|
||||
BTF for upcoming BPF CO-RE relocation support, etc). This patch
|
||||
implements simple resizable non-thread safe hashmap using single linked
|
||||
list chains.
|
||||
|
||||
Four different insert strategies are supported:
|
||||
- HASHMAP_ADD - only add key/value if key doesn't exist yet;
|
||||
- HASHMAP_SET - add key/value pair if key doesn't exist yet; otherwise,
|
||||
update value;
|
||||
- HASHMAP_UPDATE - update value, if key already exists; otherwise, do
|
||||
nothing and return -ENOENT;
|
||||
- HASHMAP_APPEND - always add key/value pair, even if key already exists.
|
||||
This turns hashmap into a multimap by allowing multiple values to be
|
||||
associated with the same key. Most useful read API for such hashmap is
|
||||
hashmap__for_each_key_entry() iteration. If hashmap__find() is still
|
||||
used, it will return last inserted key/value entry (first in a bucket
|
||||
chain).
|
||||
|
||||
For HASHMAP_SET and HASHMAP_UPDATE, old key/value pair is returned, so
|
||||
that calling code can handle proper memory management, if necessary.
|
||||
|
||||
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
|
||||
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/lib/bpf/Build
|
||||
tools/lib/bpf/hashmap.h
|
||||
---
|
||||
tools/lib/bpf/Build | 2 +-
|
||||
tools/lib/bpf/hashmap.c | 229 ++++++++++++++++++++++++++++++++++++++++
|
||||
tools/lib/bpf/hashmap.h | 172 ++++++++++++++++++++++++++++++
|
||||
3 files changed, 402 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tools/lib/bpf/hashmap.c
|
||||
create mode 100644 tools/lib/bpf/hashmap.h
|
||||
|
||||
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
|
||||
index 6eb9bacd1948..3e993bf724db 100644
|
||||
--- a/tools/lib/bpf/Build
|
||||
+++ b/tools/lib/bpf/Build
|
||||
@@ -1 +1 @@
|
||||
-libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o str_error.o
|
||||
+libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o str_error.o hashmap.o
|
||||
diff --git a/tools/lib/bpf/hashmap.c b/tools/lib/bpf/hashmap.c
|
||||
new file mode 100644
|
||||
index 000000000000..6122272943e6
|
||||
--- /dev/null
|
||||
+++ b/tools/lib/bpf/hashmap.c
|
||||
@@ -0,0 +1,229 @@
|
||||
+// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
+
|
||||
+/*
|
||||
+ * Generic non-thread safe hash map implementation.
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Facebook
|
||||
+ */
|
||||
+#include <stdint.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
+#include <linux/err.h>
|
||||
+#include "hashmap.h"
|
||||
+
|
||||
+/* start with 4 buckets */
|
||||
+#define HASHMAP_MIN_CAP_BITS 2
|
||||
+
|
||||
+static void hashmap_add_entry(struct hashmap_entry **pprev,
|
||||
+ struct hashmap_entry *entry)
|
||||
+{
|
||||
+ entry->next = *pprev;
|
||||
+ *pprev = entry;
|
||||
+}
|
||||
+
|
||||
+static void hashmap_del_entry(struct hashmap_entry **pprev,
|
||||
+ struct hashmap_entry *entry)
|
||||
+{
|
||||
+ *pprev = entry->next;
|
||||
+ entry->next = NULL;
|
||||
+}
|
||||
+
|
||||
+void hashmap__init(struct hashmap *map, hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn, void *ctx)
|
||||
+{
|
||||
+ map->hash_fn = hash_fn;
|
||||
+ map->equal_fn = equal_fn;
|
||||
+ map->ctx = ctx;
|
||||
+
|
||||
+ map->buckets = NULL;
|
||||
+ map->cap = 0;
|
||||
+ map->cap_bits = 0;
|
||||
+ map->sz = 0;
|
||||
+}
|
||||
+
|
||||
+struct hashmap *hashmap__new(hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn,
|
||||
+ void *ctx)
|
||||
+{
|
||||
+ struct hashmap *map = malloc(sizeof(struct hashmap));
|
||||
+
|
||||
+ if (!map)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+ hashmap__init(map, hash_fn, equal_fn, ctx);
|
||||
+ return map;
|
||||
+}
|
||||
+
|
||||
+void hashmap__clear(struct hashmap *map)
|
||||
+{
|
||||
+ free(map->buckets);
|
||||
+ map->cap = map->cap_bits = map->sz = 0;
|
||||
+}
|
||||
+
|
||||
+void hashmap__free(struct hashmap *map)
|
||||
+{
|
||||
+ if (!map)
|
||||
+ return;
|
||||
+
|
||||
+ hashmap__clear(map);
|
||||
+ free(map);
|
||||
+}
|
||||
+
|
||||
+size_t hashmap__size(const struct hashmap *map)
|
||||
+{
|
||||
+ return map->sz;
|
||||
+}
|
||||
+
|
||||
+size_t hashmap__capacity(const struct hashmap *map)
|
||||
+{
|
||||
+ return map->cap;
|
||||
+}
|
||||
+
|
||||
+static bool hashmap_needs_to_grow(struct hashmap *map)
|
||||
+{
|
||||
+ /* grow if empty or more than 75% filled */
|
||||
+ return (map->cap == 0) || ((map->sz + 1) * 4 / 3 > map->cap);
|
||||
+}
|
||||
+
|
||||
+static int hashmap_grow(struct hashmap *map)
|
||||
+{
|
||||
+ struct hashmap_entry **new_buckets;
|
||||
+ struct hashmap_entry *cur, *tmp;
|
||||
+ size_t new_cap_bits, new_cap;
|
||||
+ size_t h;
|
||||
+ int bkt;
|
||||
+
|
||||
+ new_cap_bits = map->cap_bits + 1;
|
||||
+ if (new_cap_bits < HASHMAP_MIN_CAP_BITS)
|
||||
+ new_cap_bits = HASHMAP_MIN_CAP_BITS;
|
||||
+
|
||||
+ new_cap = 1UL << new_cap_bits;
|
||||
+ new_buckets = calloc(new_cap, sizeof(new_buckets[0]));
|
||||
+ if (!new_buckets)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hashmap__for_each_entry_safe(map, cur, tmp, bkt) {
|
||||
+ h = hash_bits(map->hash_fn(cur->key, map->ctx), new_cap_bits);
|
||||
+ hashmap_add_entry(&new_buckets[h], cur);
|
||||
+ }
|
||||
+
|
||||
+ map->cap = new_cap;
|
||||
+ map->cap_bits = new_cap_bits;
|
||||
+ free(map->buckets);
|
||||
+ map->buckets = new_buckets;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static bool hashmap_find_entry(const struct hashmap *map,
|
||||
+ const void *key, size_t hash,
|
||||
+ struct hashmap_entry ***pprev,
|
||||
+ struct hashmap_entry **entry)
|
||||
+{
|
||||
+ struct hashmap_entry *cur, **prev_ptr;
|
||||
+
|
||||
+ if (!map->buckets)
|
||||
+ return false;
|
||||
+
|
||||
+ for (prev_ptr = &map->buckets[hash], cur = *prev_ptr;
|
||||
+ cur;
|
||||
+ prev_ptr = &cur->next, cur = cur->next) {
|
||||
+ if (map->equal_fn(cur->key, key, map->ctx)) {
|
||||
+ if (pprev)
|
||||
+ *pprev = prev_ptr;
|
||||
+ *entry = cur;
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+int hashmap__insert(struct hashmap *map, const void *key, void *value,
|
||||
+ enum hashmap_insert_strategy strategy,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ struct hashmap_entry *entry;
|
||||
+ size_t h;
|
||||
+ int err;
|
||||
+
|
||||
+ if (old_key)
|
||||
+ *old_key = NULL;
|
||||
+ if (old_value)
|
||||
+ *old_value = NULL;
|
||||
+
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ if (strategy != HASHMAP_APPEND &&
|
||||
+ hashmap_find_entry(map, key, h, NULL, &entry)) {
|
||||
+ if (old_key)
|
||||
+ *old_key = entry->key;
|
||||
+ if (old_value)
|
||||
+ *old_value = entry->value;
|
||||
+
|
||||
+ if (strategy == HASHMAP_SET || strategy == HASHMAP_UPDATE) {
|
||||
+ entry->key = key;
|
||||
+ entry->value = value;
|
||||
+ return 0;
|
||||
+ } else if (strategy == HASHMAP_ADD) {
|
||||
+ return -EEXIST;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (strategy == HASHMAP_UPDATE)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ if (hashmap_needs_to_grow(map)) {
|
||||
+ err = hashmap_grow(map);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ }
|
||||
+
|
||||
+ entry = malloc(sizeof(struct hashmap_entry));
|
||||
+ if (!entry)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ entry->key = key;
|
||||
+ entry->value = value;
|
||||
+ hashmap_add_entry(&map->buckets[h], entry);
|
||||
+ map->sz++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+bool hashmap__find(const struct hashmap *map, const void *key, void **value)
|
||||
+{
|
||||
+ struct hashmap_entry *entry;
|
||||
+ size_t h;
|
||||
+
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ if (!hashmap_find_entry(map, key, h, NULL, &entry))
|
||||
+ return false;
|
||||
+
|
||||
+ if (value)
|
||||
+ *value = entry->value;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool hashmap__delete(struct hashmap *map, const void *key,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ struct hashmap_entry **pprev, *entry;
|
||||
+ size_t h;
|
||||
+
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ if (!hashmap_find_entry(map, key, h, &pprev, &entry))
|
||||
+ return false;
|
||||
+
|
||||
+ if (old_key)
|
||||
+ *old_key = entry->key;
|
||||
+ if (old_value)
|
||||
+ *old_value = entry->value;
|
||||
+
|
||||
+ hashmap_del_entry(pprev, entry);
|
||||
+ free(entry);
|
||||
+ map->sz--;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h
|
||||
new file mode 100644
|
||||
index 000000000000..ab97b9797100
|
||||
--- /dev/null
|
||||
+++ b/tools/lib/bpf/hashmap.h
|
||||
@@ -0,0 +1,172 @@
|
||||
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||
+
|
||||
+/*
|
||||
+ * Generic non-thread safe hash map implementation.
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Facebook
|
||||
+ */
|
||||
+#ifndef __LIBBPF_HASHMAP_H
|
||||
+#define __LIBBPF_HASHMAP_H
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+static inline size_t hash_bits(size_t h, int bits)
|
||||
+{
|
||||
+ /* shuffle bits and return requested number of upper bits */
|
||||
+ return (h * 11400714819323198485llu) >> (__WORDSIZE - bits);
|
||||
+}
|
||||
+
|
||||
+typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
||||
+typedef bool (*hashmap_equal_fn)(const void *key1, const void *key2, void *ctx);
|
||||
+
|
||||
+struct hashmap_entry {
|
||||
+ const void *key;
|
||||
+ void *value;
|
||||
+ struct hashmap_entry *next;
|
||||
+};
|
||||
+
|
||||
+struct hashmap {
|
||||
+ hashmap_hash_fn hash_fn;
|
||||
+ hashmap_equal_fn equal_fn;
|
||||
+ void *ctx;
|
||||
+
|
||||
+ struct hashmap_entry **buckets;
|
||||
+ size_t cap;
|
||||
+ size_t cap_bits;
|
||||
+ size_t sz;
|
||||
+};
|
||||
+
|
||||
+#define HASHMAP_INIT(hash_fn, equal_fn, ctx) { \
|
||||
+ .hash_fn = (hash_fn), \
|
||||
+ .equal_fn = (equal_fn), \
|
||||
+ .ctx = (ctx), \
|
||||
+ .buckets = NULL, \
|
||||
+ .cap = 0, \
|
||||
+ .cap_bits = 0, \
|
||||
+ .sz = 0, \
|
||||
+}
|
||||
+
|
||||
+void hashmap__init(struct hashmap *map, hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn, void *ctx);
|
||||
+struct hashmap *hashmap__new(hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn,
|
||||
+ void *ctx);
|
||||
+void hashmap__clear(struct hashmap *map);
|
||||
+void hashmap__free(struct hashmap *map);
|
||||
+
|
||||
+size_t hashmap__size(const struct hashmap *map);
|
||||
+size_t hashmap__capacity(const struct hashmap *map);
|
||||
+
|
||||
+/*
|
||||
+ * Hashmap insertion strategy:
|
||||
+ * - HASHMAP_ADD - only add key/value if key doesn't exist yet;
|
||||
+ * - HASHMAP_SET - add key/value pair if key doesn't exist yet; otherwise,
|
||||
+ * update value;
|
||||
+ * - HASHMAP_UPDATE - update value, if key already exists; otherwise, do
|
||||
+ * nothing and return -ENOENT;
|
||||
+ * - HASHMAP_APPEND - always add key/value pair, even if key already exists.
|
||||
+ * This turns hashmap into a multimap by allowing multiple values to be
|
||||
+ * associated with the same key. Most useful read API for such hashmap is
|
||||
+ * hashmap__for_each_key_entry() iteration. If hashmap__find() is still
|
||||
+ * used, it will return last inserted key/value entry (first in a bucket
|
||||
+ * chain).
|
||||
+ */
|
||||
+enum hashmap_insert_strategy {
|
||||
+ HASHMAP_ADD,
|
||||
+ HASHMAP_SET,
|
||||
+ HASHMAP_UPDATE,
|
||||
+ HASHMAP_APPEND,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__insert() adds key/value entry w/ various semantics, depending on
|
||||
+ * provided strategy value. If a given key/value pair replaced already
|
||||
+ * existing key/value pair, both old key and old value will be returned
|
||||
+ * through old_key and old_value to allow calling code do proper memory
|
||||
+ * management.
|
||||
+ */
|
||||
+int hashmap__insert(struct hashmap *map, const void *key, void *value,
|
||||
+ enum hashmap_insert_strategy strategy,
|
||||
+ const void **old_key, void **old_value);
|
||||
+
|
||||
+static inline int hashmap__add(struct hashmap *map,
|
||||
+ const void *key, void *value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_ADD, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+static inline int hashmap__set(struct hashmap *map,
|
||||
+ const void *key, void *value,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_SET,
|
||||
+ old_key, old_value);
|
||||
+}
|
||||
+
|
||||
+static inline int hashmap__update(struct hashmap *map,
|
||||
+ const void *key, void *value,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_UPDATE,
|
||||
+ old_key, old_value);
|
||||
+}
|
||||
+
|
||||
+static inline int hashmap__append(struct hashmap *map,
|
||||
+ const void *key, void *value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_APPEND, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+bool hashmap__delete(struct hashmap *map, const void *key,
|
||||
+ const void **old_key, void **old_value);
|
||||
+
|
||||
+bool hashmap__find(const struct hashmap *map, const void *key, void **value);
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__for_each_entry - iterate over all entries in hashmap
|
||||
+ * @map: hashmap to iterate
|
||||
+ * @cur: struct hashmap_entry * used as a loop cursor
|
||||
+ * @bkt: integer used as a bucket loop cursor
|
||||
+ */
|
||||
+#define hashmap__for_each_entry(map, cur, bkt) \
|
||||
+ for (bkt = 0; bkt < map->cap; bkt++) \
|
||||
+ for (cur = map->buckets[bkt]; cur; cur = cur->next)
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__for_each_entry_safe - iterate over all entries in hashmap, safe
|
||||
+ * against removals
|
||||
+ * @map: hashmap to iterate
|
||||
+ * @cur: struct hashmap_entry * used as a loop cursor
|
||||
+ * @tmp: struct hashmap_entry * used as a temporary next cursor storage
|
||||
+ * @bkt: integer used as a bucket loop cursor
|
||||
+ */
|
||||
+#define hashmap__for_each_entry_safe(map, cur, tmp, bkt) \
|
||||
+ for (bkt = 0; bkt < map->cap; bkt++) \
|
||||
+ for (cur = map->buckets[bkt]; \
|
||||
+ cur && ({tmp = cur->next; true; }); \
|
||||
+ cur = tmp)
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__for_each_key_entry - iterate over entries associated with given key
|
||||
+ * @map: hashmap to iterate
|
||||
+ * @cur: struct hashmap_entry * used as a loop cursor
|
||||
+ * @key: key to iterate entries for
|
||||
+ */
|
||||
+#define hashmap__for_each_key_entry(map, cur, _key) \
|
||||
+ for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
+ map->cap_bits); \
|
||||
+ map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ cur; \
|
||||
+ cur = cur->next) \
|
||||
+ if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
+
|
||||
+#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
|
||||
+ for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
+ map->cap_bits); \
|
||||
+ cur = map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ cur && ({ tmp = cur->next; true; }); \
|
||||
+ cur = tmp) \
|
||||
+ if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
+
|
||||
+#endif /* __LIBBPF_HASHMAP_H */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
82
patches/0131-perf-stat-Fix-metrics-with-no-merge.patch
Normal file
82
patches/0131-perf-stat-Fix-metrics-with-no-merge.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From 7dfd2106230977845705617a25773803c1ce2e5a Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Mon, 24 Jun 2019 12:37:11 -0700
|
||||
Subject: [PATCH 014/201] perf stat: Fix metrics with --no-merge
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit e3a9427323a53ceee540276a74af7706f350d052
|
||||
category: feature
|
||||
bugzilla: e3a9427323a53ceee540276a74af7706f350d052
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e3a9427323a53ceee540276a74af7706f350d052
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Since Fixes: 8c5421c016a4 ("perf pmu: Display pmu name when printing
|
||||
unmerged events in stat") using --no-merge adds the PMU name to the
|
||||
evsel name.
|
||||
|
||||
This breaks the metric value lookup because the parser doesn't know
|
||||
about this.
|
||||
|
||||
Remove the extra postfixes for the metric evaluation.
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Agustin Vega-Frias <agustinv@codeaurora.org>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Fixes: 8c5421c016a4 ("perf pmu: Display pmu name when printing unmerged events in stat")
|
||||
Link: http://lkml.kernel.org/r/20190624193711.35241-5-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/stat-shadow.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index 93c075ddc717..77982aae7aaf 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -723,6 +723,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
double ratio;
|
||||
int i;
|
||||
void *ctxp = out->ctx;
|
||||
+ char *n, *pn;
|
||||
|
||||
expr__ctx_init(&pctx);
|
||||
expr__add_id(&pctx, name, avg);
|
||||
@@ -742,7 +743,19 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
stats = &v->stats;
|
||||
scale = 1.0;
|
||||
}
|
||||
- expr__add_id(&pctx, metric_events[i]->name, avg_stats(stats)*scale);
|
||||
+
|
||||
+ n = strdup(metric_events[i]->name);
|
||||
+ if (!n)
|
||||
+ return;
|
||||
+ /*
|
||||
+ * This display code with --no-merge adds [cpu] postfixes.
|
||||
+ * These are not supported by the parser. Remove everything
|
||||
+ * after the space.
|
||||
+ */
|
||||
+ pn = strchr(n, ' ');
|
||||
+ if (pn)
|
||||
+ *pn = 0;
|
||||
+ expr__add_id(&pctx, n, avg_stats(stats)*scale);
|
||||
}
|
||||
if (!metric_events[i]) {
|
||||
const char *p = metric_expr;
|
||||
@@ -759,6 +772,9 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
(metric_name ? metric_name : name) : "", 0);
|
||||
} else
|
||||
print_metric(config, ctxp, NULL, NULL, "", 0);
|
||||
+
|
||||
+ for (i = 1; i < pctx.num_ids; i++)
|
||||
+ free((void *)pctx.ids[i].name);
|
||||
}
|
||||
|
||||
void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
54
patches/0132-perf-jevents-Remove-unused-variable.patch
Normal file
54
patches/0132-perf-jevents-Remove-unused-variable.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 1e5e3a66f153300977d6d74aec7fb87a47532f95 Mon Sep 17 00:00:00 2001
|
||||
From: Zenghui Yu <yuzenghui@huawei.com>
|
||||
Date: Wed, 15 May 2019 11:19:29 +0000
|
||||
Subject: [PATCH 015/201] perf jevents: Remove unused variable
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.2-rc1
|
||||
commit 8e8f515d567f9ec1d960e9fdb117d39753b7504d
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8e8f515d567f9ec1d960e9fdb117d39753b7504d
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Address gcc warning:
|
||||
|
||||
pmu-events/jevents.c: In function ‘save_arch_std_events’:
|
||||
pmu-events/jevents.c:417:15: warning: unused variable ‘sb’ [-Wunused-variable]
|
||||
struct stat *sb = data;
|
||||
^~
|
||||
|
||||
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: wanghaibin.wang@huawei.com
|
||||
Link: http://lkml.kernel.org/r/1557919169-23972-1-git-send-email-yuzenghui@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/pmu-events/jevents.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index af7f961b1edc..1209d0feaeb5 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -417,7 +417,6 @@ static int save_arch_std_events(void *data, char *name, char *event,
|
||||
char *metric_name, char *metric_group)
|
||||
{
|
||||
struct event_struct *es;
|
||||
- struct stat *sb = data;
|
||||
|
||||
es = malloc(sizeof(*es));
|
||||
if (!es)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From ae0acec647f86efed2ac7a8d94852efc4136e8ed Mon Sep 17 00:00:00 2001
|
||||
From: Luke Mujica <lukemujica@google.com>
|
||||
Date: Tue, 25 Jun 2019 10:31:22 -0700
|
||||
Subject: [PATCH 016/201] perf jevents: Use nonlocal include statements in
|
||||
pmu-events.c
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 06c642c0e9fceafd16b1a4c80d44b1c09e282215
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=06c642c0e9fceafd16b1a4c80d44b1c09e282215
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Change pmu-events.c to not use local include statements. The code that
|
||||
creates the include statements for pmu-events.c is in jevents.c.
|
||||
|
||||
pmu-events.c is a generated file, and for build systems that put
|
||||
generated files in a separate directory, include statements with local
|
||||
pathing cannot find non-generated files.
|
||||
|
||||
Signed-off-by: Luke Mujica <lukemujica@google.com>
|
||||
Cc: Ian Rogers <irogers@google.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Numfor Mbiziwo-Tiapo <nums@google.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: https://lkml.kernel.org/n/tip-prgnwmaoo1pv9zz4vnv1bjaj@git.kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/pmu-events/jevents.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index 1209d0feaeb5..55c8bf2b0b32 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -849,7 +849,7 @@ static void create_empty_mapping(const char *output_file)
|
||||
_Exit(1);
|
||||
}
|
||||
|
||||
- fprintf(outfp, "#include \"../../pmu-events/pmu-events.h\"\n");
|
||||
+ fprintf(outfp, "#include \"pmu-events/pmu-events.h\"\n");
|
||||
print_mapping_table_prefix(outfp);
|
||||
print_mapping_table_suffix(outfp);
|
||||
fclose(outfp);
|
||||
@@ -1103,7 +1103,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Include pmu-events.h first */
|
||||
- fprintf(eventsfp, "#include \"../../pmu-events/pmu-events.h\"\n");
|
||||
+ fprintf(eventsfp, "#include \"pmu-events/pmu-events.h\"\n");
|
||||
|
||||
/*
|
||||
* The mapfile allows multiple CPUids to point to the same JSON file,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
43
patches/0134-perf-list-Avoid-extra-for-raw-metrics.patch
Normal file
43
patches/0134-perf-list-Avoid-extra-for-raw-metrics.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 936090e8e295cd14a5ac086baba7123ec345de95 Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Fri, 28 Jun 2019 15:07:36 -0700
|
||||
Subject: [PATCH 017/201] perf list: Avoid extra : for --raw metrics
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 9c344d15f5783260f57c711f3fce72dd744bebe2
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9c344d15f5783260f57c711f3fce72dd744bebe2
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
When printing the metrics raw, don't print : after the metricgroups.
|
||||
This helps the command line completion to complete those too.
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Link: http://lkml.kernel.org/r/20190628220737.13259-2-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 27552a0b990a..90c22757ca9d 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -388,7 +388,7 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
|
||||
struct mep *me = container_of(node, struct mep, nd);
|
||||
|
||||
if (metricgroups)
|
||||
- printf("%s%s%s", me->name, metrics ? ":" : "", raw ? " " : "\n");
|
||||
+ printf("%s%s%s", me->name, metrics && !raw ? ":" : "", raw ? " " : "\n");
|
||||
if (metrics)
|
||||
metricgroup__print_strlist(me->metrics, raw);
|
||||
next = rb_next(node);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
From 4f8b8c59605dc32e5224879c3e24ac750a05b482 Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Fri, 28 Jun 2019 15:07:37 -0700
|
||||
Subject: [PATCH 018/201] perf tools metric: Don't include duration_time in
|
||||
group
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 488c3bf7ece89e47887607863207021283e37828
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=488c3bf7ece89e47887607863207021283e37828
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The Memory_BW metric generates groups including duration_time, which
|
||||
maps to a software event.
|
||||
|
||||
For some reason this makes the group always not count.
|
||||
|
||||
Always put duration_time outside a group when generating metrics. It's
|
||||
always the same time, so no need to group it.
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Link: http://lkml.kernel.org/r/20190628220737.13259-3-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 90c22757ca9d..dae3779d4fef 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -422,6 +422,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
const char **ids;
|
||||
int idnum;
|
||||
struct egroup *eg;
|
||||
+ bool no_group = false;
|
||||
|
||||
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
|
||||
|
||||
@@ -432,11 +433,25 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
strbuf_addf(events, ",");
|
||||
for (j = 0; j < idnum; j++) {
|
||||
pr_debug("found event %s\n", ids[j]);
|
||||
+ /*
|
||||
+ * Duration time maps to a software event and can make
|
||||
+ * groups not count. Always use it outside a
|
||||
+ * group.
|
||||
+ */
|
||||
+ if (!strcmp(ids[j], "duration_time")) {
|
||||
+ if (j > 0)
|
||||
+ strbuf_addf(events, "}:W,");
|
||||
+ strbuf_addf(events, "duration_time");
|
||||
+ no_group = true;
|
||||
+ continue;
|
||||
+ }
|
||||
strbuf_addf(events, "%s%s",
|
||||
- j == 0 ? "{" : ",",
|
||||
+ j == 0 || no_group ? "{" : ",",
|
||||
ids[j]);
|
||||
+ no_group = false;
|
||||
}
|
||||
- strbuf_addf(events, "}:W");
|
||||
+ if (!no_group)
|
||||
+ strbuf_addf(events, "}:W");
|
||||
|
||||
eg = malloc(sizeof(struct egroup));
|
||||
if (!eg) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From 05ef3cb8a048bcc5eb4a16faae5e192a521a240c Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Thu, 4 Jul 2019 12:20:21 -0300
|
||||
Subject: [PATCH 019/201] perf metricgroup: Add missing list_del_init() when
|
||||
flushing egroups list
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit acc7bfb3db9744c4a18c96fd6536069e8647cb11
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=acc7bfb3db9744c4a18c96fd6536069e8647cb11
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
So that at the end each of the entries have its list node struct cleared
|
||||
and the egroup list head ends emptied.
|
||||
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Link: https://lkml.kernel.org/n/tip-dxzj1ah350fy9ec0xbhb15b6@git.kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index dae3779d4fef..4c6ecda3e7ac 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -504,6 +504,7 @@ static void metricgroup__free_egroups(struct list_head *group_list)
|
||||
for (i = 0; i < eg->idnum; i++)
|
||||
free((char *)eg->ids[i]);
|
||||
free(eg->ids);
|
||||
+ list_del_init(&eg->nd);
|
||||
free(eg);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
From dfb7c7fcf8833337c750f07a2f876f5f22e1f1be Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Wed, 21 Aug 2019 10:54:14 -0300
|
||||
Subject: [PATCH 020/201] perf metricgroup: Remove needless includes from
|
||||
metricgroup.h
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.4-rc1
|
||||
commit 0b8026e8fb0ea3893caa2f1924a2c15fcf6760b3
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0b8026e8fb0ea3893caa2f1924a2c15fcf6760b3
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
There we need just some struct forward declarations, do that instead and
|
||||
add the includes needed by metricgroup.c.
|
||||
|
||||
That should help with needless rebuilds when changing the removed
|
||||
headers from metricgroup.h.
|
||||
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Link: https://lkml.kernel.org/n/tip-1fkskjws6imir2hhztqhdyb0@git.kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
tools/perf/util/metricgroup.h
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 3 ++-
|
||||
tools/perf/util/metricgroup.h | 13 ++++++++-----
|
||||
2 files changed, 10 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 4c6ecda3e7ac..503cd543de9c 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -16,17 +16,18 @@
|
||||
|
||||
#include "metricgroup.h"
|
||||
#include "evlist.h"
|
||||
+#include "evsel.h"
|
||||
#include "strbuf.h"
|
||||
#include "pmu.h"
|
||||
#include "expr.h"
|
||||
#include "rblist.h"
|
||||
#include <string.h>
|
||||
-#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include "pmu-events/pmu-events.h"
|
||||
#include "strlist.h"
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
+#include <subcmd/parse-options.h>
|
||||
|
||||
struct metric_event *metricgroup__lookup(struct rblist *metric_events,
|
||||
struct perf_evsel *evsel,
|
||||
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
|
||||
index 5c52097a5c63..b5d785f37073 100644
|
||||
--- a/tools/perf/util/metricgroup.h
|
||||
+++ b/tools/perf/util/metricgroup.h
|
||||
@@ -1,11 +1,14 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
#ifndef METRICGROUP_H
|
||||
#define METRICGROUP_H 1
|
||||
|
||||
-#include "linux/list.h"
|
||||
-#include "rblist.h"
|
||||
-#include <subcmd/parse-options.h>
|
||||
-#include "evlist.h"
|
||||
-#include "strbuf.h"
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/rbtree.h>
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+struct perf_evsel;
|
||||
+struct option;
|
||||
+struct rblist;
|
||||
|
||||
struct metric_event {
|
||||
struct rb_node nd;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
From ab598ff7883c85c929b287a06501d9df15b1a42c Mon Sep 17 00:00:00 2001
|
||||
From: Jin Yao <yao.jin@linux.intel.com>
|
||||
Date: Wed, 28 Aug 2019 13:59:29 +0800
|
||||
Subject: [PATCH 021/201] perf pmu: Change convert_scale from static to global
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.4-rc1
|
||||
commit 287f2649f791819dd2d8f32f0213c8c521d6dfa0
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=287f2649f791819dd2d8f32f0213c8c521d6dfa0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The function convert_scale() can be used to convert string to unit and
|
||||
scale. For example,
|
||||
|
||||
s = "6000000000ns";
|
||||
convert_scale(s, &unit, &scale);
|
||||
|
||||
unit = "ns", scale = 6000000000.
|
||||
|
||||
Currently this function is static. This patch renames the function to
|
||||
perf_pmu__convert_scale and changes the function to global. No
|
||||
functional change.
|
||||
|
||||
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lore.kernel.org/lkml/20190828055932.8269-2-yao.jin@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/pmu.c | 6 +++---
|
||||
tools/perf/util/pmu.h | 2 ++
|
||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
|
||||
index aa91fcb51a6d..256a9792bd7e 100644
|
||||
--- a/tools/perf/util/pmu.c
|
||||
+++ b/tools/perf/util/pmu.c
|
||||
@@ -100,7 +100,7 @@ static int pmu_format(const char *name, struct list_head *format)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int convert_scale(const char *scale, char **end, double *sval)
|
||||
+int perf_pmu__convert_scale(const char *scale, char **end, double *sval)
|
||||
{
|
||||
char *lc;
|
||||
int ret = 0;
|
||||
@@ -163,7 +163,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
|
||||
else
|
||||
scale[sret] = '\0';
|
||||
|
||||
- ret = convert_scale(scale, NULL, &alias->scale);
|
||||
+ ret = perf_pmu__convert_scale(scale, NULL, &alias->scale);
|
||||
error:
|
||||
close(fd);
|
||||
return ret;
|
||||
@@ -371,7 +371,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
|
||||
desc ? strdup(desc) : NULL;
|
||||
alias->topic = topic ? strdup(topic) : NULL;
|
||||
if (unit) {
|
||||
- if (convert_scale(unit, &unit, &alias->scale) < 0)
|
||||
+ if (perf_pmu__convert_scale(unit, &unit, &alias->scale) < 0)
|
||||
return -1;
|
||||
snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
|
||||
}
|
||||
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
|
||||
index 76fecec7b3f9..ea0e7c36eae9 100644
|
||||
--- a/tools/perf/util/pmu.h
|
||||
+++ b/tools/perf/util/pmu.h
|
||||
@@ -94,4 +94,6 @@ struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu);
|
||||
|
||||
struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu);
|
||||
|
||||
+int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
|
||||
+
|
||||
#endif /* __PMU_H */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
186
patches/0139-perf-metricgroup-Scale-the-metric-result.patch
Normal file
186
patches/0139-perf-metricgroup-Scale-the-metric-result.patch
Normal file
@ -0,0 +1,186 @@
|
||||
From a9fa8ae0dd8e2c2cddf376b6ce19f06bf812992d Mon Sep 17 00:00:00 2001
|
||||
From: Jin Yao <yao.jin@linux.intel.com>
|
||||
Date: Wed, 28 Aug 2019 13:59:31 +0800
|
||||
Subject: [PATCH 022/201] perf metricgroup: Scale the metric result
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.4-rc1
|
||||
commit 287f2649f791819dd2d8f32f0213c8c521d6dfa0
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=287f2649f791819dd2d8f32f0213c8c521d6dfa0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Some metrics define the scale unit, such as
|
||||
|
||||
{
|
||||
"BriefDescription": "Intel Optane DC persistent memory read latency (ns). Derived from unc_m_pmm_rpq_occupancy.all",
|
||||
"Counter": "0,1,2,3",
|
||||
"EventCode": "0xE0",
|
||||
"EventName": "UNC_M_PMM_READ_LATENCY",
|
||||
"MetricExpr": "UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS",
|
||||
"MetricName": "UNC_M_PMM_READ_LATENCY",
|
||||
"PerPkg": "1",
|
||||
"ScaleUnit": "6000000000ns",
|
||||
"UMask": "0x1",
|
||||
"Unit": "iMC"
|
||||
},
|
||||
|
||||
For above example, the ratio should be,
|
||||
|
||||
ratio = (UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS) * 6000000000
|
||||
|
||||
But in current code, the ratio is not scaled ( * 6000000000)
|
||||
|
||||
With this patch, the ratio is scaled and the unit (ns) is printed.
|
||||
|
||||
For example,
|
||||
# 219.4 ns UNC_M_PMM_READ_LATENCY
|
||||
|
||||
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lore.kernel.org/lkml/20190828055932.8269-4-yao.jin@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 3 +++
|
||||
tools/perf/util/metricgroup.h | 1 +
|
||||
tools/perf/util/stat-shadow.c | 38 +++++++++++++++++++++++++----------
|
||||
3 files changed, 31 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 503cd543de9c..d01f16448bab 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -93,6 +93,7 @@ struct egroup {
|
||||
const char **ids;
|
||||
const char *metric_name;
|
||||
const char *metric_expr;
|
||||
+ const char *metric_unit;
|
||||
};
|
||||
|
||||
static bool record_evsel(int *ind, struct perf_evsel **start,
|
||||
@@ -191,6 +192,7 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
}
|
||||
expr->metric_expr = eg->metric_expr;
|
||||
expr->metric_name = eg->metric_name;
|
||||
+ expr->metric_unit = eg->metric_unit;
|
||||
expr->metric_events = metric_events;
|
||||
list_add(&expr->nd, &me->head);
|
||||
}
|
||||
@@ -463,6 +465,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
eg->idnum = idnum;
|
||||
eg->metric_name = pe->metric_name;
|
||||
eg->metric_expr = pe->metric_expr;
|
||||
+ eg->metric_unit = pe->unit;
|
||||
list_add_tail(&eg->nd, group_list);
|
||||
ret = 0;
|
||||
}
|
||||
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
|
||||
index b5d785f37073..9c6e6913f905 100644
|
||||
--- a/tools/perf/util/metricgroup.h
|
||||
+++ b/tools/perf/util/metricgroup.h
|
||||
@@ -20,6 +20,7 @@ struct metric_expr {
|
||||
struct list_head nd;
|
||||
const char *metric_expr;
|
||||
const char *metric_name;
|
||||
+ const char *metric_unit;
|
||||
struct perf_evsel **metric_events;
|
||||
};
|
||||
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index 77982aae7aaf..f687ca257e5d 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -713,6 +713,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
struct perf_evsel **metric_events,
|
||||
char *name,
|
||||
const char *metric_name,
|
||||
+ const char *metric_unit,
|
||||
double avg,
|
||||
int cpu,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -720,7 +721,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
{
|
||||
print_metric_t print_metric = out->print_metric;
|
||||
struct parse_ctx pctx;
|
||||
- double ratio;
|
||||
+ double ratio, scale;
|
||||
int i;
|
||||
void *ctxp = out->ctx;
|
||||
char *n, *pn;
|
||||
@@ -730,7 +731,6 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
for (i = 0; metric_events[i]; i++) {
|
||||
struct saved_value *v;
|
||||
struct stats *stats;
|
||||
- double scale;
|
||||
|
||||
if (!strcmp(metric_events[i]->name, "duration_time")) {
|
||||
stats = &walltime_nsecs_stats;
|
||||
@@ -760,16 +760,32 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
if (!metric_events[i]) {
|
||||
const char *p = metric_expr;
|
||||
|
||||
- if (expr__parse(&ratio, &pctx, &p) == 0)
|
||||
- print_metric(config, ctxp, NULL, "%8.1f",
|
||||
- metric_name ?
|
||||
- metric_name :
|
||||
- out->force_header ? name : "",
|
||||
- ratio);
|
||||
- else
|
||||
+ if (expr__parse(&ratio, &pctx, &p) == 0) {
|
||||
+ char *unit;
|
||||
+ char metric_bf[64];
|
||||
+
|
||||
+ if (metric_unit && metric_name) {
|
||||
+ if (perf_pmu__convert_scale(metric_unit,
|
||||
+ &unit, &scale) >= 0) {
|
||||
+ ratio *= scale;
|
||||
+ }
|
||||
+
|
||||
+ scnprintf(metric_bf, sizeof(metric_bf),
|
||||
+ "%s %s", unit, metric_name);
|
||||
+ print_metric(config, ctxp, NULL, "%8.1f",
|
||||
+ metric_bf, ratio);
|
||||
+ } else {
|
||||
+ print_metric(config, ctxp, NULL, "%8.1f",
|
||||
+ metric_name ?
|
||||
+ metric_name :
|
||||
+ out->force_header ? name : "",
|
||||
+ ratio);
|
||||
+ }
|
||||
+ } else {
|
||||
print_metric(config, ctxp, NULL, NULL,
|
||||
out->force_header ?
|
||||
(metric_name ? metric_name : name) : "", 0);
|
||||
+ }
|
||||
} else
|
||||
print_metric(config, ctxp, NULL, NULL, "", 0);
|
||||
|
||||
@@ -989,7 +1005,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
print_metric(config, ctxp, NULL, NULL, name, 0);
|
||||
} else if (evsel->metric_expr) {
|
||||
generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name,
|
||||
- evsel->metric_name, avg, cpu, out, st);
|
||||
+ evsel->metric_name, NULL, avg, cpu, out, st);
|
||||
} else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) {
|
||||
char unit = 'M';
|
||||
char unit_buf[10];
|
||||
@@ -1018,7 +1034,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
out->new_line(config, ctxp);
|
||||
generic_metric(config, mexp->metric_expr, mexp->metric_events,
|
||||
evsel->name, mexp->metric_name,
|
||||
- avg, cpu, out, st);
|
||||
+ mexp->metric_unit, avg, cpu, out, st);
|
||||
}
|
||||
}
|
||||
if (num == 0)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,316 @@
|
||||
From c650ff6651b9ee0f846f73275d580f062197ec78 Mon Sep 17 00:00:00 2001
|
||||
From: Jin Yao <yao.jin@linux.intel.com>
|
||||
Date: Wed, 28 Aug 2019 13:59:32 +0800
|
||||
Subject: [PATCH 023/201] perf metricgroup: Support multiple events for
|
||||
metricgroup
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.4-rc1
|
||||
commit f01642e4912bb80a01d693f4cc6fb0897207a090
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f01642e4912bb80a01d693f4cc6fb0897207a090
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Some uncore metrics don't work as expected. For example, on
|
||||
cascadelakex:
|
||||
|
||||
root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_BANDWIDTH.TOTAL -a -- sleep 1
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
1841092 unc_m_pmm_rpq_inserts
|
||||
3680816 unc_m_pmm_wpq_inserts
|
||||
|
||||
1.001775055 seconds time elapsed
|
||||
|
||||
root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_READ_LATENCY -a -- sleep 1
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
860649746 unc_m_pmm_rpq_occupancy.all
|
||||
1840557 unc_m_pmm_rpq_inserts
|
||||
12790627455 unc_m_clockticks
|
||||
|
||||
1.001773348 seconds time elapsed
|
||||
|
||||
No metrics 'UNC_M_PMM_BANDWIDTH.TOTAL' or 'UNC_M_PMM_READ_LATENCY' are
|
||||
reported.
|
||||
|
||||
The issue is, the case of an alias expanding to mulitple events is not
|
||||
supported, typically the uncore events. (see comments in
|
||||
find_evsel_group()).
|
||||
|
||||
For UNC_M_PMM_BANDWIDTH.TOTAL in above example, the expanded event group
|
||||
is '{unc_m_pmm_rpq_inserts,unc_m_pmm_wpq_inserts}:W', but the actual
|
||||
events passed to find_evsel_group are:
|
||||
|
||||
unc_m_pmm_rpq_inserts
|
||||
unc_m_pmm_rpq_inserts
|
||||
unc_m_pmm_rpq_inserts
|
||||
unc_m_pmm_rpq_inserts
|
||||
unc_m_pmm_rpq_inserts
|
||||
unc_m_pmm_rpq_inserts
|
||||
unc_m_pmm_wpq_inserts
|
||||
unc_m_pmm_wpq_inserts
|
||||
unc_m_pmm_wpq_inserts
|
||||
unc_m_pmm_wpq_inserts
|
||||
unc_m_pmm_wpq_inserts
|
||||
unc_m_pmm_wpq_inserts
|
||||
|
||||
For this multiple events case, it's not supported well.
|
||||
|
||||
This patch introduces a new field 'metric_leader' in struct evsel. The
|
||||
first event is considered as a metric leader. For the rest of same
|
||||
events, they point to the first event via it's metric_leader field in
|
||||
struct evsel.
|
||||
|
||||
This design is for adding the counting results of all same events to the
|
||||
first event in group (the metric_leader).
|
||||
|
||||
With this patch,
|
||||
|
||||
root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_BANDWIDTH.TOTAL -a -- sleep 1
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
1842108 unc_m_pmm_rpq_inserts # 337.2 MB/sec UNC_M_PMM_BANDWIDTH.TOTAL
|
||||
3682209 unc_m_pmm_wpq_inserts
|
||||
|
||||
1.001819706 seconds time elapsed
|
||||
|
||||
root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_READ_LATENCY -a -- sleep 1
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
861970685 unc_m_pmm_rpq_occupancy.all # 219.4 ns UNC_M_PMM_READ_LATENCY
|
||||
1842772 unc_m_pmm_rpq_inserts
|
||||
12790196356 unc_m_clockticks
|
||||
|
||||
1.001749103 seconds time elapsed
|
||||
|
||||
Now we can see the correct metrics 'UNC_M_PMM_BANDWIDTH.TOTAL' and
|
||||
'UNC_M_PMM_READ_LATENCY'.
|
||||
|
||||
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lore.kernel.org/lkml/20190828055932.8269-5-yao.jin@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
---
|
||||
tools/perf/util/evsel.h | 1 +
|
||||
tools/perf/util/metricgroup.c | 90 ++++++++++++++++++-----------------
|
||||
tools/perf/util/stat-shadow.c | 27 +++++++++--
|
||||
3 files changed, 71 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
|
||||
index dab3930e2a8c..be63c73ca69c 100644
|
||||
--- a/tools/perf/util/evsel.h
|
||||
+++ b/tools/perf/util/evsel.h
|
||||
@@ -149,6 +149,7 @@ struct perf_evsel {
|
||||
const char * metric_expr;
|
||||
const char * metric_name;
|
||||
struct perf_evsel **metric_events;
|
||||
+ struct perf_evsel *metric_leader;
|
||||
bool collect_stat;
|
||||
bool weak_group;
|
||||
const char *pmu_name;
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index d01f16448bab..375866dab75b 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -96,57 +96,61 @@ struct egroup {
|
||||
const char *metric_unit;
|
||||
};
|
||||
|
||||
-static bool record_evsel(int *ind, struct perf_evsel **start,
|
||||
- int idnum,
|
||||
- struct perf_evsel **metric_events,
|
||||
- struct perf_evsel *ev)
|
||||
-{
|
||||
- metric_events[*ind] = ev;
|
||||
- if (*ind == 0)
|
||||
- *start = ev;
|
||||
- if (++*ind == idnum) {
|
||||
- metric_events[*ind] = NULL;
|
||||
- return true;
|
||||
- }
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
- const char **ids,
|
||||
- int idnum,
|
||||
- struct perf_evsel **metric_events)
|
||||
+ const char **ids,
|
||||
+ int idnum,
|
||||
+ struct perf_evsel **metric_events)
|
||||
{
|
||||
- struct perf_evsel *ev, *start = NULL;
|
||||
- int ind = 0;
|
||||
+ struct perf_evsel *ev;
|
||||
+ int i = 0;
|
||||
+ bool leader_found;
|
||||
|
||||
evlist__for_each_entry (perf_evlist, ev) {
|
||||
- if (ev->collect_stat)
|
||||
- continue;
|
||||
- if (!strcmp(ev->name, ids[ind])) {
|
||||
- if (record_evsel(&ind, &start, idnum,
|
||||
- metric_events, ev))
|
||||
- return start;
|
||||
+ if (!strcmp(ev->name, ids[i])) {
|
||||
+ if (!metric_events[i])
|
||||
+ metric_events[i] = ev;
|
||||
} else {
|
||||
- /*
|
||||
- * We saw some other event that is not
|
||||
- * in our list of events. Discard
|
||||
- * the whole match and start again.
|
||||
- */
|
||||
- ind = 0;
|
||||
- start = NULL;
|
||||
- if (!strcmp(ev->name, ids[ind])) {
|
||||
- if (record_evsel(&ind, &start, idnum,
|
||||
- metric_events, ev))
|
||||
- return start;
|
||||
+ if (++i == idnum) {
|
||||
+ /* Discard the whole match and start again */
|
||||
+ i = 0;
|
||||
+ memset(metric_events, 0,
|
||||
+ sizeof(struct evsel *) * idnum);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!strcmp(ev->name, ids[i]))
|
||||
+ metric_events[i] = ev;
|
||||
+ else {
|
||||
+ /* Discard the whole match and start again */
|
||||
+ i = 0;
|
||||
+ memset(metric_events, 0,
|
||||
+ sizeof(struct evsel *) * idnum);
|
||||
+ continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
- /*
|
||||
- * This can happen when an alias expands to multiple
|
||||
- * events, like for uncore events.
|
||||
- * We don't support this case for now.
|
||||
- */
|
||||
- return NULL;
|
||||
+
|
||||
+ if (i != idnum - 1) {
|
||||
+ /* Not whole match */
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ metric_events[idnum] = NULL;
|
||||
+
|
||||
+ for (i = 0; i < idnum; i++) {
|
||||
+ leader_found = false;
|
||||
+ evlist__for_each_entry(perf_evlist, ev) {
|
||||
+ if (!leader_found && (ev == metric_events[i]))
|
||||
+ leader_found = true;
|
||||
+
|
||||
+ if (leader_found &&
|
||||
+ !strcmp(ev->name, metric_events[i]->name)) {
|
||||
+ ev->metric_leader = metric_events[i];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return metric_events[0];
|
||||
}
|
||||
|
||||
static int metricgroup__setup_events(struct list_head *groups,
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index f687ca257e5d..a274f04cbeee 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -29,6 +29,8 @@ struct saved_value {
|
||||
int cpu;
|
||||
struct runtime_stat *stat;
|
||||
struct stats stats;
|
||||
+ u64 metric_total;
|
||||
+ int metric_other;
|
||||
};
|
||||
|
||||
static int saved_value_cmp(struct rb_node *rb_node, const void *entry)
|
||||
@@ -210,6 +212,7 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count,
|
||||
{
|
||||
int ctx = evsel_context(counter);
|
||||
u64 count_ns = count;
|
||||
+ struct saved_value *v;
|
||||
|
||||
count *= counter->scale;
|
||||
|
||||
@@ -264,9 +267,15 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count,
|
||||
update_runtime_stat(st, STAT_APERF, ctx, cpu, count);
|
||||
|
||||
if (counter->collect_stat) {
|
||||
- struct saved_value *v = saved_value_lookup(counter, cpu, true,
|
||||
- STAT_NONE, 0, st);
|
||||
+ v = saved_value_lookup(counter, cpu, true, STAT_NONE, 0, st);
|
||||
update_stats(&v->stats, count);
|
||||
+ if (counter->metric_leader)
|
||||
+ v->metric_total += count;
|
||||
+ } else if (counter->metric_leader) {
|
||||
+ v = saved_value_lookup(counter->metric_leader,
|
||||
+ cpu, true, STAT_NONE, 0, st);
|
||||
+ v->metric_total += count;
|
||||
+ v->metric_other++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,10 +736,10 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
char *n, *pn;
|
||||
|
||||
expr__ctx_init(&pctx);
|
||||
- expr__add_id(&pctx, name, avg);
|
||||
for (i = 0; metric_events[i]; i++) {
|
||||
struct saved_value *v;
|
||||
struct stats *stats;
|
||||
+ u64 metric_total = 0;
|
||||
|
||||
if (!strcmp(metric_events[i]->name, "duration_time")) {
|
||||
stats = &walltime_nsecs_stats;
|
||||
@@ -742,6 +751,9 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
break;
|
||||
stats = &v->stats;
|
||||
scale = 1.0;
|
||||
+
|
||||
+ if (v->metric_other)
|
||||
+ metric_total = v->metric_total;
|
||||
}
|
||||
|
||||
n = strdup(metric_events[i]->name);
|
||||
@@ -755,8 +767,15 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
pn = strchr(n, ' ');
|
||||
if (pn)
|
||||
*pn = 0;
|
||||
- expr__add_id(&pctx, n, avg_stats(stats)*scale);
|
||||
+
|
||||
+ if (metric_total)
|
||||
+ expr__add_id(&pctx, n, metric_total);
|
||||
+ else
|
||||
+ expr__add_id(&pctx, n, avg_stats(stats)*scale);
|
||||
}
|
||||
+
|
||||
+ expr__add_id(&pctx, name, avg);
|
||||
+
|
||||
if (!metric_events[i]) {
|
||||
const char *p = metric_expr;
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
From 837ab95c606351cf258959cd33f9b2a7d3c0b5f9 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Fri, 28 Jun 2019 22:35:49 +0800
|
||||
Subject: [PATCH 024/201] perf pmu: Support more complex PMU event aliasing
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 730670b1d108c4a8aa1924762738ca38593ee44c
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=730670b1d108c4a8aa1924762738ca38593ee44c
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The jevent "Unit" field is used for uncore PMU alias definition.
|
||||
|
||||
The form uncore_pmu_example_X is supported, where "X" is a wildcard, to
|
||||
support multiple instances of the same PMU in a system.
|
||||
|
||||
Unfortunately this format not suitable for all uncore PMUs; take the
|
||||
Hisi DDRC uncore PMU for example, where the name is in the form
|
||||
hisi_scclX_ddrcY.
|
||||
|
||||
For for current jevent parsing, we would be required to hardcode an
|
||||
uncore alias translation for each possible value of X. This is not
|
||||
scalable.
|
||||
|
||||
Instead, add support for "Unit" field in the form "hisi_sccl,ddrc",
|
||||
where we can match by hisi_scclX and ddrcY. Tokens in Unit field are
|
||||
delimited by ','.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ben Hutchings <ben@decadent.org.uk>
|
||||
Cc: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Cc: Will Deacon <will.deacon@arm.com>
|
||||
Cc: linux-arm-kernel@lists.infradead.org
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lkml.kernel.org/r/1561732552-143038-2-git-send-email-john.garry@huawei.com
|
||||
[ Shut up older gcc complianing about the last arg to strtok_r() being uninitialized, set that tmp to NULL ]
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/pmu.c | 46 ++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 41 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
|
||||
index 256a9792bd7e..147989e2bff0 100644
|
||||
--- a/tools/perf/util/pmu.c
|
||||
+++ b/tools/perf/util/pmu.c
|
||||
@@ -741,6 +741,46 @@ struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
|
||||
return map;
|
||||
}
|
||||
|
||||
+static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
|
||||
+{
|
||||
+ char *tmp = NULL, *tok, *str;
|
||||
+ bool res;
|
||||
+
|
||||
+ str = strdup(pmu_name);
|
||||
+ if (!str)
|
||||
+ return false;
|
||||
+
|
||||
+ /*
|
||||
+ * uncore alias may be from different PMU with common prefix
|
||||
+ */
|
||||
+ tok = strtok_r(str, ",", &tmp);
|
||||
+ if (strncmp(pmu_name, tok, strlen(tok))) {
|
||||
+ res = false;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Match more complex aliases where the alias name is a comma-delimited
|
||||
+ * list of tokens, orderly contained in the matching PMU name.
|
||||
+ *
|
||||
+ * Example: For alias "socket,pmuname" and PMU "socketX_pmunameY", we
|
||||
+ * match "socket" in "socketX_pmunameY" and then "pmuname" in
|
||||
+ * "pmunameY".
|
||||
+ */
|
||||
+ for (; tok; name += strlen(tok), tok = strtok_r(NULL, ",", &tmp)) {
|
||||
+ name = strstr(name, tok);
|
||||
+ if (!name) {
|
||||
+ res = false;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ res = true;
|
||||
+out:
|
||||
+ free(str);
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* From the pmu_events_map, find the table of PMU events that corresponds
|
||||
* to the current running CPU. Then, add all PMU events from that table
|
||||
@@ -771,12 +811,8 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
|
||||
break;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * uncore alias may be from different PMU
|
||||
- * with common prefix
|
||||
- */
|
||||
if (pmu_is_uncore(name) &&
|
||||
- !strncmp(pname, name, strlen(pname)))
|
||||
+ pmu_uncore_alias_match(pname, name))
|
||||
goto new_alias;
|
||||
|
||||
if (strcmp(pname, name))
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,153 @@
|
||||
From 23613a50c4e84e51444051ba608de3cc45cc3ad9 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Fri, 28 Jun 2019 22:35:50 +0800
|
||||
Subject: [PATCH 025/201] perf jevents: Add support for Hisi hip08 DDRC PMU
|
||||
aliasing
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 57cc732479bac2a3cbd759fb07188657c871d5c1
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=57cc732479bac2a3cbd759fb07188657c871d5c1
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Add support for Hisi hip08 DDRC PMU aliasing. We can now do something like
|
||||
this:
|
||||
|
||||
$perf list
|
||||
|
||||
[snip]
|
||||
|
||||
uncore ddrc:
|
||||
uncore_hisi_ddrc.act_cmd
|
||||
[DDRC active commands. Unit: hisi_sccl,ddrc]
|
||||
uncore_hisi_ddrc.flux_rcmd
|
||||
[DDRC read commands. Unit: hisi_sccl,ddrc]
|
||||
uncore_hisi_ddrc.flux_wcmd
|
||||
[DDRC write commands. Unit: hisi_sccl,ddrc]
|
||||
uncore_hisi_ddrc.flux_wr
|
||||
[DDRC precharge commands. Unit: hisi_sccl,ddrc]
|
||||
uncore_hisi_ddrc.rnk_chg
|
||||
[DDRC rank commands. Unit: hisi_sccl,ddrc]
|
||||
uncore_hisi_ddrc.rw_chg
|
||||
[DDRC read and write changes. Unit: hisi_sccl,ddrc]
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl1_ddrc0]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl3_ddrc1]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl5_ddrc2]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl7_ddrc3]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl5_ddrc0]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl7_ddrc1]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl1_ddrc3]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl1_ddrc1]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl3_ddrc2]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl5_ddrc3]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl3_ddrc0]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl5_ddrc1]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl7_ddrc2]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl7_ddrc0]
|
||||
20,421 uncore_hisi_ddrc.flux_rcmd [hisi_sccl1_ddrc2]
|
||||
0 uncore_hisi_ddrc.flux_rcmd [hisi_sccl3_ddrc3]
|
||||
|
||||
1.001559011 seconds time elapsed
|
||||
|
||||
The kernel driver is in drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ben Hutchings <ben@decadent.org.uk>
|
||||
Cc: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Cc: Will Deacon <will.deacon@arm.com>
|
||||
Cc: linux-arm-kernel@lists.infradead.org
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lkml.kernel.org/r/1561732552-143038-3-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/pmu-events/jevents.c
|
||||
---
|
||||
.../arm64/hisilicon/hip08/uncore-ddrc.json | 44 +++++++++++++++++++
|
||||
tools/perf/pmu-events/jevents.c | 1 +
|
||||
2 files changed, 45 insertions(+)
|
||||
create mode 100644 tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
new file mode 100644
|
||||
index 000000000000..0d1556fcdffe
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
@@ -0,0 +1,44 @@
|
||||
+[
|
||||
+ {
|
||||
+ "EventCode": "0x02",
|
||||
+ "EventName": "uncore_hisi_ddrc.flux_wcmd",
|
||||
+ "BriefDescription": "DDRC write commands",
|
||||
+ "PublicDescription": "DDRC write commands",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x03",
|
||||
+ "EventName": "uncore_hisi_ddrc.flux_rcmd",
|
||||
+ "BriefDescription": "DDRC read commands",
|
||||
+ "PublicDescription": "DDRC read commands",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x04",
|
||||
+ "EventName": "uncore_hisi_ddrc.flux_wr",
|
||||
+ "BriefDescription": "DDRC precharge commands",
|
||||
+ "PublicDescription": "DDRC precharge commands",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x05",
|
||||
+ "EventName": "uncore_hisi_ddrc.act_cmd",
|
||||
+ "BriefDescription": "DDRC active commands",
|
||||
+ "PublicDescription": "DDRC active commands",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x06",
|
||||
+ "EventName": "uncore_hisi_ddrc.rnk_chg",
|
||||
+ "BriefDescription": "DDRC rank commands",
|
||||
+ "PublicDescription": "DDRC rank commands",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x07",
|
||||
+ "EventName": "uncore_hisi_ddrc.rw_chg",
|
||||
+ "BriefDescription": "DDRC read and write changes",
|
||||
+ "PublicDescription": "DDRC read and write changes",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+]
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index 55c8bf2b0b32..e3c8b4b34cb0 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -238,6 +238,7 @@ static struct map {
|
||||
{ "UPI LL", "uncore_upi" },
|
||||
{ "L3PMC", "amd_l3" },
|
||||
{ "DFPMC", "amd_df" },
|
||||
+ { "hisi_sccl,ddrc", "hisi_sccl,ddrc" },
|
||||
{}
|
||||
};
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,117 @@
|
||||
From 0c6076da3c1b6c6bde349c706f196dea620cd0e5 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Fri, 28 Jun 2019 22:35:51 +0800
|
||||
Subject: [PATCH 026/201] perf jevents: Add support for Hisi hip08 HHA PMU
|
||||
aliasing
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 8f5b703add99473b59b4a38a6b66afbafc29d92e
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8f5b703add99473b59b4a38a6b66afbafc29d92e
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Add support for Hisi hip08 HHA PMU aliasing.
|
||||
|
||||
The kernel driver is in drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ben Hutchings <ben@decadent.org.uk>
|
||||
Cc: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Cc: Will Deacon <will.deacon@arm.com>
|
||||
Cc: linux-arm-kernel@lists.infradead.org
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lkml.kernel.org/r/1561732552-143038-4-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../arm64/hisilicon/hip08/uncore-hha.json | 51 +++++++++++++++++++
|
||||
tools/perf/pmu-events/jevents.c | 1 +
|
||||
2 files changed, 52 insertions(+)
|
||||
create mode 100644 tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json
|
||||
new file mode 100644
|
||||
index 000000000000..447d3064de90
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json
|
||||
@@ -0,0 +1,51 @@
|
||||
+[
|
||||
+ {
|
||||
+ "EventCode": "0x00",
|
||||
+ "EventName": "uncore_hisi_hha.rx_ops_num",
|
||||
+ "BriefDescription": "The number of all operations received by the HHA",
|
||||
+ "PublicDescription": "The number of all operations received by the HHA",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x01",
|
||||
+ "EventName": "uncore_hisi_hha.rx_outer",
|
||||
+ "BriefDescription": "The number of all operations received by the HHA from another socket",
|
||||
+ "PublicDescription": "The number of all operations received by the HHA from another socket",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x02",
|
||||
+ "EventName": "uncore_hisi_hha.rx_sccl",
|
||||
+ "BriefDescription": "The number of all operations received by the HHA from another SCCL in this socket",
|
||||
+ "PublicDescription": "The number of all operations received by the HHA from another SCCL in this socket",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x1c",
|
||||
+ "EventName": "uncore_hisi_hha.rd_ddr_64b",
|
||||
+ "BriefDescription": "The number of read operations sent by HHA to DDRC which size is 64 bytes",
|
||||
+ "PublicDescription": "The number of read operations sent by HHA to DDRC which size is 64bytes",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x1d",
|
||||
+ "EventName": "uncore_hisi_hha.wr_dr_64b",
|
||||
+ "BriefDescription": "The number of write operations sent by HHA to DDRC which size is 64 bytes",
|
||||
+ "PublicDescription": "The number of write operations sent by HHA to DDRC which size is 64 bytes",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x1e",
|
||||
+ "EventName": "uncore_hisi_hha.rd_ddr_128b",
|
||||
+ "BriefDescription": "The number of read operations sent by HHA to DDRC which size is 128 bytes",
|
||||
+ "PublicDescription": "The number of read operations sent by HHA to DDRC which size is 128 bytes",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x1f",
|
||||
+ "EventName": "uncore_hisi_hha.wr_ddr_128b",
|
||||
+ "BriefDescription": "The number of write operations sent by HHA to DDRC which size is 128 bytes",
|
||||
+ "PublicDescription": "The number of write operations sent by HHA to DDRC which size is 128 bytes",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+]
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index e3c8b4b34cb0..24223bac1993 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -239,6 +239,7 @@ static struct map {
|
||||
{ "L3PMC", "amd_l3" },
|
||||
{ "DFPMC", "amd_df" },
|
||||
{ "hisi_sccl,ddrc", "hisi_sccl,ddrc" },
|
||||
+ { "hisi_sccl,hha", "hisi_sccl,hha" },
|
||||
{}
|
||||
};
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
From 5b4c2a0be90df3842095d9ed3bbd5d0bfef4ef30 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Fri, 28 Jun 2019 22:35:52 +0800
|
||||
Subject: [PATCH 027/201] perf jevents: Add support for Hisi hip08 L3C PMU
|
||||
aliasing
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit edd93a4076cf18ede423c167de6d6fb8e4211e7b
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=edd93a4076cf18ede423c167de6d6fb8e4211e7b
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Add support for Hisi hip08 L3C PMU aliasing.
|
||||
|
||||
The kernel driver is in drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ben Hutchings <ben@decadent.org.uk>
|
||||
Cc: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Cc: Will Deacon <will.deacon@arm.com>
|
||||
Cc: linux-arm-kernel@lists.infradead.org
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lkml.kernel.org/r/1561732552-143038-5-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../arm64/hisilicon/hip08/uncore-l3c.json | 37 +++++++++++++++++++
|
||||
tools/perf/pmu-events/jevents.c | 1 +
|
||||
2 files changed, 38 insertions(+)
|
||||
create mode 100644 tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json
|
||||
new file mode 100644
|
||||
index 000000000000..ca48747642e1
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json
|
||||
@@ -0,0 +1,37 @@
|
||||
+[
|
||||
+ {
|
||||
+ "EventCode": "0x00",
|
||||
+ "EventName": "uncore_hisi_l3c.rd_cpipe",
|
||||
+ "BriefDescription": "Total read accesses",
|
||||
+ "PublicDescription": "Total read accesses",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x01",
|
||||
+ "EventName": "uncore_hisi_l3c.wr_cpipe",
|
||||
+ "BriefDescription": "Total write accesses",
|
||||
+ "PublicDescription": "Total write accesses",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x02",
|
||||
+ "EventName": "uncore_hisi_l3c.rd_hit_cpipe",
|
||||
+ "BriefDescription": "Total read hits",
|
||||
+ "PublicDescription": "Total read hits",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x03",
|
||||
+ "EventName": "uncore_hisi_l3c.wr_hit_cpipe",
|
||||
+ "BriefDescription": "Total write hits",
|
||||
+ "PublicDescription": "Total write hits",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x04",
|
||||
+ "EventName": "uncore_hisi_l3c.victim_num",
|
||||
+ "BriefDescription": "l3c precharge commands",
|
||||
+ "PublicDescription": "l3c precharge commands",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+]
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index 24223bac1993..b6960ef3a553 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -240,6 +240,7 @@ static struct map {
|
||||
{ "DFPMC", "amd_df" },
|
||||
{ "hisi_sccl,ddrc", "hisi_sccl,ddrc" },
|
||||
{ "hisi_sccl,hha", "hisi_sccl,hha" },
|
||||
+ { "hisi_sccl,l3c", "hisi_sccl,l3c" },
|
||||
{}
|
||||
};
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
From d1a1248e70094869a82c8f3b43e80718e4d211eb Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Wed, 4 Sep 2019 23:54:41 +0800
|
||||
Subject: [PATCH 028/201] perf vendor events arm64: Fix Hisi hip08 DDRC PMU
|
||||
eventname
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc1
|
||||
commit 84b0975f4853ba32d2d9b3c19ffa2b947f023fb3
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=84b0975f4853ba32d2d9b3c19ffa2b947f023fb3
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The "EventName" for the DDRC precharge command event is incorrect, so
|
||||
fix it.
|
||||
|
||||
Fixes: 57cc732479ba ("perf jevents: Add support for Hisi hip08 DDRC PMU aliasing")
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1567612484-195727-2-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
index 0d1556fcdffe..99f4fc425564 100644
|
||||
--- a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
{
|
||||
"EventCode": "0x04",
|
||||
- "EventName": "uncore_hisi_ddrc.flux_wr",
|
||||
+ "EventName": "uncore_hisi_ddrc.pre_cmd",
|
||||
"BriefDescription": "DDRC precharge commands",
|
||||
"PublicDescription": "DDRC precharge commands",
|
||||
"Unit": "hisi_sccl,ddrc",
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From 2ba983a40018104ce95c97db4ab9fcb7ff91f974 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Wed, 4 Sep 2019 23:54:42 +0800
|
||||
Subject: [PATCH 029/201] perf vendor events arm64: Add some missing events for
|
||||
Hisi hip08 DDRC PMU
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc1
|
||||
commit 1410732a1b642ba82730a95bdf7f4dafbac1891a
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1410732a1b642ba82730a95bdf7f4dafbac1891a
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Add some more missing events.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1567612484-195727-3-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../arch/arm64/hisilicon/hip08/uncore-ddrc.json | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
index 99f4fc425564..7da86942dae2 100644
|
||||
--- a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-ddrc.json
|
||||
@@ -1,4 +1,18 @@
|
||||
[
|
||||
+ {
|
||||
+ "EventCode": "0x00",
|
||||
+ "EventName": "uncore_hisi_ddrc.flux_wr",
|
||||
+ "BriefDescription": "DDRC total write operations",
|
||||
+ "PublicDescription": "DDRC total write operations",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x01",
|
||||
+ "EventName": "uncore_hisi_ddrc.flux_rd",
|
||||
+ "BriefDescription": "DDRC total read operations",
|
||||
+ "PublicDescription": "DDRC total read operations",
|
||||
+ "Unit": "hisi_sccl,ddrc",
|
||||
+ },
|
||||
{
|
||||
"EventCode": "0x02",
|
||||
"EventName": "uncore_hisi_ddrc.flux_wcmd",
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
From 512e47929f31707b18b9345c7dd172e48eb451a0 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Wed, 4 Sep 2019 23:54:43 +0800
|
||||
Subject: [PATCH 030/201] perf vendor events arm64: Add some missing events for
|
||||
Hisi hip08 L3C PMU
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc1
|
||||
commit e3ae569541802a6c9e89ab1f0f3ff613a5a1237b
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e3ae569541802a6c9e89ab1f0f3ff613a5a1237b
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Add some more missing events.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1567612484-195727-4-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../arm64/hisilicon/hip08/uncore-l3c.json | 56 +++++++++++++++++++
|
||||
1 file changed, 56 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json
|
||||
index ca48747642e1..f463d0acfaef 100644
|
||||
--- a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json
|
||||
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-l3c.json
|
||||
@@ -34,4 +34,60 @@
|
||||
"PublicDescription": "l3c precharge commands",
|
||||
"Unit": "hisi_sccl,l3c",
|
||||
},
|
||||
+ {
|
||||
+ "EventCode": "0x20",
|
||||
+ "EventName": "uncore_hisi_l3c.rd_spipe",
|
||||
+ "BriefDescription": "Count of the number of read lines that come from this cluster of CPU core in spipe",
|
||||
+ "PublicDescription": "Count of the number of read lines that come from this cluster of CPU core in spipe",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x21",
|
||||
+ "EventName": "uncore_hisi_l3c.wr_spipe",
|
||||
+ "BriefDescription": "Count of the number of write lines that come from this cluster of CPU core in spipe",
|
||||
+ "PublicDescription": "Count of the number of write lines that come from this cluster of CPU core in spipe",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x22",
|
||||
+ "EventName": "uncore_hisi_l3c.rd_hit_spipe",
|
||||
+ "BriefDescription": "Count of the number of read lines that hits in spipe of this L3C",
|
||||
+ "PublicDescription": "Count of the number of read lines that hits in spipe of this L3C",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x23",
|
||||
+ "EventName": "uncore_hisi_l3c.wr_hit_spipe",
|
||||
+ "BriefDescription": "Count of the number of write lines that hits in spipe of this L3C",
|
||||
+ "PublicDescription": "Count of the number of write lines that hits in spipe of this L3C",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x29",
|
||||
+ "EventName": "uncore_hisi_l3c.back_invalid",
|
||||
+ "BriefDescription": "Count of the number of L3C back invalid operations",
|
||||
+ "PublicDescription": "Count of the number of L3C back invalid operations",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x40",
|
||||
+ "EventName": "uncore_hisi_l3c.retry_cpu",
|
||||
+ "BriefDescription": "Count of the number of retry that L3C suppresses the CPU operations",
|
||||
+ "PublicDescription": "Count of the number of retry that L3C suppresses the CPU operations",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x41",
|
||||
+ "EventName": "uncore_hisi_l3c.retry_ring",
|
||||
+ "BriefDescription": "Count of the number of retry that L3C suppresses the ring operations",
|
||||
+ "PublicDescription": "Count of the number of retry that L3C suppresses the ring operations",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x42",
|
||||
+ "EventName": "uncore_hisi_l3c.prefetch_drop",
|
||||
+ "BriefDescription": "Count of the number of prefetch drops from this L3C",
|
||||
+ "PublicDescription": "Count of the number of prefetch drops from this L3C",
|
||||
+ "Unit": "hisi_sccl,l3c",
|
||||
+ },
|
||||
]
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
From 394d1db77007ebac4a69b73c690901ebf4dc733a Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Wed, 4 Sep 2019 23:54:44 +0800
|
||||
Subject: [PATCH 031/201] perf vendor events arm64: Add some missing events for
|
||||
Hisi hip08 HHA PMU
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc1
|
||||
commit 2b7847158120136c4b23684c768a82d571ee59bf
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2b7847158120136c4b23684c768a82d571ee59bf
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Add some more missing events.
|
||||
|
||||
A trivial typo is also fixed.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1567612484-195727-5-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../arm64/hisilicon/hip08/uncore-hha.json | 23 ++++++++++++++++++-
|
||||
1 file changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json
|
||||
index 447d3064de90..3be418a248ea 100644
|
||||
--- a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json
|
||||
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/uncore-hha.json
|
||||
@@ -20,6 +20,13 @@
|
||||
"PublicDescription": "The number of all operations received by the HHA from another SCCL in this socket",
|
||||
"Unit": "hisi_sccl,hha",
|
||||
},
|
||||
+ {
|
||||
+ "EventCode": "0x03",
|
||||
+ "EventName": "uncore_hisi_hha.rx_ccix",
|
||||
+ "BriefDescription": "Count of the number of operations that HHA has received from CCIX",
|
||||
+ "PublicDescription": "Count of the number of operations that HHA has received from CCIX",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
{
|
||||
"EventCode": "0x1c",
|
||||
"EventName": "uncore_hisi_hha.rd_ddr_64b",
|
||||
@@ -29,7 +36,7 @@
|
||||
},
|
||||
{
|
||||
"EventCode": "0x1d",
|
||||
- "EventName": "uncore_hisi_hha.wr_dr_64b",
|
||||
+ "EventName": "uncore_hisi_hha.wr_ddr_64b",
|
||||
"BriefDescription": "The number of write operations sent by HHA to DDRC which size is 64 bytes",
|
||||
"PublicDescription": "The number of write operations sent by HHA to DDRC which size is 64 bytes",
|
||||
"Unit": "hisi_sccl,hha",
|
||||
@@ -48,4 +55,18 @@
|
||||
"PublicDescription": "The number of write operations sent by HHA to DDRC which size is 128 bytes",
|
||||
"Unit": "hisi_sccl,hha",
|
||||
},
|
||||
+ {
|
||||
+ "EventCode": "0x20",
|
||||
+ "EventName": "uncore_hisi_hha.spill_num",
|
||||
+ "BriefDescription": "Count of the number of spill operations that the HHA has sent",
|
||||
+ "PublicDescription": "Count of the number of spill operations that the HHA has sent",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x21",
|
||||
+ "EventName": "uncore_hisi_hha.spill_success",
|
||||
+ "BriefDescription": "Count of the number of successful spill operations that the HHA has sent",
|
||||
+ "PublicDescription": "Count of the number of successful spill operations that the HHA has sent",
|
||||
+ "Unit": "hisi_sccl,hha",
|
||||
+ },
|
||||
]
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
From 1ce326c8887a25381760da2070d9bfd1934bd068 Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Mon, 23 Sep 2019 16:33:39 -0700
|
||||
Subject: [PATCH 032/201] perf stat: Fix free memory access / memory leaks in
|
||||
metrics
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.4-rc1
|
||||
commit 6f6473c37d34b00676a152ec7e60770c78ed7c2f
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6f6473c37d34b00676a152ec7e60770c78ed7c2f
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Make sure to not free the name passed in by the caller, but free all the
|
||||
allocated ids when parsing expressions.
|
||||
|
||||
The loop at the end knows that the first entry shouldn't be freed, so
|
||||
make sure the caller name is the first entry.
|
||||
|
||||
Fixes
|
||||
|
||||
% perf stat -M IpB,IpCall,IpTB,IPC,Retiring_SMT,Frontend_Bound_SMT,Kernel_Utilization,CPU_Utilization --metric-only -a -I 1000 sleep 2
|
||||
|
||||
valgrind:
|
||||
1.009943231 ==21527== Invalid read of size 1
|
||||
==21527== at 0x483CB74: strcmp (vg_replace_strmem.c:849)
|
||||
==21527== by 0x582CF8: collect_all_aliases (stat-display.c:554)
|
||||
==21527== by 0x582EB3: collect_data (stat-display.c:577)
|
||||
==21527== by 0x583A32: print_counter_aggr (stat-display.c:806)
|
||||
==21527== by 0x584FAD: perf_evlist__print_counters (stat-display.c:1200)
|
||||
==21527== by 0x45133A: print_counters (builtin-stat.c:655)
|
||||
==21527== by 0x450629: process_interval (builtin-stat.c:353)
|
||||
==21527== by 0x450FBD: __run_perf_stat (builtin-stat.c:564)
|
||||
==21527== by 0x451285: run_perf_stat (builtin-stat.c:636)
|
||||
==21527== by 0x454619: cmd_stat (builtin-stat.c:1966)
|
||||
==21527== by 0x4D557D: run_builtin (perf.c:310)
|
||||
==21527== by 0x4D57EA: handle_internal_command (perf.c:362)
|
||||
==21527== Address 0x12826cd0 is 0 bytes inside a block of size 25 free'd
|
||||
==21527== at 0x4839A0C: free (vg_replace_malloc.c:540)
|
||||
==21527== by 0x627041: __zfree (zalloc.c:13)
|
||||
==21527== by 0x57F66A: generic_metric (stat-shadow.c:814)
|
||||
==21527== by 0x580B21: perf_stat__print_shadow_stats (stat-shadow.c:1057)
|
||||
==21527== by 0x58418E: print_metric_headers (stat-display.c:943)
|
||||
==21527== by 0x5844BC: print_interval (stat-display.c:1004)
|
||||
==21527== by 0x584DEB: perf_evlist__print_counters (stat-display.c:1172)
|
||||
==21527== by 0x45133A: print_counters (builtin-stat.c:655)
|
||||
==21527== by 0x450629: process_interval (builtin-stat.c:353)
|
||||
==21527== by 0x450FBD: __run_perf_stat (builtin-stat.c:564)
|
||||
==21527== by 0x451285: run_perf_stat (builtin-stat.c:636)
|
||||
==21527== by 0x454619: cmd_stat (builtin-stat.c:1966)
|
||||
==21527== Block was alloc'd at
|
||||
==21527== at 0x483880B: malloc (vg_replace_malloc.c:309)
|
||||
==21527== by 0x51677DE: strdup (in /usr/lib64/libc-2.29.so)
|
||||
==21527== by 0x506457: parse_events_name (parse-events.c:1754)
|
||||
==21527== by 0x5550BB: parse_events_parse (parse-events.y:214)
|
||||
==21527== by 0x50694D: parse_events__scanner (parse-events.c:1887)
|
||||
==21527== by 0x506AEF: parse_events (parse-events.c:1927)
|
||||
==21527== by 0x521D8B: metricgroup__parse_groups (metricgroup.c:527)
|
||||
==21527== by 0x45156F: parse_metric_groups (builtin-stat.c:721)
|
||||
==21527== by 0x6228A9: get_value (parse-options.c:243)
|
||||
==21527== by 0x62363F: parse_short_opt (parse-options.c:348)
|
||||
==21527== by 0x62363F: parse_options_step (parse-options.c:536)
|
||||
==21527== by 0x62363F: parse_options_subcommand (parse-options.c:651)
|
||||
==21527== by 0x453C1D: cmd_stat (builtin-stat.c:1718)
|
||||
==21527== by 0x4D557D: run_builtin (perf.c:310)
|
||||
|
||||
and also a leak report.
|
||||
|
||||
Committer testing:
|
||||
|
||||
Before:
|
||||
|
||||
# perf stat -M IpB,IpCall,IpTB,IPC,Retiring_SMT,Frontend_Bound_SMT,Kernel_Utilization,CPU_Utilization --metric-only -a -I 1000 sleep 2
|
||||
# time CPU_Utilization
|
||||
1.000470810 free(): double free detected in tcache 2
|
||||
Aborted (core dumped)
|
||||
#
|
||||
|
||||
After:
|
||||
|
||||
# perf stat -M IpB,IpCall,IpTB,IPC,Retiring_SMT,Frontend_Bound_SMT,Kernel_Utilization,CPU_Utilization --metric-only -a -I 1000 sleep 2
|
||||
# time CPU_Utilization
|
||||
1.000494752 0.1
|
||||
2.001105112 0.1
|
||||
#
|
||||
|
||||
Signed-off-by: Andi Kleen <ak@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Link: http://lore.kernel.org/lkml/20190923233339.25326-3-andi@firstfloor.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/stat-shadow.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index a274f04cbeee..c9d92c1dac0e 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -736,6 +736,8 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
char *n, *pn;
|
||||
|
||||
expr__ctx_init(&pctx);
|
||||
+ /* Must be first id entry */
|
||||
+ expr__add_id(&pctx, name, avg);
|
||||
for (i = 0; metric_events[i]; i++) {
|
||||
struct saved_value *v;
|
||||
struct stats *stats;
|
||||
@@ -774,8 +776,6 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
expr__add_id(&pctx, n, avg_stats(stats)*scale);
|
||||
}
|
||||
|
||||
- expr__add_id(&pctx, name, avg);
|
||||
-
|
||||
if (!metric_events[i]) {
|
||||
const char *p = metric_expr;
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
236
patches/0150-perf-tools-Move-ALLOC_LIST-into-a-function.patch
Normal file
236
patches/0150-perf-tools-Move-ALLOC_LIST-into-a-function.patch
Normal file
@ -0,0 +1,236 @@
|
||||
From 272232b23a91bc246d17a1117162180670de1c92 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Tue, 22 Oct 2019 17:53:32 -0700
|
||||
Subject: [PATCH 033/201] perf tools: Move ALLOC_LIST into a function
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc1
|
||||
commit a26e47162d7670ddea4f67978ecf848dc23ef671
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a26e47162d7670ddea4f67978ecf848dc23ef671
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Having a YYABORT in a macro makes it hard to free memory for components
|
||||
of a rule. Separate the logic out.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Alexei Starovoitov <ast@kernel.org>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Martin KaFai Lau <kafai@fb.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Yonghong Song <yhs@fb.com>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: clang-built-linux@googlegroups.com
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20191023005337.196160-5-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/parse-events.y | 65 ++++++++++++++++++++++------------
|
||||
1 file changed, 43 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
|
||||
index a2c7b6fb1fd5..ef4c83b07c22 100644
|
||||
--- a/tools/perf/util/parse-events.y
|
||||
+++ b/tools/perf/util/parse-events.y
|
||||
@@ -27,12 +27,17 @@ do { \
|
||||
YYABORT; \
|
||||
} while (0)
|
||||
|
||||
-#define ALLOC_LIST(list) \
|
||||
-do { \
|
||||
- list = malloc(sizeof(*list)); \
|
||||
- ABORT_ON(!list); \
|
||||
- INIT_LIST_HEAD(list); \
|
||||
-} while (0)
|
||||
+static struct list_head* alloc_list()
|
||||
+{
|
||||
+ struct list_head *list;
|
||||
+
|
||||
+ list = malloc(sizeof(*list));
|
||||
+ if (!list)
|
||||
+ return NULL;
|
||||
+
|
||||
+ INIT_LIST_HEAD(list);
|
||||
+ return list;
|
||||
+}
|
||||
|
||||
static void inc_group_count(struct list_head *list,
|
||||
struct parse_events_state *parse_state)
|
||||
@@ -240,7 +245,8 @@ PE_NAME opt_pmu_config
|
||||
if (error)
|
||||
error->idx = @1.first_column;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) {
|
||||
struct perf_pmu *pmu = NULL;
|
||||
int ok = 0;
|
||||
@@ -308,7 +314,8 @@ value_sym '/' event_config '/'
|
||||
int type = $1 >> 16;
|
||||
int config = $1 & 255;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3));
|
||||
parse_events_terms__delete($3);
|
||||
$$ = list;
|
||||
@@ -320,7 +327,8 @@ value_sym sep_slash_slash_dc
|
||||
int type = $1 >> 16;
|
||||
int config = $1 & 255;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
|
||||
$$ = list;
|
||||
}
|
||||
@@ -329,7 +337,8 @@ PE_VALUE_SYM_TOOL sep_slash_slash_dc
|
||||
{
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_tool(_parse_state, list, $1));
|
||||
$$ = list;
|
||||
}
|
||||
@@ -341,7 +350,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_e
|
||||
struct parse_events_error *error = parse_state->error;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6));
|
||||
parse_events_terms__delete($6);
|
||||
$$ = list;
|
||||
@@ -353,7 +363,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config
|
||||
struct parse_events_error *error = parse_state->error;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4));
|
||||
parse_events_terms__delete($4);
|
||||
$$ = list;
|
||||
@@ -365,7 +376,8 @@ PE_NAME_CACHE_TYPE opt_event_config
|
||||
struct parse_events_error *error = parse_state->error;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2));
|
||||
parse_events_terms__delete($2);
|
||||
$$ = list;
|
||||
@@ -377,7 +389,8 @@ PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
|
||||
struct parse_events_state *parse_state = _parse_state;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
|
||||
(void *) $2, $6, $4));
|
||||
$$ = list;
|
||||
@@ -388,7 +401,8 @@ PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
|
||||
struct parse_events_state *parse_state = _parse_state;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
|
||||
(void *) $2, NULL, $4));
|
||||
$$ = list;
|
||||
@@ -399,7 +413,8 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
|
||||
struct parse_events_state *parse_state = _parse_state;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
|
||||
(void *) $2, $4, 0));
|
||||
$$ = list;
|
||||
@@ -410,7 +425,8 @@ PE_PREFIX_MEM PE_VALUE sep_dc
|
||||
struct parse_events_state *parse_state = _parse_state;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
|
||||
(void *) $2, NULL, 0));
|
||||
$$ = list;
|
||||
@@ -423,7 +439,8 @@ tracepoint_name opt_event_config
|
||||
struct parse_events_error *error = parse_state->error;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
if (error)
|
||||
error->idx = @1.first_column;
|
||||
|
||||
@@ -459,7 +476,8 @@ PE_VALUE ':' PE_VALUE opt_event_config
|
||||
{
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4));
|
||||
parse_events_terms__delete($4);
|
||||
$$ = list;
|
||||
@@ -470,7 +488,8 @@ PE_RAW opt_event_config
|
||||
{
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2));
|
||||
parse_events_terms__delete($2);
|
||||
$$ = list;
|
||||
@@ -483,7 +502,8 @@ PE_BPF_OBJECT opt_event_config
|
||||
struct parse_events_error *error = parse_state->error;
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2));
|
||||
parse_events_terms__delete($2);
|
||||
$$ = list;
|
||||
@@ -493,7 +513,8 @@ PE_BPF_SOURCE opt_event_config
|
||||
{
|
||||
struct list_head *list;
|
||||
|
||||
- ALLOC_LIST(list);
|
||||
+ list = alloc_list();
|
||||
+ ABORT_ON(!list);
|
||||
ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2));
|
||||
parse_events_terms__delete($2);
|
||||
$$ = list;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
393
patches/0151-perf-list-Hide-deprecated-events-by-default.patch
Normal file
393
patches/0151-perf-list-Hide-deprecated-events-by-default.patch
Normal file
@ -0,0 +1,393 @@
|
||||
From 2670fb710163524ae338f2736fe240abb18e9af8 Mon Sep 17 00:00:00 2001
|
||||
From: Jin Yao <yao.jin@linux.intel.com>
|
||||
Date: Tue, 15 Oct 2019 10:53:57 +0800
|
||||
Subject: [PATCH 034/201] perf list: Hide deprecated events by default
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc1
|
||||
commit a7f6c8c81afdd6d24eb12558f2fb66901207d349
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a7f6c8c81afdd6d24eb12558f2fb66901207d349
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
There are some deprecated events listed by perf list. But we can't
|
||||
remove them from perf list with ease because some old scripts may use
|
||||
them.
|
||||
|
||||
Deprecated events are old names of renamed events. When an event gets
|
||||
renamed the old name is kept around for some time and marked with
|
||||
Deprecated. The newer Intel event lists in the tree already have these
|
||||
headers.
|
||||
|
||||
So we need to keep them in the event list, but provide a new option to
|
||||
show them. The new option is "--deprecated".
|
||||
|
||||
With this patch, the deprecated events are hidden by default but they
|
||||
can be displayed when option "--deprecated" is enabled.
|
||||
|
||||
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@intel.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lore.kernel.org/lkml/20191015025357.8708-1-yao.jin@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/Documentation/perf-list.txt | 3 +++
|
||||
tools/perf/builtin-list.c | 14 ++++++++++----
|
||||
tools/perf/pmu-events/jevents.c | 26 ++++++++++++++++++++------
|
||||
tools/perf/pmu-events/jevents.h | 3 ++-
|
||||
tools/perf/pmu-events/pmu-events.h | 1 +
|
||||
tools/perf/util/parse-events.c | 4 ++--
|
||||
tools/perf/util/parse-events.h | 2 +-
|
||||
tools/perf/util/pmu.c | 17 +++++++++++++----
|
||||
tools/perf/util/pmu.h | 4 +++-
|
||||
9 files changed, 55 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
|
||||
index 236b9b97dfdb..54d16b4d1ede 100644
|
||||
--- a/tools/perf/Documentation/perf-list.txt
|
||||
+++ b/tools/perf/Documentation/perf-list.txt
|
||||
@@ -36,6 +36,9 @@ Enable debugging output.
|
||||
Print how named events are resolved internally into perf events, and also
|
||||
any extra expressions computed by perf stat.
|
||||
|
||||
+--deprecated::
|
||||
+Print deprecated events. By default the deprecated events are hidden.
|
||||
+
|
||||
[[EVENT_MODIFIERS]]
|
||||
EVENT MODIFIERS
|
||||
---------------
|
||||
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
|
||||
index e4606919bda9..169f1ece7c68 100644
|
||||
--- a/tools/perf/builtin-list.c
|
||||
+++ b/tools/perf/builtin-list.c
|
||||
@@ -27,6 +27,7 @@ int cmd_list(int argc, const char **argv)
|
||||
int i;
|
||||
bool raw_dump = false;
|
||||
bool long_desc_flag = false;
|
||||
+ bool deprecated = false;
|
||||
struct option list_options[] = {
|
||||
OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"),
|
||||
OPT_BOOLEAN('d', "desc", &desc_flag,
|
||||
@@ -35,6 +36,8 @@ int cmd_list(int argc, const char **argv)
|
||||
"Print longer event descriptions."),
|
||||
OPT_BOOLEAN(0, "details", &details_flag,
|
||||
"Print information on the perf event names and expressions used internally by events."),
|
||||
+ OPT_BOOLEAN(0, "deprecated", &deprecated,
|
||||
+ "Print deprecated events."),
|
||||
OPT_INCR(0, "debug", &verbose,
|
||||
"Enable debugging output"),
|
||||
OPT_END()
|
||||
@@ -56,7 +59,7 @@ int cmd_list(int argc, const char **argv)
|
||||
|
||||
if (argc == 0) {
|
||||
print_events(NULL, raw_dump, !desc_flag, long_desc_flag,
|
||||
- details_flag);
|
||||
+ details_flag, deprecated);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -79,7 +82,8 @@ int cmd_list(int argc, const char **argv)
|
||||
print_hwcache_events(NULL, raw_dump);
|
||||
else if (strcmp(argv[i], "pmu") == 0)
|
||||
print_pmu_events(NULL, raw_dump, !desc_flag,
|
||||
- long_desc_flag, details_flag);
|
||||
+ long_desc_flag, details_flag,
|
||||
+ deprecated);
|
||||
else if (strcmp(argv[i], "sdt") == 0)
|
||||
print_sdt_events(NULL, NULL, raw_dump);
|
||||
else if (strcmp(argv[i], "metric") == 0)
|
||||
@@ -92,7 +96,8 @@ int cmd_list(int argc, const char **argv)
|
||||
if (sep == NULL) {
|
||||
print_events(argv[i], raw_dump, !desc_flag,
|
||||
long_desc_flag,
|
||||
- details_flag);
|
||||
+ details_flag,
|
||||
+ deprecated);
|
||||
continue;
|
||||
}
|
||||
sep_idx = sep - argv[i];
|
||||
@@ -118,7 +123,8 @@ int cmd_list(int argc, const char **argv)
|
||||
print_hwcache_events(s, raw_dump);
|
||||
print_pmu_events(s, raw_dump, !desc_flag,
|
||||
long_desc_flag,
|
||||
- details_flag);
|
||||
+ details_flag,
|
||||
+ deprecated);
|
||||
print_tracepoint_events(NULL, s, raw_dump);
|
||||
print_sdt_events(NULL, s, raw_dump);
|
||||
metricgroup__print(true, true, NULL, raw_dump, details_flag);
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index b6960ef3a553..a1eff577f002 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -323,7 +323,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
|
||||
char *desc, char *long_desc,
|
||||
char *pmu, char *unit, char *perpkg,
|
||||
char *metric_expr,
|
||||
- char *metric_name, char *metric_group)
|
||||
+ char *metric_name, char *metric_group,
|
||||
+ char *deprecated)
|
||||
{
|
||||
struct perf_entry_data *pd = data;
|
||||
FILE *outfp = pd->outfp;
|
||||
@@ -355,6 +356,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
|
||||
fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name);
|
||||
if (metric_group)
|
||||
fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group);
|
||||
+ if (deprecated)
|
||||
+ fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated);
|
||||
fprintf(outfp, "},\n");
|
||||
|
||||
return 0;
|
||||
@@ -372,6 +375,7 @@ struct event_struct {
|
||||
char *metric_expr;
|
||||
char *metric_name;
|
||||
char *metric_group;
|
||||
+ char *deprecated;
|
||||
};
|
||||
|
||||
#define ADD_EVENT_FIELD(field) do { if (field) { \
|
||||
@@ -399,6 +403,7 @@ struct event_struct {
|
||||
op(metric_expr); \
|
||||
op(metric_name); \
|
||||
op(metric_group); \
|
||||
+ op(deprecated); \
|
||||
} while (0)
|
||||
|
||||
static LIST_HEAD(arch_std_events);
|
||||
@@ -417,7 +422,8 @@ static void free_arch_std_events(void)
|
||||
static int save_arch_std_events(void *data, char *name, char *event,
|
||||
char *desc, char *long_desc, char *pmu,
|
||||
char *unit, char *perpkg, char *metric_expr,
|
||||
- char *metric_name, char *metric_group)
|
||||
+ char *metric_name, char *metric_group,
|
||||
+ char *deprecated)
|
||||
{
|
||||
struct event_struct *es;
|
||||
|
||||
@@ -480,7 +486,8 @@ static int
|
||||
try_fixup(const char *fn, char *arch_std, char **event, char **desc,
|
||||
char **name, char **long_desc, char **pmu, char **filter,
|
||||
char **perpkg, char **unit, char **metric_expr, char **metric_name,
|
||||
- char **metric_group, unsigned long long eventcode)
|
||||
+ char **metric_group, unsigned long long eventcode,
|
||||
+ char **deprecated)
|
||||
{
|
||||
/* try to find matching event from arch standard values */
|
||||
struct event_struct *es;
|
||||
@@ -508,7 +515,8 @@ int json_events(const char *fn,
|
||||
char *long_desc,
|
||||
char *pmu, char *unit, char *perpkg,
|
||||
char *metric_expr,
|
||||
- char *metric_name, char *metric_group),
|
||||
+ char *metric_name, char *metric_group,
|
||||
+ char *deprecated),
|
||||
void *data)
|
||||
{
|
||||
int err;
|
||||
@@ -537,6 +545,7 @@ int json_events(const char *fn,
|
||||
char *metric_expr = NULL;
|
||||
char *metric_name = NULL;
|
||||
char *metric_group = NULL;
|
||||
+ char *deprecated = NULL;
|
||||
char *arch_std = NULL;
|
||||
unsigned long long eventcode = 0;
|
||||
struct msrmap *msr = NULL;
|
||||
@@ -615,6 +624,8 @@ 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, "Deprecated")) {
|
||||
+ addfield(map, &deprecated, "", "", val);
|
||||
} else if (json_streq(map, field, "MetricName")) {
|
||||
addfield(map, &metric_name, "", "", val);
|
||||
} else if (json_streq(map, field, "MetricGroup")) {
|
||||
@@ -659,12 +670,14 @@ int json_events(const char *fn,
|
||||
err = try_fixup(fn, arch_std, &event, &desc, &name,
|
||||
&long_desc, &pmu, &filter, &perpkg,
|
||||
&unit, &metric_expr, &metric_name,
|
||||
- &metric_group, eventcode);
|
||||
+ &metric_group, eventcode,
|
||||
+ &deprecated);
|
||||
if (err)
|
||||
goto free_strings;
|
||||
}
|
||||
err = func(data, name, real_event(name, event), desc, long_desc,
|
||||
- pmu, unit, perpkg, metric_expr, metric_name, metric_group);
|
||||
+ pmu, unit, perpkg, metric_expr, metric_name,
|
||||
+ metric_group, deprecated);
|
||||
free_strings:
|
||||
free(event);
|
||||
free(desc);
|
||||
@@ -674,6 +687,7 @@ int json_events(const char *fn,
|
||||
free(pmu);
|
||||
free(filter);
|
||||
free(perpkg);
|
||||
+ free(deprecated);
|
||||
free(unit);
|
||||
free(metric_expr);
|
||||
free(metric_name);
|
||||
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
|
||||
index 4684c673c445..5cda49a42143 100644
|
||||
--- a/tools/perf/pmu-events/jevents.h
|
||||
+++ b/tools/perf/pmu-events/jevents.h
|
||||
@@ -7,7 +7,8 @@ int json_events(const char *fn,
|
||||
char *long_desc,
|
||||
char *pmu,
|
||||
char *unit, char *perpkg, char *metric_expr,
|
||||
- char *metric_name, char *metric_group),
|
||||
+ char *metric_name, char *metric_group,
|
||||
+ char *deprecated),
|
||||
void *data);
|
||||
char *get_cpu_str(void);
|
||||
|
||||
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
|
||||
index 92a4d15ee0b9..caeb577d36c9 100644
|
||||
--- a/tools/perf/pmu-events/pmu-events.h
|
||||
+++ b/tools/perf/pmu-events/pmu-events.h
|
||||
@@ -17,6 +17,7 @@ struct pmu_event {
|
||||
const char *metric_expr;
|
||||
const char *metric_name;
|
||||
const char *metric_group;
|
||||
+ const char *deprecated;
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index c0a13cf41ef6..8b9b13b6e901 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -2555,7 +2555,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 details_flag)
|
||||
+ bool long_desc, bool details_flag, bool deprecated)
|
||||
{
|
||||
print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
|
||||
event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
|
||||
@@ -2567,7 +2567,7 @@ 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,
|
||||
- details_flag);
|
||||
+ details_flag, deprecated);
|
||||
|
||||
if (event_glob != NULL)
|
||||
return;
|
||||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
||||
index 58c6730526f9..52be0b3b26f7 100644
|
||||
--- a/tools/perf/util/parse-events.h
|
||||
+++ b/tools/perf/util/parse-events.h
|
||||
@@ -192,7 +192,7 @@ void parse_events_evlist_error(struct parse_events_state *parse_state,
|
||||
int idx, const char *str);
|
||||
|
||||
void print_events(const char *event_glob, bool name_only, bool quiet,
|
||||
- bool long_desc, bool details_flag);
|
||||
+ bool long_desc, bool details_flag, bool deprecated);
|
||||
|
||||
struct event_symbol {
|
||||
const char *symbol;
|
||||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
|
||||
index 147989e2bff0..2d06db85c135 100644
|
||||
--- a/tools/perf/util/pmu.c
|
||||
+++ b/tools/perf/util/pmu.c
|
||||
@@ -307,7 +307,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
|
||||
char *long_desc, char *topic,
|
||||
char *unit, char *perpkg,
|
||||
char *metric_expr,
|
||||
- char *metric_name)
|
||||
+ char *metric_name,
|
||||
+ char *deprecated)
|
||||
{
|
||||
struct parse_events_term *term;
|
||||
struct perf_pmu_alias *alias;
|
||||
@@ -324,6 +325,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
|
||||
alias->unit[0] = '\0';
|
||||
alias->per_pkg = false;
|
||||
alias->snapshot = false;
|
||||
+ alias->deprecated = false;
|
||||
|
||||
ret = parse_events_terms(&alias->terms, val);
|
||||
if (ret) {
|
||||
@@ -378,6 +380,9 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
|
||||
alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
|
||||
alias->str = strdup(newval);
|
||||
|
||||
+ if (deprecated)
|
||||
+ alias->deprecated = true;
|
||||
+
|
||||
if (!perf_pmu_merge_alias(alias, list))
|
||||
list_add_tail(&alias->list, list);
|
||||
|
||||
@@ -399,7 +404,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
|
||||
rtrim(buf);
|
||||
|
||||
return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
|
||||
- NULL, NULL, NULL);
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static inline bool pmu_alias_info_file(char *name)
|
||||
@@ -825,7 +830,8 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
|
||||
(char *)pe->long_desc, (char *)pe->topic,
|
||||
(char *)pe->unit, (char *)pe->perpkg,
|
||||
(char *)pe->metric_expr,
|
||||
- (char *)pe->metric_name);
|
||||
+ (char *)pe->metric_name,
|
||||
+ (char *)pe->deprecated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1407,7 +1413,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 details_flag)
|
||||
+ bool long_desc, bool details_flag, bool deprecated)
|
||||
{
|
||||
struct perf_pmu *pmu;
|
||||
struct perf_pmu_alias *alias;
|
||||
@@ -1438,6 +1444,9 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
|
||||
format_alias(buf, sizeof(buf), pmu, alias);
|
||||
bool is_cpu = !strcmp(pmu->name, "cpu");
|
||||
|
||||
+ if (alias->deprecated && !deprecated)
|
||||
+ continue;
|
||||
+
|
||||
if (event_glob != NULL &&
|
||||
!(strglobmatch_nocase(name, event_glob) ||
|
||||
(!is_cpu && strglobmatch_nocase(alias->name,
|
||||
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
|
||||
index ea0e7c36eae9..a7f1d60c288b 100644
|
||||
--- a/tools/perf/util/pmu.h
|
||||
+++ b/tools/perf/util/pmu.h
|
||||
@@ -55,6 +55,7 @@ struct perf_pmu_alias {
|
||||
double scale;
|
||||
bool per_pkg;
|
||||
bool snapshot;
|
||||
+ bool deprecated;
|
||||
char *metric_expr;
|
||||
char *metric_name;
|
||||
};
|
||||
@@ -83,7 +84,8 @@ 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 details_flag);
|
||||
+ bool long_desc, bool details_flag,
|
||||
+ bool deprecated);
|
||||
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, ...) __scanf(3, 4);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,151 @@
|
||||
From aa636dd0053413996f78efb463c8a4e1802930e2 Mon Sep 17 00:00:00 2001
|
||||
From: Kajol Jain <kjain@linux.ibm.com>
|
||||
Date: Wed, 20 Nov 2019 14:10:59 +0530
|
||||
Subject: [PATCH 035/201] perf metricgroup: Fix printing event names of metric
|
||||
group with multiple events
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc3
|
||||
commit eb573e746b9d4f0921dcb2449be3df41dae3caea
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=eb573e746b9d4f0921dcb2449be3df41dae3caea
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Commit f01642e4912b ("perf metricgroup: Support multiple events for
|
||||
metricgroup") introduced support for multiple events in a metric group.
|
||||
But with the current upstream, metric events names are not printed
|
||||
properly
|
||||
|
||||
In power9 platform:
|
||||
|
||||
command:# ./perf stat --metric-only -M translation -C 0 -I 1000 sleep 2
|
||||
1.000208486
|
||||
2.000368863
|
||||
2.001400558
|
||||
|
||||
Similarly in skylake platform:
|
||||
|
||||
command:./perf stat --metric-only -M Power -I 1000
|
||||
1.000579994
|
||||
2.002189493
|
||||
|
||||
With current upstream version, issue is with event name comparison logic
|
||||
in find_evsel_group(). Current logic is to compare events belonging to a
|
||||
metric group to the events in perf_evlist. Since the break statement is
|
||||
missing in the loop used for comparison between metric group and
|
||||
perf_evlist events, the loop continues to execute even after getting a
|
||||
pattern match, and end up in discarding the matches.
|
||||
|
||||
Incase of single metric event belongs to metric group, its working fine,
|
||||
because in case of single event once it compare all events it reaches to
|
||||
end of perf_evlist.
|
||||
|
||||
Example for single metric event in power9 platform:
|
||||
|
||||
command:# ./perf stat --metric-only -M branches_per_inst -I 1000 sleep 1
|
||||
1.000094653 0.2
|
||||
1.001337059 0.0
|
||||
|
||||
This patch fixes the issue by making sure once we found all events
|
||||
belongs to that metric event matched in find_evsel_group(), we
|
||||
successfully break from that loop by adding corresponding condition.
|
||||
|
||||
With this patch:
|
||||
In power9 platform:
|
||||
|
||||
command:# ./perf stat --metric-only -M translation -C 0 -I 1000 sleep 2
|
||||
result:#
|
||||
time derat_4k_miss_rate_percent derat_4k_miss_ratio derat_miss_ratio derat_64k_miss_rate_percent derat_64k_miss_ratio dslb_miss_rate_percent islb_miss_rate_percent
|
||||
1.000135672 0.0 0.3 1.0 0.0 0.2 0.0 0.0
|
||||
2.000380617 0.0 0.0 0.0 0.0 0.0 0.0 0.0
|
||||
|
||||
command:# ./perf stat --metric-only -M Power -I 1000
|
||||
|
||||
Similarly in skylake platform:
|
||||
result:#
|
||||
time Turbo_Utilization C3_Core_Residency C6_Core_Residency C7_Core_Residency C2_Pkg_Residency C3_Pkg_Residency C6_Pkg_Residency C7_Pkg_Residency
|
||||
1.000563580 0.3 0.0 2.6 44.2 21.9 0.0 0.0 0.0
|
||||
2.002235027 0.4 0.0 2.7 43.0 20.7 0.0 0.0 0.0
|
||||
|
||||
Committer testing:
|
||||
|
||||
Before:
|
||||
|
||||
[root@seventh ~]# perf stat --metric-only -M Power -I 1000
|
||||
# time
|
||||
1.000383223
|
||||
2.001168182
|
||||
3.001968545
|
||||
4.002741200
|
||||
5.003442022
|
||||
^C 5.777687244
|
||||
|
||||
[root@seventh ~]#
|
||||
|
||||
After the patch:
|
||||
|
||||
[root@seventh ~]# perf stat --metric-only -M Power -I 1000
|
||||
# time Turbo_Utilization C3_Core_Residency C6_Core_Residency C7_Core_Residency C2_Pkg_Residency C3_Pkg_Residency C6_Pkg_Residency C7_Pkg_Residency
|
||||
1.000406577 0.4 0.1 1.4 97.0 0.0 0.0 0.0 0.0
|
||||
2.001481572 0.3 0.0 0.6 97.9 0.0 0.0 0.0 0.0
|
||||
3.002332585 0.2 0.0 1.0 97.5 0.0 0.0 0.0 0.0
|
||||
4.003196624 0.2 0.0 0.3 98.6 0.0 0.0 0.0 0.0
|
||||
5.004063851 0.3 0.0 0.7 97.7 0.0 0.0 0.0 0.0
|
||||
^C 5.471260276 0.2 0.0 0.5 49.3 0.0 0.0 0.0 0.0
|
||||
|
||||
[root@seventh ~]#
|
||||
[root@seventh ~]# dmesg | grep -i skylake
|
||||
[ 0.187807] Performance Events: PEBS fmt3+, Skylake events, 32-deep LBR, full-width counters, Intel PMU driver.
|
||||
[root@seventh ~]#
|
||||
|
||||
Fixes: f01642e4912b ("perf metricgroup: Support multiple events for metricgroup")
|
||||
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
|
||||
Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Anju T Sudhakar <anju@linux.vnet.ibm.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lore.kernel.org/lkml/20191120084059.24458-1-kjain@linux.ibm.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 375866dab75b..303f0fde6759 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -109,8 +109,11 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
if (!strcmp(ev->name, ids[i])) {
|
||||
if (!metric_events[i])
|
||||
metric_events[i] = ev;
|
||||
+ i++;
|
||||
+ if (i == idnum)
|
||||
+ break;
|
||||
} else {
|
||||
- if (++i == idnum) {
|
||||
+ if (i + 1 == idnum) {
|
||||
/* Discard the whole match and start again */
|
||||
i = 0;
|
||||
memset(metric_events, 0,
|
||||
@@ -130,7 +133,7 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
}
|
||||
}
|
||||
|
||||
- if (i != idnum - 1) {
|
||||
+ if (i != idnum) {
|
||||
/* Not whole match */
|
||||
return NULL;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
From b91e36590cb2508bff91771222eb811dfde5ee77 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Budankov <alexey.budankov@linux.intel.com>
|
||||
Date: Tue, 3 Dec 2019 14:43:33 +0300
|
||||
Subject: [PATCH 036/201] tools bitmap: Implement bitmap_equal() operation at
|
||||
bitmap API
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.6-rc1
|
||||
commit 8812ad412f851216d6c39488a7e563ccc5c604cc
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8812ad412f851216d6c39488a7e563ccc5c604cc
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
Extend tools bitmap API with bitmap_equal() implementation.
|
||||
|
||||
The implementation has been derived from the kernel.
|
||||
|
||||
Extend tools bitmap API with bitmap_free() implementation for symmetry
|
||||
with bitmap_alloc() function.
|
||||
|
||||
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lore.kernel.org/lkml/43757993-0b28-d8af-a6c7-ede12e3a6877@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
tools/include/linux/bitmap.h
|
||||
---
|
||||
tools/include/linux/bitmap.h | 30 ++++++++++++++++++++++++++++++
|
||||
tools/lib/bitmap.c | 15 +++++++++++++++
|
||||
2 files changed, 45 insertions(+)
|
||||
|
||||
diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
|
||||
index e63662db131b..682a3f88db87 100644
|
||||
--- a/tools/include/linux/bitmap.h
|
||||
+++ b/tools/include/linux/bitmap.h
|
||||
@@ -15,6 +15,8 @@ void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, int bits);
|
||||
int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, unsigned int bits);
|
||||
+int __bitmap_equal(const unsigned long *bitmap1,
|
||||
+ const unsigned long *bitmap2, unsigned int bits);
|
||||
|
||||
#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
|
||||
|
||||
@@ -122,6 +124,15 @@ static inline unsigned long *bitmap_alloc(int nbits)
|
||||
return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * bitmap_free - Free bitmap
|
||||
+ * @bitmap: pointer to bitmap
|
||||
+ */
|
||||
+static inline void bitmap_free(unsigned long *bitmap)
|
||||
+{
|
||||
+ free(bitmap);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* bitmap_scnprintf - print bitmap list into buffer
|
||||
* @bitmap: bitmap
|
||||
@@ -147,4 +158,23 @@ static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
|
||||
return __bitmap_and(dst, src1, src2, nbits);
|
||||
}
|
||||
|
||||
+#ifdef __LITTLE_ENDIAN
|
||||
+#define BITMAP_MEM_ALIGNMENT 8
|
||||
+#else
|
||||
+#define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long))
|
||||
+#endif
|
||||
+#define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
|
||||
+#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
|
||||
+
|
||||
+static inline int bitmap_equal(const unsigned long *src1,
|
||||
+ const unsigned long *src2, unsigned int nbits)
|
||||
+{
|
||||
+ if (small_const_nbits(nbits))
|
||||
+ return !((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
|
||||
+ if (__builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
|
||||
+ IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
|
||||
+ return !memcmp(src1, src2, nbits / 8);
|
||||
+ return __bitmap_equal(src1, src2, nbits);
|
||||
+}
|
||||
+
|
||||
#endif /* _PERF_BITOPS_H */
|
||||
diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
|
||||
index 38748b0e342f..e4a0db44d615 100644
|
||||
--- a/tools/lib/bitmap.c
|
||||
+++ b/tools/lib/bitmap.c
|
||||
@@ -73,3 +73,18 @@ int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
|
||||
BITMAP_LAST_WORD_MASK(bits));
|
||||
return result != 0;
|
||||
}
|
||||
+
|
||||
+int __bitmap_equal(const unsigned long *bitmap1,
|
||||
+ const unsigned long *bitmap2, unsigned int bits)
|
||||
+{
|
||||
+ unsigned int k, lim = bits/BITS_PER_LONG;
|
||||
+ for (k = 0; k < lim; ++k)
|
||||
+ if (bitmap1[k] != bitmap2[k])
|
||||
+ return 0;
|
||||
+
|
||||
+ if (bits % BITS_PER_LONG)
|
||||
+ if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
|
||||
+ return 0;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,212 @@
|
||||
From 887e5e7550dda0f6c99d796a9bf81cbf2e128b31 Mon Sep 17 00:00:00 2001
|
||||
From: Kajol Jain <kjain@linux.ibm.com>
|
||||
Date: Fri, 21 Feb 2020 15:41:21 +0530
|
||||
Subject: [PATCH 037/201] perf metricgroup: Fix printing event names of metric
|
||||
group with multiple events incase of overlapping events
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 58fc90fda0cc983c11c5290c7a9e992b08ac4a5c
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=58fc90fda0cc983c11c5290c7a9e992b08ac4a5c
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Commit f01642e4912b ("perf metricgroup: Support multiple events for
|
||||
metricgroup") introduced support for multiple events in a metric group.
|
||||
But with the current upstream, metric events names are not printed
|
||||
properly incase we try to run multiple metric groups with overlapping
|
||||
event.
|
||||
|
||||
With current upstream version, incase of overlapping metric events issue
|
||||
is, we always start our comparision logic from start. So, the events
|
||||
which already matched with some metric group also take part in
|
||||
comparision logic. Because of that when we have overlapping events, we
|
||||
end up matching current metric group event with already matched one.
|
||||
|
||||
For example, in skylake machine we have metric event CoreIPC and
|
||||
Instructions. Both of them need 'inst_retired.any' event value. As
|
||||
events in Instructions is subset of events in CoreIPC, they endup in
|
||||
pointing to same 'inst_retired.any' value.
|
||||
|
||||
In skylake platform:
|
||||
|
||||
command:# ./perf stat -M CoreIPC,Instructions -C 0 sleep 1
|
||||
|
||||
Performance counter stats for 'CPU(s) 0':
|
||||
|
||||
1,254,992,790 inst_retired.any # 1254992790.0
|
||||
Instructions
|
||||
# 1.3 CoreIPC
|
||||
977,172,805 cycles
|
||||
1,254,992,756 inst_retired.any
|
||||
|
||||
1.000802596 seconds time elapsed
|
||||
|
||||
command:# sudo ./perf stat -M UPI,IPC sleep 1
|
||||
|
||||
Performance counter stats for 'sleep 1':
|
||||
948,650 uops_retired.retire_slots
|
||||
866,182 inst_retired.any # 0.7 IPC
|
||||
866,182 inst_retired.any
|
||||
1,175,671 cpu_clk_unhalted.thread
|
||||
|
||||
Patch fixes the issue by adding a new bool pointer 'evlist_used' to keep
|
||||
track of events which already matched with some group by setting it
|
||||
true. So, we skip all used events in list when we start comparision
|
||||
logic. Patch also make some changes in comparision logic, incase we get
|
||||
a match miss, we discard the whole match and start again with first
|
||||
event id in metric event.
|
||||
|
||||
With this patch:
|
||||
|
||||
In skylake platform:
|
||||
|
||||
command:# ./perf stat -M CoreIPC,Instructions -C 0 sleep 1
|
||||
|
||||
Performance counter stats for 'CPU(s) 0':
|
||||
|
||||
3,348,415 inst_retired.any # 0.3 CoreIPC
|
||||
11,779,026 cycles
|
||||
3,348,381 inst_retired.any # 3348381.0
|
||||
Instructions
|
||||
|
||||
1.001649056 seconds time elapsed
|
||||
|
||||
command:# ./perf stat -M UPI,IPC sleep 1
|
||||
|
||||
Performance counter stats for 'sleep 1':
|
||||
|
||||
1,023,148 uops_retired.retire_slots # 1.1 UPI
|
||||
924,976 inst_retired.any
|
||||
924,976 inst_retired.any # 0.6 IPC
|
||||
1,489,414 cpu_clk_unhalted.thread
|
||||
|
||||
1.003064672 seconds time elapsed
|
||||
|
||||
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Anju T Sudhakar <anju@linux.vnet.ibm.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200221101121.28920-1-kjain@linux.ibm.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 49 +++++++++++++++++++++--------------
|
||||
1 file changed, 30 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 303f0fde6759..9f6b0b0f7b59 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -99,13 +99,16 @@ struct egroup {
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
const char **ids,
|
||||
int idnum,
|
||||
- struct perf_evsel **metric_events)
|
||||
+ struct perf_evsel **metric_events,
|
||||
+ bool *evlist_used)
|
||||
{
|
||||
struct perf_evsel *ev;
|
||||
- int i = 0;
|
||||
+ int i = 0, j = 0;
|
||||
bool leader_found;
|
||||
|
||||
evlist__for_each_entry (perf_evlist, ev) {
|
||||
+ if (evlist_used[j++])
|
||||
+ continue;
|
||||
if (!strcmp(ev->name, ids[i])) {
|
||||
if (!metric_events[i])
|
||||
metric_events[i] = ev;
|
||||
@@ -113,22 +116,17 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
if (i == idnum)
|
||||
break;
|
||||
} else {
|
||||
- if (i + 1 == idnum) {
|
||||
- /* Discard the whole match and start again */
|
||||
- i = 0;
|
||||
- memset(metric_events, 0,
|
||||
- sizeof(struct evsel *) * idnum);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (!strcmp(ev->name, ids[i]))
|
||||
- metric_events[i] = ev;
|
||||
- else {
|
||||
- /* Discard the whole match and start again */
|
||||
- i = 0;
|
||||
- memset(metric_events, 0,
|
||||
- sizeof(struct evsel *) * idnum);
|
||||
- continue;
|
||||
+ /* Discard the whole match and start again */
|
||||
+ i = 0;
|
||||
+ memset(metric_events, 0,
|
||||
+ sizeof(struct perf_evsel *) * idnum);
|
||||
+
|
||||
+ if (!strcmp(ev->name, ids[i])) {
|
||||
+ if (!metric_events[i])
|
||||
+ metric_events[i] = ev;
|
||||
+ i++;
|
||||
+ if (i == idnum)
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +148,10 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
!strcmp(ev->name, metric_events[i]->name)) {
|
||||
ev->metric_leader = metric_events[i];
|
||||
}
|
||||
+ j++;
|
||||
}
|
||||
+ ev = metric_events[i];
|
||||
+ evlist_used[ev->idx] = true;
|
||||
}
|
||||
|
||||
return metric_events[0];
|
||||
@@ -166,6 +167,13 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
int ret = 0;
|
||||
struct egroup *eg;
|
||||
struct perf_evsel *evsel;
|
||||
+ bool *evlist_used;
|
||||
+
|
||||
+ evlist_used = calloc(perf_evlist->nr_entries, sizeof(bool));
|
||||
+ if (!evlist_used) {
|
||||
+ ret = -ENOMEM;
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
list_for_each_entry (eg, groups, nd) {
|
||||
struct perf_evsel **metric_events;
|
||||
@@ -176,7 +184,7 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
break;
|
||||
}
|
||||
evsel = find_evsel_group(perf_evlist, eg->ids, eg->idnum,
|
||||
- metric_events);
|
||||
+ metric_events, evlist_used);
|
||||
if (!evsel) {
|
||||
pr_debug("Cannot resolve %s: %s\n",
|
||||
eg->metric_name, eg->metric_expr);
|
||||
@@ -203,6 +211,9 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
expr->metric_events = metric_events;
|
||||
list_add(&expr->nd, &me->head);
|
||||
}
|
||||
+
|
||||
+ free(evlist_used);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From 52390925ed8b978cc74dc82655ebbddceb0a7b12 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Mon, 8 Jun 2020 22:36:10 -0700
|
||||
Subject: [PATCH 038/201] perf parse-events: Fix an old style declaration
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc2
|
||||
commit ffaecd7d1f88a955f0b321749de8c0158f973afd
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ffaecd7d1f88a955f0b321749de8c0158f973afd
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Fixes: a26e47162d76 (perf tools: Move ALLOC_LIST into a function)
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200609053610.206588-2-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/parse-events.y | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
|
||||
index ef4c83b07c22..b940b621b14e 100644
|
||||
--- a/tools/perf/util/parse-events.y
|
||||
+++ b/tools/perf/util/parse-events.y
|
||||
@@ -27,7 +27,7 @@ do { \
|
||||
YYABORT; \
|
||||
} while (0)
|
||||
|
||||
-static struct list_head* alloc_list()
|
||||
+static struct list_head* alloc_list(void)
|
||||
{
|
||||
struct list_head *list;
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
54
patches/0156-libbpf-fix-missing-__WORDSIZE-definition.patch
Normal file
54
patches/0156-libbpf-fix-missing-__WORDSIZE-definition.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 0ac7392379b31ec9b76fb42b083544cac8e4ba29 Mon Sep 17 00:00:00 2001
|
||||
From: Andrii Nakryiko <andriin@fb.com>
|
||||
Date: Thu, 18 Jul 2019 10:30:21 -0700
|
||||
Subject: [PATCH 039/201] libbpf: fix missing __WORDSIZE definition
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc3
|
||||
commit 8aa259b10a6a759c50137bbbf225df0c17ca5d27
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8aa259b10a6a759c50137bbbf225df0c17ca5d27
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
hashmap.h depends on __WORDSIZE being defined. It is defined by
|
||||
glibc/musl in different headers. It's an explicit goal for musl to be
|
||||
"non-detectable" at compilation time, so instead include glibc header if
|
||||
glibc is explicitly detected and fall back to musl header otherwise.
|
||||
|
||||
Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Cc: Alexei Starovoitov <ast@fb.com>
|
||||
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
|
||||
Cc: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Fixes: e3b924224028 ("libbpf: add resizable non-thread safe internal hashmap")
|
||||
Link: https://lkml.kernel.org/r/20190718173021.2418606-1-andriin@fb.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/lib/bpf/hashmap.h | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h
|
||||
index ab97b9797100..bae8879cdf58 100644
|
||||
--- a/tools/lib/bpf/hashmap.h
|
||||
+++ b/tools/lib/bpf/hashmap.h
|
||||
@@ -10,6 +10,12 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
+#ifdef __GLIBC__
|
||||
+#include <bits/wordsize.h>
|
||||
+#else
|
||||
+#include <bits/reg.h>
|
||||
+#endif
|
||||
+#include "libbpf_internal.h"
|
||||
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
{
|
||||
--
|
||||
2.27.0
|
||||
|
||||
44
patches/0157-libbpf-hashmap-Remove-unused-include.patch
Normal file
44
patches/0157-libbpf-hashmap-Remove-unused-include.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From e7f925737486dd8d1cd4c10f5f813632bf19f81b Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Fri, 15 May 2020 09:50:02 -0700
|
||||
Subject: [PATCH 040/201] libbpf, hashmap: Remove unused #include
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit f516acd5397fdbb77ef0aad0798d9ef7c3001d72
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f516acd5397fdbb77ef0aad0798d9ef7c3001d72
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Remove #include of libbpf_internal.h that is unused.
|
||||
|
||||
Discussed in this thread:
|
||||
https://lore.kernel.org/lkml/CAEf4BzZRmiEds_8R8g4vaAeWvJzPb4xYLnpF0X2VNY8oTzkphQ@mail.gmail.com/
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Acked-by: Andrii Nakryiko <andriin@fb.com>
|
||||
Link: https://lore.kernel.org/bpf/20200515165007.217120-3-irogers@google.com
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/lib/bpf/hashmap.h | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h
|
||||
index bae8879cdf58..e823b35e7371 100644
|
||||
--- a/tools/lib/bpf/hashmap.h
|
||||
+++ b/tools/lib/bpf/hashmap.h
|
||||
@@ -15,7 +15,6 @@
|
||||
#else
|
||||
#include <bits/reg.h>
|
||||
#endif
|
||||
-#include "libbpf_internal.h"
|
||||
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
{
|
||||
--
|
||||
2.27.0
|
||||
|
||||
54
patches/0158-libbpf-Define-__WORDSIZE-if-not-available.patch
Normal file
54
patches/0158-libbpf-Define-__WORDSIZE-if-not-available.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 5095414bbfa881d0835506efffdc28a80aeb0a21 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@kernel.org>
|
||||
Date: Tue, 9 Jun 2020 18:16:53 -0300
|
||||
Subject: [PATCH 041/201] libbpf: Define __WORDSIZE if not available
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 8ca8d4a841730c02e77bf3c87bf658cc44f364b9
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8ca8d4a841730c02e77bf3c87bf658cc44f364b9
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Some systems, such as Android, don't have a define for __WORDSIZE, do it
|
||||
in terms of __SIZEOF_LONG__, as done in perf since 2012:
|
||||
|
||||
http://git.kernel.org/torvalds/c/3f34f6c0233ae055b5
|
||||
|
||||
For reference: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
|
||||
|
||||
I build tested it here and Andrii did some Travis CI build tests too.
|
||||
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Acked-by: Andrii Nakryiko <andriin@fb.com>
|
||||
Link: https://lore.kernel.org/bpf/20200608161150.GA3073@kernel.org
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/lib/bpf/hashmap.h | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h
|
||||
index e823b35e7371..df59fd4fc95b 100644
|
||||
--- a/tools/lib/bpf/hashmap.h
|
||||
+++ b/tools/lib/bpf/hashmap.h
|
||||
@@ -10,10 +10,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
-#ifdef __GLIBC__
|
||||
-#include <bits/wordsize.h>
|
||||
-#else
|
||||
-#include <bits/reg.h>
|
||||
+#include <limits.h>
|
||||
+#ifndef __WORDSIZE
|
||||
+#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
||||
#endif
|
||||
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From 9196accd36718701e49be67194b78de6af7fe699 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Bogusz <qboosh@pld-linux.org>
|
||||
Date: Thu, 9 Jul 2020 15:57:23 -0700
|
||||
Subject: [PATCH 042/201] libbpf: Fix libbpf hashmap on (I)LP32 architectures
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc5
|
||||
commit b2f9f1535bb93ee5fa2ea30ac1c26fa0d676154c
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b2f9f1535bb93ee5fa2ea30ac1c26fa0d676154c
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
On ILP32, 64-bit result was shifted by value calculated for 32-bit long type
|
||||
and returned value was much outside hashmap capacity.
|
||||
As advised by Andrii Nakryiko, this patch uses different hashing variant for
|
||||
architectures with size_t shorter than long long.
|
||||
|
||||
Fixes: e3b924224028 ("libbpf: add resizable non-thread safe internal hashmap")
|
||||
Signed-off-by: Jakub Bogusz <qboosh@pld-linux.org>
|
||||
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
|
||||
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
||||
Link: https://lore.kernel.org/bpf/20200709225723.1069937-1-andriin@fb.com
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/lib/bpf/hashmap.h | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h
|
||||
index df59fd4fc95b..e0af36b0e5d8 100644
|
||||
--- a/tools/lib/bpf/hashmap.h
|
||||
+++ b/tools/lib/bpf/hashmap.h
|
||||
@@ -11,14 +11,18 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
-#ifndef __WORDSIZE
|
||||
-#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
||||
-#endif
|
||||
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
{
|
||||
/* shuffle bits and return requested number of upper bits */
|
||||
- return (h * 11400714819323198485llu) >> (__WORDSIZE - bits);
|
||||
+#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
|
||||
+ /* LP64 case */
|
||||
+ return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
|
||||
+#elif (__SIZEOF_SIZE_T__ <= __SIZEOF_LONG__)
|
||||
+ return (h * 2654435769lu) >> (__SIZEOF_LONG__ * 8 - bits);
|
||||
+#else
|
||||
+# error "Unsupported size_t size"
|
||||
+#endif
|
||||
}
|
||||
|
||||
typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
From 045d2fb4dd250981ae4a1df07660bcd2972f73d3 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Thu, 29 Oct 2020 15:37:07 -0700
|
||||
Subject: [PATCH 043/201] libbpf, hashmap: Fix undefined behavior in hash_bits
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.10-rc4
|
||||
commit 7a078d2d18801bba7bde7337a823d7342299acf7
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7a078d2d18801bba7bde7337a823d7342299acf7
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
If bits is 0, the case when the map is empty, then the >> is the size of
|
||||
the register which is undefined behavior - on x86 it is the same as a
|
||||
shift by 0.
|
||||
|
||||
Fix by handling the 0 case explicitly and guarding calls to hash_bits for
|
||||
empty maps in hashmap__for_each_key_entry and hashmap__for_each_entry_safe.
|
||||
|
||||
Fixes: e3b924224028 ("libbpf: add resizable non-thread safe internal hashmap")
|
||||
Suggested-by: Andrii Nakryiko <andriin@fb.com>,
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Acked-by: Andrii Nakryiko <andrii@kernel.org>
|
||||
Acked-by: Song Liu <songliubraving@fb.com>
|
||||
Link: https://lore.kernel.org/bpf/20201029223707.494059-1-irogers@google.com
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/lib/bpf/hashmap.h | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h
|
||||
index e0af36b0e5d8..6a3c3d8bb4ab 100644
|
||||
--- a/tools/lib/bpf/hashmap.h
|
||||
+++ b/tools/lib/bpf/hashmap.h
|
||||
@@ -15,6 +15,9 @@
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
{
|
||||
/* shuffle bits and return requested number of upper bits */
|
||||
+ if (bits == 0)
|
||||
+ return 0;
|
||||
+
|
||||
#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
|
||||
/* LP64 case */
|
||||
return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
|
||||
@@ -162,17 +165,17 @@ bool hashmap__find(const struct hashmap *map, const void *key, void **value);
|
||||
* @key: key to iterate entries for
|
||||
*/
|
||||
#define hashmap__for_each_key_entry(map, cur, _key) \
|
||||
- for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
- map->cap_bits); \
|
||||
- map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ for (cur = map->buckets \
|
||||
+ ? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||
+ : NULL; \
|
||||
cur; \
|
||||
cur = cur->next) \
|
||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
|
||||
#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
|
||||
- for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
- map->cap_bits); \
|
||||
- cur = map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ for (cur = map->buckets \
|
||||
+ ? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||
+ : NULL; \
|
||||
cur && ({ tmp = cur->next; true; }); \
|
||||
cur = tmp) \
|
||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
--
|
||||
2.27.0
|
||||
|
||||
530
patches/0161-perf-tools-Grab-a-copy-of-libbpf-s-hashmap.patch
Normal file
530
patches/0161-perf-tools-Grab-a-copy-of-libbpf-s-hashmap.patch
Normal file
@ -0,0 +1,530 @@
|
||||
From 625cfee7500b6402a2b280e960bd84110db9ec7a Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Fri, 15 May 2020 15:17:29 -0700
|
||||
Subject: [PATCH 044/201] perf tools: Grab a copy of libbpf's hashmap
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit eee19501926d98c894f15c1644b815c7d1fbd187
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=eee19501926d98c894f15c1644b815c7d1fbd187
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Allow use of hashmap in perf. Modify perf's check-headers.sh script to
|
||||
check that the files are kept in sync, in the same way kernel headers
|
||||
are checked. This will warn if they are out of sync at the start of a
|
||||
perf build.
|
||||
|
||||
Committer note:
|
||||
|
||||
This starts out of synch as a fix went thru the bpf tree, namely the one
|
||||
removing the needless libbpf_internal.h include in hashmap.h.
|
||||
|
||||
There is also another change related to __WORDSIZE, that as is in
|
||||
tools/lib/bpf/hashmap.h causes the tools/perf/ build to fail in systems
|
||||
such as Alpine Linus, that uses the Musl libc, so we need an alternative
|
||||
way of having __WORDSIZE available, use the one used by
|
||||
tools/include/linux/bitops.h, that builds in all the systems I have
|
||||
build containers for.
|
||||
|
||||
These differences will be resolved at some point, so keep the warning in
|
||||
check-headers.sh as a reminder.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Alexei Starovoitov <ast@kernel.org>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: John Fastabend <john.fastabend@gmail.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Martin KaFai Lau <kafai@fb.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Yonghong Song <yhs@fb.com>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: kp singh <kpsingh@chromium.org>
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200515221732.44078-5-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/check-headers.sh | 4 +
|
||||
tools/perf/util/Build | 4 +
|
||||
tools/perf/util/hashmap.c | 238 ++++++++++++++++++++++++++++++++++++
|
||||
tools/perf/util/hashmap.h | 176 ++++++++++++++++++++++++++
|
||||
4 files changed, 422 insertions(+)
|
||||
create mode 100644 tools/perf/util/hashmap.c
|
||||
create mode 100644 tools/perf/util/hashmap.h
|
||||
|
||||
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
|
||||
index c72cc73a6b09..79e3c3670655 100755
|
||||
--- a/tools/perf/check-headers.sh
|
||||
+++ b/tools/perf/check-headers.sh
|
||||
@@ -105,4 +105,8 @@ check include/uapi/linux/mman.h '-I "^#include <\(uapi/\)*asm/mman.h>"'
|
||||
# diff non-symmetric files
|
||||
check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
|
||||
|
||||
+# check duplicated library files
|
||||
+check_2 tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h
|
||||
+check_2 tools/perf/util/hashmap.c tools/lib/bpf/hashmap.c
|
||||
+
|
||||
cd tools/perf
|
||||
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
|
||||
index f4148ecffeae..de3b99f927ac 100644
|
||||
--- a/tools/perf/util/Build
|
||||
+++ b/tools/perf/util/Build
|
||||
@@ -115,6 +115,10 @@ libperf-$(CONFIG_LIBELF) += symbol-elf.o
|
||||
libperf-$(CONFIG_LIBELF) += probe-file.o
|
||||
libperf-$(CONFIG_LIBELF) += probe-event.o
|
||||
|
||||
+ifndef CONFIG_LIBBPF
|
||||
+perf-y += hashmap.o
|
||||
+endif
|
||||
+
|
||||
ifndef CONFIG_LIBELF
|
||||
libperf-y += symbol-minimal.o
|
||||
endif
|
||||
diff --git a/tools/perf/util/hashmap.c b/tools/perf/util/hashmap.c
|
||||
new file mode 100644
|
||||
index 000000000000..a405dad068f5
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/util/hashmap.c
|
||||
@@ -0,0 +1,238 @@
|
||||
+// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
+
|
||||
+/*
|
||||
+ * Generic non-thread safe hash map implementation.
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Facebook
|
||||
+ */
|
||||
+#include <stdint.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
+#include <linux/err.h>
|
||||
+#include "hashmap.h"
|
||||
+
|
||||
+/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
+#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
+
|
||||
+/* start with 4 buckets */
|
||||
+#define HASHMAP_MIN_CAP_BITS 2
|
||||
+
|
||||
+static void hashmap_add_entry(struct hashmap_entry **pprev,
|
||||
+ struct hashmap_entry *entry)
|
||||
+{
|
||||
+ entry->next = *pprev;
|
||||
+ *pprev = entry;
|
||||
+}
|
||||
+
|
||||
+static void hashmap_del_entry(struct hashmap_entry **pprev,
|
||||
+ struct hashmap_entry *entry)
|
||||
+{
|
||||
+ *pprev = entry->next;
|
||||
+ entry->next = NULL;
|
||||
+}
|
||||
+
|
||||
+void hashmap__init(struct hashmap *map, hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn, void *ctx)
|
||||
+{
|
||||
+ map->hash_fn = hash_fn;
|
||||
+ map->equal_fn = equal_fn;
|
||||
+ map->ctx = ctx;
|
||||
+
|
||||
+ map->buckets = NULL;
|
||||
+ map->cap = 0;
|
||||
+ map->cap_bits = 0;
|
||||
+ map->sz = 0;
|
||||
+}
|
||||
+
|
||||
+struct hashmap *hashmap__new(hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn,
|
||||
+ void *ctx)
|
||||
+{
|
||||
+ struct hashmap *map = malloc(sizeof(struct hashmap));
|
||||
+
|
||||
+ if (!map)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+ hashmap__init(map, hash_fn, equal_fn, ctx);
|
||||
+ return map;
|
||||
+}
|
||||
+
|
||||
+void hashmap__clear(struct hashmap *map)
|
||||
+{
|
||||
+ struct hashmap_entry *cur, *tmp;
|
||||
+ size_t bkt;
|
||||
+
|
||||
+ hashmap__for_each_entry_safe(map, cur, tmp, bkt) {
|
||||
+ free(cur);
|
||||
+ }
|
||||
+ free(map->buckets);
|
||||
+ map->buckets = NULL;
|
||||
+ map->cap = map->cap_bits = map->sz = 0;
|
||||
+}
|
||||
+
|
||||
+void hashmap__free(struct hashmap *map)
|
||||
+{
|
||||
+ if (!map)
|
||||
+ return;
|
||||
+
|
||||
+ hashmap__clear(map);
|
||||
+ free(map);
|
||||
+}
|
||||
+
|
||||
+size_t hashmap__size(const struct hashmap *map)
|
||||
+{
|
||||
+ return map->sz;
|
||||
+}
|
||||
+
|
||||
+size_t hashmap__capacity(const struct hashmap *map)
|
||||
+{
|
||||
+ return map->cap;
|
||||
+}
|
||||
+
|
||||
+static bool hashmap_needs_to_grow(struct hashmap *map)
|
||||
+{
|
||||
+ /* grow if empty or more than 75% filled */
|
||||
+ return (map->cap == 0) || ((map->sz + 1) * 4 / 3 > map->cap);
|
||||
+}
|
||||
+
|
||||
+static int hashmap_grow(struct hashmap *map)
|
||||
+{
|
||||
+ struct hashmap_entry **new_buckets;
|
||||
+ struct hashmap_entry *cur, *tmp;
|
||||
+ size_t new_cap_bits, new_cap;
|
||||
+ size_t h, bkt;
|
||||
+
|
||||
+ new_cap_bits = map->cap_bits + 1;
|
||||
+ if (new_cap_bits < HASHMAP_MIN_CAP_BITS)
|
||||
+ new_cap_bits = HASHMAP_MIN_CAP_BITS;
|
||||
+
|
||||
+ new_cap = 1UL << new_cap_bits;
|
||||
+ new_buckets = calloc(new_cap, sizeof(new_buckets[0]));
|
||||
+ if (!new_buckets)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hashmap__for_each_entry_safe(map, cur, tmp, bkt) {
|
||||
+ h = hash_bits(map->hash_fn(cur->key, map->ctx), new_cap_bits);
|
||||
+ hashmap_add_entry(&new_buckets[h], cur);
|
||||
+ }
|
||||
+
|
||||
+ map->cap = new_cap;
|
||||
+ map->cap_bits = new_cap_bits;
|
||||
+ free(map->buckets);
|
||||
+ map->buckets = new_buckets;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static bool hashmap_find_entry(const struct hashmap *map,
|
||||
+ const void *key, size_t hash,
|
||||
+ struct hashmap_entry ***pprev,
|
||||
+ struct hashmap_entry **entry)
|
||||
+{
|
||||
+ struct hashmap_entry *cur, **prev_ptr;
|
||||
+
|
||||
+ if (!map->buckets)
|
||||
+ return false;
|
||||
+
|
||||
+ for (prev_ptr = &map->buckets[hash], cur = *prev_ptr;
|
||||
+ cur;
|
||||
+ prev_ptr = &cur->next, cur = cur->next) {
|
||||
+ if (map->equal_fn(cur->key, key, map->ctx)) {
|
||||
+ if (pprev)
|
||||
+ *pprev = prev_ptr;
|
||||
+ *entry = cur;
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+int hashmap__insert(struct hashmap *map, const void *key, void *value,
|
||||
+ enum hashmap_insert_strategy strategy,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ struct hashmap_entry *entry;
|
||||
+ size_t h;
|
||||
+ int err;
|
||||
+
|
||||
+ if (old_key)
|
||||
+ *old_key = NULL;
|
||||
+ if (old_value)
|
||||
+ *old_value = NULL;
|
||||
+
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ if (strategy != HASHMAP_APPEND &&
|
||||
+ hashmap_find_entry(map, key, h, NULL, &entry)) {
|
||||
+ if (old_key)
|
||||
+ *old_key = entry->key;
|
||||
+ if (old_value)
|
||||
+ *old_value = entry->value;
|
||||
+
|
||||
+ if (strategy == HASHMAP_SET || strategy == HASHMAP_UPDATE) {
|
||||
+ entry->key = key;
|
||||
+ entry->value = value;
|
||||
+ return 0;
|
||||
+ } else if (strategy == HASHMAP_ADD) {
|
||||
+ return -EEXIST;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (strategy == HASHMAP_UPDATE)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ if (hashmap_needs_to_grow(map)) {
|
||||
+ err = hashmap_grow(map);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ }
|
||||
+
|
||||
+ entry = malloc(sizeof(struct hashmap_entry));
|
||||
+ if (!entry)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ entry->key = key;
|
||||
+ entry->value = value;
|
||||
+ hashmap_add_entry(&map->buckets[h], entry);
|
||||
+ map->sz++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+bool hashmap__find(const struct hashmap *map, const void *key, void **value)
|
||||
+{
|
||||
+ struct hashmap_entry *entry;
|
||||
+ size_t h;
|
||||
+
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ if (!hashmap_find_entry(map, key, h, NULL, &entry))
|
||||
+ return false;
|
||||
+
|
||||
+ if (value)
|
||||
+ *value = entry->value;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool hashmap__delete(struct hashmap *map, const void *key,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ struct hashmap_entry **pprev, *entry;
|
||||
+ size_t h;
|
||||
+
|
||||
+ h = hash_bits(map->hash_fn(key, map->ctx), map->cap_bits);
|
||||
+ if (!hashmap_find_entry(map, key, h, &pprev, &entry))
|
||||
+ return false;
|
||||
+
|
||||
+ if (old_key)
|
||||
+ *old_key = entry->key;
|
||||
+ if (old_value)
|
||||
+ *old_value = entry->value;
|
||||
+
|
||||
+ hashmap_del_entry(pprev, entry);
|
||||
+ free(entry);
|
||||
+ map->sz--;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
diff --git a/tools/perf/util/hashmap.h b/tools/perf/util/hashmap.h
|
||||
new file mode 100644
|
||||
index 000000000000..df59fd4fc95b
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/util/hashmap.h
|
||||
@@ -0,0 +1,176 @@
|
||||
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||
+
|
||||
+/*
|
||||
+ * Generic non-thread safe hash map implementation.
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Facebook
|
||||
+ */
|
||||
+#ifndef __LIBBPF_HASHMAP_H
|
||||
+#define __LIBBPF_HASHMAP_H
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+#include <stddef.h>
|
||||
+#include <limits.h>
|
||||
+#ifndef __WORDSIZE
|
||||
+#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
||||
+#endif
|
||||
+
|
||||
+static inline size_t hash_bits(size_t h, int bits)
|
||||
+{
|
||||
+ /* shuffle bits and return requested number of upper bits */
|
||||
+ return (h * 11400714819323198485llu) >> (__WORDSIZE - bits);
|
||||
+}
|
||||
+
|
||||
+typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
||||
+typedef bool (*hashmap_equal_fn)(const void *key1, const void *key2, void *ctx);
|
||||
+
|
||||
+struct hashmap_entry {
|
||||
+ const void *key;
|
||||
+ void *value;
|
||||
+ struct hashmap_entry *next;
|
||||
+};
|
||||
+
|
||||
+struct hashmap {
|
||||
+ hashmap_hash_fn hash_fn;
|
||||
+ hashmap_equal_fn equal_fn;
|
||||
+ void *ctx;
|
||||
+
|
||||
+ struct hashmap_entry **buckets;
|
||||
+ size_t cap;
|
||||
+ size_t cap_bits;
|
||||
+ size_t sz;
|
||||
+};
|
||||
+
|
||||
+#define HASHMAP_INIT(hash_fn, equal_fn, ctx) { \
|
||||
+ .hash_fn = (hash_fn), \
|
||||
+ .equal_fn = (equal_fn), \
|
||||
+ .ctx = (ctx), \
|
||||
+ .buckets = NULL, \
|
||||
+ .cap = 0, \
|
||||
+ .cap_bits = 0, \
|
||||
+ .sz = 0, \
|
||||
+}
|
||||
+
|
||||
+void hashmap__init(struct hashmap *map, hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn, void *ctx);
|
||||
+struct hashmap *hashmap__new(hashmap_hash_fn hash_fn,
|
||||
+ hashmap_equal_fn equal_fn,
|
||||
+ void *ctx);
|
||||
+void hashmap__clear(struct hashmap *map);
|
||||
+void hashmap__free(struct hashmap *map);
|
||||
+
|
||||
+size_t hashmap__size(const struct hashmap *map);
|
||||
+size_t hashmap__capacity(const struct hashmap *map);
|
||||
+
|
||||
+/*
|
||||
+ * Hashmap insertion strategy:
|
||||
+ * - HASHMAP_ADD - only add key/value if key doesn't exist yet;
|
||||
+ * - HASHMAP_SET - add key/value pair if key doesn't exist yet; otherwise,
|
||||
+ * update value;
|
||||
+ * - HASHMAP_UPDATE - update value, if key already exists; otherwise, do
|
||||
+ * nothing and return -ENOENT;
|
||||
+ * - HASHMAP_APPEND - always add key/value pair, even if key already exists.
|
||||
+ * This turns hashmap into a multimap by allowing multiple values to be
|
||||
+ * associated with the same key. Most useful read API for such hashmap is
|
||||
+ * hashmap__for_each_key_entry() iteration. If hashmap__find() is still
|
||||
+ * used, it will return last inserted key/value entry (first in a bucket
|
||||
+ * chain).
|
||||
+ */
|
||||
+enum hashmap_insert_strategy {
|
||||
+ HASHMAP_ADD,
|
||||
+ HASHMAP_SET,
|
||||
+ HASHMAP_UPDATE,
|
||||
+ HASHMAP_APPEND,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__insert() adds key/value entry w/ various semantics, depending on
|
||||
+ * provided strategy value. If a given key/value pair replaced already
|
||||
+ * existing key/value pair, both old key and old value will be returned
|
||||
+ * through old_key and old_value to allow calling code do proper memory
|
||||
+ * management.
|
||||
+ */
|
||||
+int hashmap__insert(struct hashmap *map, const void *key, void *value,
|
||||
+ enum hashmap_insert_strategy strategy,
|
||||
+ const void **old_key, void **old_value);
|
||||
+
|
||||
+static inline int hashmap__add(struct hashmap *map,
|
||||
+ const void *key, void *value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_ADD, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+static inline int hashmap__set(struct hashmap *map,
|
||||
+ const void *key, void *value,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_SET,
|
||||
+ old_key, old_value);
|
||||
+}
|
||||
+
|
||||
+static inline int hashmap__update(struct hashmap *map,
|
||||
+ const void *key, void *value,
|
||||
+ const void **old_key, void **old_value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_UPDATE,
|
||||
+ old_key, old_value);
|
||||
+}
|
||||
+
|
||||
+static inline int hashmap__append(struct hashmap *map,
|
||||
+ const void *key, void *value)
|
||||
+{
|
||||
+ return hashmap__insert(map, key, value, HASHMAP_APPEND, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+bool hashmap__delete(struct hashmap *map, const void *key,
|
||||
+ const void **old_key, void **old_value);
|
||||
+
|
||||
+bool hashmap__find(const struct hashmap *map, const void *key, void **value);
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__for_each_entry - iterate over all entries in hashmap
|
||||
+ * @map: hashmap to iterate
|
||||
+ * @cur: struct hashmap_entry * used as a loop cursor
|
||||
+ * @bkt: integer used as a bucket loop cursor
|
||||
+ */
|
||||
+#define hashmap__for_each_entry(map, cur, bkt) \
|
||||
+ for (bkt = 0; bkt < map->cap; bkt++) \
|
||||
+ for (cur = map->buckets[bkt]; cur; cur = cur->next)
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__for_each_entry_safe - iterate over all entries in hashmap, safe
|
||||
+ * against removals
|
||||
+ * @map: hashmap to iterate
|
||||
+ * @cur: struct hashmap_entry * used as a loop cursor
|
||||
+ * @tmp: struct hashmap_entry * used as a temporary next cursor storage
|
||||
+ * @bkt: integer used as a bucket loop cursor
|
||||
+ */
|
||||
+#define hashmap__for_each_entry_safe(map, cur, tmp, bkt) \
|
||||
+ for (bkt = 0; bkt < map->cap; bkt++) \
|
||||
+ for (cur = map->buckets[bkt]; \
|
||||
+ cur && ({tmp = cur->next; true; }); \
|
||||
+ cur = tmp)
|
||||
+
|
||||
+/*
|
||||
+ * hashmap__for_each_key_entry - iterate over entries associated with given key
|
||||
+ * @map: hashmap to iterate
|
||||
+ * @cur: struct hashmap_entry * used as a loop cursor
|
||||
+ * @key: key to iterate entries for
|
||||
+ */
|
||||
+#define hashmap__for_each_key_entry(map, cur, _key) \
|
||||
+ for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
+ map->cap_bits); \
|
||||
+ map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ cur; \
|
||||
+ cur = cur->next) \
|
||||
+ if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
+
|
||||
+#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
|
||||
+ for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
+ map->cap_bits); \
|
||||
+ cur = map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ cur && ({ tmp = cur->next; true; }); \
|
||||
+ cur = tmp) \
|
||||
+ if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
+
|
||||
+#endif /* __LIBBPF_HASHMAP_H */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
71
patches/0162-perf-tools-Sync-hashmap.h-with-libbpf-s.patch
Normal file
71
patches/0162-perf-tools-Sync-hashmap.h-with-libbpf-s.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From 7661750ff202b9382e81b0c2de267f029be4a61f Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Fri, 17 Jul 2020 09:35:18 -0300
|
||||
Subject: [PATCH 045/201] perf tools: Sync hashmap.h with libbpf's
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc6
|
||||
commit 94fddb7ad019ad9f14d33cd0a6cd159a52a082b8
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8aa259b10a6a759c50137bbbf225df0c17ca5d27
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
To pick up the changes in:
|
||||
|
||||
b2f9f1535bb9 ("libbpf: Fix libbpf hashmap on (I)LP32 architectures")
|
||||
|
||||
Silencing this warning:
|
||||
|
||||
Warning: Kernel ABI header at 'tools/perf/util/hashmap.h' differs from latest version at 'tools/lib/bpf/hashmap.h'
|
||||
diff -u tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h
|
||||
|
||||
I'll eventually update the warning to remove the "Kernel ABI" part
|
||||
and instead state libbpf when noticing that the original is at
|
||||
"tools/lib/something".
|
||||
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexei Starovoitov <ast@kernel.org>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Jakub Bogusz <qboosh@pld-linux.org>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Ian Rogers <irogers@google.com>
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/hashmap.h | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/hashmap.h b/tools/perf/util/hashmap.h
|
||||
index df59fd4fc95b..e0af36b0e5d8 100644
|
||||
--- a/tools/perf/util/hashmap.h
|
||||
+++ b/tools/perf/util/hashmap.h
|
||||
@@ -11,14 +11,18 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
-#ifndef __WORDSIZE
|
||||
-#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
||||
-#endif
|
||||
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
{
|
||||
/* shuffle bits and return requested number of upper bits */
|
||||
- return (h * 11400714819323198485llu) >> (__WORDSIZE - bits);
|
||||
+#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
|
||||
+ /* LP64 case */
|
||||
+ return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
|
||||
+#elif (__SIZEOF_SIZE_T__ <= __SIZEOF_LONG__)
|
||||
+ return (h * 2654435769lu) >> (__SIZEOF_LONG__ * 8 - bits);
|
||||
+#else
|
||||
+# error "Unsupported size_t size"
|
||||
+#endif
|
||||
}
|
||||
|
||||
typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
From 4585d686a89dbea92f4d25ad72f249079bc17205 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Wed, 18 Nov 2020 08:32:33 -0300
|
||||
Subject: [PATCH 046/201] perf tools: Update copy of libbpf's hashmap.c
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.10-rc6
|
||||
commit 3b13eaf0ba1d5ab59368e23ff5e5350f51c1a352
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3b13eaf0ba1d5ab59368e23ff5e5350f51c1a352
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
To pick the changes in:
|
||||
|
||||
7a078d2d18801bba ("libbpf, hashmap: Fix undefined behavior in hash_bits")
|
||||
|
||||
That don't entail any changes in tools/perf.
|
||||
|
||||
This addresses this perf build warning:
|
||||
|
||||
Warning: Kernel ABI header at 'tools/perf/util/hashmap.h' differs from latest version at 'tools/lib/bpf/hashmap.h'
|
||||
diff -u tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h
|
||||
|
||||
Not a kernel ABI, its just that this uses the mechanism in place for
|
||||
checking kernel ABI files drift.
|
||||
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Cc: Ian Rogers <irogers@google.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/hashmap.h | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/hashmap.h b/tools/perf/util/hashmap.h
|
||||
index e0af36b0e5d8..6a3c3d8bb4ab 100644
|
||||
--- a/tools/perf/util/hashmap.h
|
||||
+++ b/tools/perf/util/hashmap.h
|
||||
@@ -15,6 +15,9 @@
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
{
|
||||
/* shuffle bits and return requested number of upper bits */
|
||||
+ if (bits == 0)
|
||||
+ return 0;
|
||||
+
|
||||
#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
|
||||
/* LP64 case */
|
||||
return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
|
||||
@@ -162,17 +165,17 @@ bool hashmap__find(const struct hashmap *map, const void *key, void **value);
|
||||
* @key: key to iterate entries for
|
||||
*/
|
||||
#define hashmap__for_each_key_entry(map, cur, _key) \
|
||||
- for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
- map->cap_bits); \
|
||||
- map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ for (cur = map->buckets \
|
||||
+ ? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||
+ : NULL; \
|
||||
cur; \
|
||||
cur = cur->next) \
|
||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
|
||||
#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
|
||||
- for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
- map->cap_bits); \
|
||||
- cur = map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
+ for (cur = map->buckets \
|
||||
+ ? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||
+ : NULL; \
|
||||
cur && ({ tmp = cur->next; true; }); \
|
||||
cur = tmp) \
|
||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
--
|
||||
2.27.0
|
||||
|
||||
163
patches/0164-perf-jevents-Support-metric-constraint.patch
Normal file
163
patches/0164-perf-jevents-Support-metric-constraint.patch
Normal file
@ -0,0 +1,163 @@
|
||||
From a9c52df71f4eb8655717014fe266527a572e5c82 Mon Sep 17 00:00:00 2001
|
||||
From: Kan Liang <kan.liang@linux.intel.com>
|
||||
Date: Mon, 24 Feb 2020 13:59:20 -0800
|
||||
Subject: [PATCH 047/201] perf jevents: Support metric constraint
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 03fe02b113888576dc90c3e918d8e1a76b1ceb63
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=03fe02b113888576dc90c3e918d8e1a76b1ceb63
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
A new field "MetricConstraint" is introduced in JSON event list.
|
||||
|
||||
Extend jevents to parse the field and save the value in
|
||||
metric_constraint.
|
||||
|
||||
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/1582581564-184429-2-git-send-email-kan.liang@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/pmu-events/jevents.c | 19 +++++++++++++------
|
||||
tools/perf/pmu-events/jevents.h | 2 +-
|
||||
tools/perf/pmu-events/pmu-events.h | 1 +
|
||||
3 files changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index a1eff577f002..6bf2237fef2d 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -324,7 +324,7 @@ static int print_events_table_entry(void *data, char *name, char *event,
|
||||
char *pmu, char *unit, char *perpkg,
|
||||
char *metric_expr,
|
||||
char *metric_name, char *metric_group,
|
||||
- char *deprecated)
|
||||
+ char *deprecated, char *metric_constraint)
|
||||
{
|
||||
struct perf_entry_data *pd = data;
|
||||
FILE *outfp = pd->outfp;
|
||||
@@ -358,6 +358,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
|
||||
fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group);
|
||||
if (deprecated)
|
||||
fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated);
|
||||
+ if (metric_constraint)
|
||||
+ fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint);
|
||||
fprintf(outfp, "},\n");
|
||||
|
||||
return 0;
|
||||
@@ -376,6 +378,7 @@ struct event_struct {
|
||||
char *metric_name;
|
||||
char *metric_group;
|
||||
char *deprecated;
|
||||
+ char *metric_constraint;
|
||||
};
|
||||
|
||||
#define ADD_EVENT_FIELD(field) do { if (field) { \
|
||||
@@ -423,7 +426,7 @@ static int save_arch_std_events(void *data, char *name, char *event,
|
||||
char *desc, char *long_desc, char *pmu,
|
||||
char *unit, char *perpkg, char *metric_expr,
|
||||
char *metric_name, char *metric_group,
|
||||
- char *deprecated)
|
||||
+ char *deprecated, char *metric_constraint)
|
||||
{
|
||||
struct event_struct *es;
|
||||
|
||||
@@ -487,7 +490,7 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc,
|
||||
char **name, char **long_desc, char **pmu, char **filter,
|
||||
char **perpkg, char **unit, char **metric_expr, char **metric_name,
|
||||
char **metric_group, unsigned long long eventcode,
|
||||
- char **deprecated)
|
||||
+ char **deprecated, char **metric_constraint)
|
||||
{
|
||||
/* try to find matching event from arch standard values */
|
||||
struct event_struct *es;
|
||||
@@ -516,7 +519,7 @@ int json_events(const char *fn,
|
||||
char *pmu, char *unit, char *perpkg,
|
||||
char *metric_expr,
|
||||
char *metric_name, char *metric_group,
|
||||
- char *deprecated),
|
||||
+ char *deprecated, char *metric_constraint),
|
||||
void *data)
|
||||
{
|
||||
int err;
|
||||
@@ -546,6 +549,7 @@ int json_events(const char *fn,
|
||||
char *metric_name = NULL;
|
||||
char *metric_group = NULL;
|
||||
char *deprecated = NULL;
|
||||
+ char *metric_constraint = NULL;
|
||||
char *arch_std = NULL;
|
||||
unsigned long long eventcode = 0;
|
||||
struct msrmap *msr = NULL;
|
||||
@@ -630,6 +634,8 @@ int json_events(const char *fn,
|
||||
addfield(map, &metric_name, "", "", val);
|
||||
} else if (json_streq(map, field, "MetricGroup")) {
|
||||
addfield(map, &metric_group, "", "", val);
|
||||
+ } else if (json_streq(map, field, "MetricConstraint")) {
|
||||
+ addfield(map, &metric_constraint, "", "", val);
|
||||
} else if (json_streq(map, field, "MetricExpr")) {
|
||||
addfield(map, &metric_expr, "", "", val);
|
||||
for (s = metric_expr; *s; s++)
|
||||
@@ -671,13 +677,13 @@ int json_events(const char *fn,
|
||||
&long_desc, &pmu, &filter, &perpkg,
|
||||
&unit, &metric_expr, &metric_name,
|
||||
&metric_group, eventcode,
|
||||
- &deprecated);
|
||||
+ &deprecated, &metric_constraint);
|
||||
if (err)
|
||||
goto free_strings;
|
||||
}
|
||||
err = func(data, name, real_event(name, event), desc, long_desc,
|
||||
pmu, unit, perpkg, metric_expr, metric_name,
|
||||
- metric_group, deprecated);
|
||||
+ metric_group, deprecated, metric_constraint);
|
||||
free_strings:
|
||||
free(event);
|
||||
free(desc);
|
||||
@@ -692,6 +698,7 @@ int json_events(const char *fn,
|
||||
free(metric_expr);
|
||||
free(metric_name);
|
||||
free(metric_group);
|
||||
+ free(metric_constraint);
|
||||
free(arch_std);
|
||||
|
||||
if (err)
|
||||
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
|
||||
index 5cda49a42143..2afc8304529e 100644
|
||||
--- a/tools/perf/pmu-events/jevents.h
|
||||
+++ b/tools/perf/pmu-events/jevents.h
|
||||
@@ -8,7 +8,7 @@ int json_events(const char *fn,
|
||||
char *pmu,
|
||||
char *unit, char *perpkg, char *metric_expr,
|
||||
char *metric_name, char *metric_group,
|
||||
- char *deprecated),
|
||||
+ char *deprecated, char *metric_constraint),
|
||||
void *data);
|
||||
char *get_cpu_str(void);
|
||||
|
||||
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
|
||||
index caeb577d36c9..53e76d5d5b37 100644
|
||||
--- a/tools/perf/pmu-events/pmu-events.h
|
||||
+++ b/tools/perf/pmu-events/pmu-events.h
|
||||
@@ -18,6 +18,7 @@ struct pmu_event {
|
||||
const char *metric_name;
|
||||
const char *metric_group;
|
||||
const char *deprecated;
|
||||
+ const char *metric_constraint;
|
||||
};
|
||||
|
||||
/*
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,125 @@
|
||||
From a2ceca18eb350e991b34f4aac6512293e0a9d707 Mon Sep 17 00:00:00 2001
|
||||
From: Kan Liang <kan.liang@linux.intel.com>
|
||||
Date: Mon, 24 Feb 2020 13:59:21 -0800
|
||||
Subject: [PATCH 048/201] perf metricgroup: Factor out
|
||||
metricgroup__add_metric_weak_group()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit f742634ab47f59160a85ddc502418556b21953c2
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f742634ab47f59160a85ddc502418556b21953c2
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Factor out metricgroup__add_metric_weak_group() which add metrics into a
|
||||
weak group. The change can improve code readability. Because following
|
||||
patch will introduce a function which add standalone metrics.
|
||||
|
||||
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/1582581564-184429-3-git-send-email-kan.liang@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 57 ++++++++++++++++++++---------------
|
||||
1 file changed, 33 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 9f6b0b0f7b59..8951c6f6593b 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -420,13 +420,42 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
|
||||
strlist__delete(metriclist);
|
||||
}
|
||||
|
||||
+static void metricgroup__add_metric_weak_group(struct strbuf *events,
|
||||
+ const char **ids,
|
||||
+ int idnum)
|
||||
+{
|
||||
+ bool no_group = false;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < idnum; i++) {
|
||||
+ pr_debug("found event %s\n", ids[i]);
|
||||
+ /*
|
||||
+ * Duration time maps to a software event and can make
|
||||
+ * groups not count. Always use it outside a
|
||||
+ * group.
|
||||
+ */
|
||||
+ if (!strcmp(ids[i], "duration_time")) {
|
||||
+ if (i > 0)
|
||||
+ strbuf_addf(events, "}:W,");
|
||||
+ strbuf_addf(events, "duration_time");
|
||||
+ no_group = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ strbuf_addf(events, "%s%s",
|
||||
+ i == 0 || no_group ? "{" : ",",
|
||||
+ ids[i]);
|
||||
+ no_group = false;
|
||||
+ }
|
||||
+ if (!no_group)
|
||||
+ strbuf_addf(events, "}:W");
|
||||
+}
|
||||
+
|
||||
static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
struct list_head *group_list)
|
||||
{
|
||||
struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
struct pmu_event *pe;
|
||||
- int ret = -EINVAL;
|
||||
- int i, j;
|
||||
+ int i, ret = -EINVAL;
|
||||
|
||||
if (!map)
|
||||
return 0;
|
||||
@@ -443,7 +472,6 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
const char **ids;
|
||||
int idnum;
|
||||
struct egroup *eg;
|
||||
- bool no_group = false;
|
||||
|
||||
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
|
||||
|
||||
@@ -452,27 +480,8 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
continue;
|
||||
if (events->len > 0)
|
||||
strbuf_addf(events, ",");
|
||||
- for (j = 0; j < idnum; j++) {
|
||||
- pr_debug("found event %s\n", ids[j]);
|
||||
- /*
|
||||
- * Duration time maps to a software event and can make
|
||||
- * groups not count. Always use it outside a
|
||||
- * group.
|
||||
- */
|
||||
- if (!strcmp(ids[j], "duration_time")) {
|
||||
- if (j > 0)
|
||||
- strbuf_addf(events, "}:W,");
|
||||
- strbuf_addf(events, "duration_time");
|
||||
- no_group = true;
|
||||
- continue;
|
||||
- }
|
||||
- strbuf_addf(events, "%s%s",
|
||||
- j == 0 || no_group ? "{" : ",",
|
||||
- ids[j]);
|
||||
- no_group = false;
|
||||
- }
|
||||
- if (!no_group)
|
||||
- strbuf_addf(events, "}:W");
|
||||
+
|
||||
+ metricgroup__add_metric_weak_group(events, ids, idnum);
|
||||
|
||||
eg = malloc(sizeof(struct egroup));
|
||||
if (!eg) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,112 @@
|
||||
From 88ef54c8b0a53893de4781bc27fd92b930d5670b Mon Sep 17 00:00:00 2001
|
||||
From: Kan Liang <kan.liang@linux.intel.com>
|
||||
Date: Mon, 24 Feb 2020 13:59:22 -0800
|
||||
Subject: [PATCH 049/201] perf util: Factor out sysctl__nmi_watchdog_enabled()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 2a14c1bf017f48a17c8c0ba26a22625363e77cc7
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2a14c1bf017f48a17c8c0ba26a22625363e77cc7
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The NMI watchdog status is required for metric group constraint
|
||||
examination. Factor out sysctl__nmi_watchdog_enabled() to retrieve the
|
||||
NMI watchdog status.
|
||||
|
||||
Users may count more than one metric group each time. If so, the NMI
|
||||
watchdog status may be retrieved several times. To reduce the overhead,
|
||||
cache the NMI watchdog status.
|
||||
|
||||
Replace the NMI watchdog status checking in print_footer() by
|
||||
sysctl__nmi_watchdog_enabled().
|
||||
|
||||
Suggested-by: Andi Kleen <ak@linux.intel.com>
|
||||
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/1582581564-184429-4-git-send-email-kan.liang@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/builtin-stat.c | 5 +----
|
||||
tools/perf/util/util.c | 18 ++++++++++++++++++
|
||||
tools/perf/util/util.h | 2 ++
|
||||
3 files changed, 21 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index c96c0715171f..0d8943ead576 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -1800,7 +1800,6 @@ static void print_footer(struct perf_stat_config *config)
|
||||
{
|
||||
double avg = avg_stats(&walltime_nsecs_stats) / NSEC_PER_SEC;
|
||||
FILE *output = config->output;
|
||||
- int n;
|
||||
|
||||
if (!null_run)
|
||||
fprintf(output, "\n");
|
||||
@@ -1834,9 +1833,7 @@ static void print_footer(struct perf_stat_config *config)
|
||||
}
|
||||
fprintf(output, "\n\n");
|
||||
|
||||
- if (print_free_counters_hint &&
|
||||
- sysctl__read_int("kernel/nmi_watchdog", &n) >= 0 &&
|
||||
- n > 0)
|
||||
+ if (print_free_counters_hint && sysctl__nmi_watchdog_enabled())
|
||||
fprintf(output,
|
||||
"Some events weren't counted. Try disabling the NMI watchdog:\n"
|
||||
" echo 0 > /proc/sys/kernel/nmi_watchdog\n"
|
||||
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
|
||||
index eac5b858a371..935e2be276d5 100644
|
||||
--- a/tools/perf/util/util.c
|
||||
+++ b/tools/perf/util/util.c
|
||||
@@ -75,6 +75,24 @@ int sysctl__max_stack(void)
|
||||
return sysctl_perf_event_max_stack;
|
||||
}
|
||||
|
||||
+bool sysctl__nmi_watchdog_enabled(void)
|
||||
+{
|
||||
+ static bool cached;
|
||||
+ static bool nmi_watchdog;
|
||||
+ int value;
|
||||
+
|
||||
+ if (cached)
|
||||
+ return nmi_watchdog;
|
||||
+
|
||||
+ if (sysctl__read_int("kernel/nmi_watchdog", &value) < 0)
|
||||
+ return false;
|
||||
+
|
||||
+ nmi_watchdog = (value > 0) ? true : false;
|
||||
+ cached = true;
|
||||
+
|
||||
+ return nmi_watchdog;
|
||||
+}
|
||||
+
|
||||
bool test_attr__enabled;
|
||||
|
||||
bool perf_host = true;
|
||||
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
|
||||
index 2efec9e77753..bd39aad17eea 100644
|
||||
--- a/tools/perf/util/util.h
|
||||
+++ b/tools/perf/util/util.h
|
||||
@@ -47,6 +47,8 @@ int __pure cacheline_size(void);
|
||||
|
||||
int sysctl__max_stack(void);
|
||||
|
||||
+bool sysctl__nmi_watchdog_enabled(void);
|
||||
+
|
||||
int fetch_kernel_version(unsigned int *puint,
|
||||
char *str, size_t str_sz);
|
||||
#define KVER_VERSION(x) (((x) >> 16) & 0xff)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
138
patches/0167-perf-metricgroup-Support-metric-constraint.patch
Normal file
138
patches/0167-perf-metricgroup-Support-metric-constraint.patch
Normal file
@ -0,0 +1,138 @@
|
||||
From f7fceacb6e8e14742426d7eda0cb9b0f09f5b312 Mon Sep 17 00:00:00 2001
|
||||
From: Kan Liang <kan.liang@linux.intel.com>
|
||||
Date: Mon, 24 Feb 2020 13:59:23 -0800
|
||||
Subject: [PATCH 050/201] perf metricgroup: Support metric constraint
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit ab483d8bc8acb83f0103bc38ef8f2c27d98ffd1b
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ab483d8bc8acb83f0103bc38ef8f2c27d98ffd1b
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Some metric groups have metric constraints. A metric group can be
|
||||
scheduled as a group only when some constraints are applied. For
|
||||
example, Page_Walks_Utilization has a metric constraint,
|
||||
"NO_NMI_WATCHDOG".
|
||||
|
||||
When NMI watchdog is disabled, the metric group can be scheduled as a
|
||||
group. Otherwise, splitting the metric group into standalone metrics.
|
||||
|
||||
Add a new function, metricgroup__has_constraint(), to check whether all
|
||||
constraints are applied. If not, splitting the metric group into
|
||||
standalone metrics.
|
||||
|
||||
Currently, only one constraint, "NO_NMI_WATCHDOG", is checked. Print a
|
||||
warning for the metric group with the constraint, when NMI WATCHDOG is
|
||||
enabled.
|
||||
|
||||
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/1582581564-184429-5-git-send-email-kan.liang@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 54 ++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 53 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 8951c6f6593b..4baa9f2040ec 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <subcmd/parse-options.h>
|
||||
+#include <api/fs/fs.h>
|
||||
+#include "util.h"
|
||||
|
||||
struct metric_event *metricgroup__lookup(struct rblist *metric_events,
|
||||
struct perf_evsel *evsel,
|
||||
@@ -450,6 +452,49 @@ static void metricgroup__add_metric_weak_group(struct strbuf *events,
|
||||
strbuf_addf(events, "}:W");
|
||||
}
|
||||
|
||||
+static void metricgroup__add_metric_non_group(struct strbuf *events,
|
||||
+ const char **ids,
|
||||
+ int idnum)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < idnum; i++)
|
||||
+ strbuf_addf(events, ",%s", ids[i]);
|
||||
+}
|
||||
+
|
||||
+static void metricgroup___watchdog_constraint_hint(const char *name, bool foot)
|
||||
+{
|
||||
+ static bool violate_nmi_constraint;
|
||||
+
|
||||
+ if (!foot) {
|
||||
+ pr_warning("Splitting metric group %s into standalone metrics.\n", name);
|
||||
+ violate_nmi_constraint = true;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!violate_nmi_constraint)
|
||||
+ return;
|
||||
+
|
||||
+ pr_warning("Try disabling the NMI watchdog to comply NO_NMI_WATCHDOG metric constraint:\n"
|
||||
+ " echo 0 > /proc/sys/kernel/nmi_watchdog\n"
|
||||
+ " perf stat ...\n"
|
||||
+ " echo 1 > /proc/sys/kernel/nmi_watchdog\n");
|
||||
+}
|
||||
+
|
||||
+static bool metricgroup__has_constraint(struct pmu_event *pe)
|
||||
+{
|
||||
+ if (!pe->metric_constraint)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!strcmp(pe->metric_constraint, "NO_NMI_WATCHDOG") &&
|
||||
+ sysctl__nmi_watchdog_enabled()) {
|
||||
+ metricgroup___watchdog_constraint_hint(pe->metric_name, false);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
struct list_head *group_list)
|
||||
{
|
||||
@@ -481,7 +526,10 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
if (events->len > 0)
|
||||
strbuf_addf(events, ",");
|
||||
|
||||
- metricgroup__add_metric_weak_group(events, ids, idnum);
|
||||
+ if (metricgroup__has_constraint(pe))
|
||||
+ metricgroup__add_metric_non_group(events, ids, idnum);
|
||||
+ else
|
||||
+ metricgroup__add_metric_weak_group(events, ids, idnum);
|
||||
|
||||
eg = malloc(sizeof(struct egroup));
|
||||
if (!eg) {
|
||||
@@ -523,6 +571,10 @@ static int metricgroup__add_metric_list(const char *list, struct strbuf *events,
|
||||
}
|
||||
}
|
||||
free(nlist);
|
||||
+
|
||||
+ if (!ret)
|
||||
+ metricgroup___watchdog_constraint_hint(NULL, true);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,187 @@
|
||||
From 6a06ffa3cbe8297a580a72f5b24c6720adeb87b9 Mon Sep 17 00:00:00 2001
|
||||
From: Kan Liang <kan.liang@linux.intel.com>
|
||||
Date: Mon, 24 Feb 2020 13:59:24 -0800
|
||||
Subject: [PATCH 051/201] perf vendor events intel: Add NO_NMI_WATCHDOG metric
|
||||
constraint
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit b95fcd2c1c25bd14f55d5d6ab268b3ab00b8a774
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b95fcd2c1c25bd14f55d5d6ab268b3ab00b8a774
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add NO_NMI_WATCHDOG metric constraint to Page_Walks_Utilization for Sky Lake
|
||||
and Cascade Lake.
|
||||
|
||||
Committer testing:
|
||||
|
||||
On a Lenovo T480S, Intel(R) Core(TM) i7-8650U Kaby Lake, that looking at x86's
|
||||
mapfile.csv file is a:
|
||||
|
||||
$ grep -w skylake tools/perf/pmu-events/arch/x86/mapfile.csv
|
||||
GenuineIntel-6-[4589]E,v24,skylake,core
|
||||
$
|
||||
|
||||
So uses the constraint added in this patch in this file:
|
||||
|
||||
tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json
|
||||
|
||||
Before:
|
||||
|
||||
# perf stat -a -M Page_Walks_Utilization sleep 2
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
<not counted> itlb_misses.walk_pending (0.00%)
|
||||
<not counted> dtlb_load_misses.walk_pending (0.00%)
|
||||
<not counted> dtlb_store_misses.walk_pending (0.00%)
|
||||
<not counted> ept.walk_pending (0.00%)
|
||||
<not counted> cycles (0.00%)
|
||||
|
||||
2.001750514 seconds time elapsed
|
||||
|
||||
Some events weren't counted. Try disabling the NMI watchdog:
|
||||
echo 0 > /proc/sys/kernel/nmi_watchdog
|
||||
perf stat ...
|
||||
echo 1 > /proc/sys/kernel/nmi_watchdog
|
||||
The events in group usually have to be from the same PMU. Try reorganizing the group.
|
||||
#
|
||||
|
||||
After:
|
||||
|
||||
# perf stat -a -M Page_Walks_Utilization sleep 2
|
||||
Splitting metric group Page_Walks_Utilization into standalone metrics.
|
||||
Try disabling the NMI watchdog to comply NO_NMI_WATCHDOG metric constraint:
|
||||
echo 0 > /proc/sys/kernel/nmi_watchdog
|
||||
perf stat ...
|
||||
echo 1 > /proc/sys/kernel/nmi_watchdog
|
||||
,
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
36,883,102 itlb_misses.walk_pending # 0.1 Page_Walks_Utilization (79.99%)
|
||||
123,104,146 dtlb_load_misses.walk_pending (80.02%)
|
||||
13,720,795 dtlb_store_misses.walk_pending (79.99%)
|
||||
0 ept.walk_pending (79.99%)
|
||||
1,519,948,400 cycles (80.01%)
|
||||
|
||||
2.002170780 seconds time elapsed
|
||||
|
||||
#
|
||||
|
||||
Before and after, if we disable the nmi_watchdog we get:
|
||||
|
||||
# echo 0 > /proc/sys/kernel/nmi_watchdog
|
||||
# perf stat -a -M Page_Walks_Utilization sleep 2
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
33,721,658 itlb_misses.walk_pending # 0.1 Page_Walks_Utilization
|
||||
84,070,996 dtlb_load_misses.walk_pending
|
||||
9,816,071 dtlb_store_misses.walk_pending
|
||||
0 ept.walk_pending
|
||||
704,920,899 cycles
|
||||
|
||||
2.002331670 seconds time elapsed
|
||||
|
||||
#
|
||||
|
||||
More information about the metric expressions:
|
||||
|
||||
# perf stat -v -a -M Page_Walks_Utilization sleep 2
|
||||
Using CPUID GenuineIntel-6-8E-A
|
||||
metric expr ( itlb_misses.walk_pending + dtlb_load_misses.walk_pending + dtlb_store_misses.walk_pending + ept.walk_pending ) / ( 2 * cycles ) for Page_Walks_Utilization
|
||||
found event itlb_misses.walk_pending
|
||||
found event dtlb_load_misses.walk_pending
|
||||
found event dtlb_store_misses.walk_pending
|
||||
found event ept.walk_pending
|
||||
found event cycles
|
||||
adding {itlb_misses.walk_pending,dtlb_load_misses.walk_pending,dtlb_store_misses.walk_pending,ept.walk_pending,cycles}:W
|
||||
-> cpu/umask=0x10,(null)=0x186a3,event=0x85/
|
||||
-> cpu/umask=0x10,(null)=0x1e8483,event=0x8/
|
||||
-> cpu/umask=0x10,(null)=0x1e8483,event=0x49/
|
||||
-> cpu/umask=0x10,(null)=0x1e8483,event=0x4f/
|
||||
itlb_misses.walk_pending: 8085772 16010162799 16010162799
|
||||
dtlb_load_misses.walk_pending: 28134579 16010162799 16010162799
|
||||
dtlb_store_misses.walk_pending: 7276535 16010162799 16010162799
|
||||
ept.walk_pending: 2 16010162799 16010162799
|
||||
cycles: 315140605 16010162799 16010162799
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
8,085,772 itlb_misses.walk_pending # 0.1 Page_Walks_Utilization
|
||||
28,134,579 dtlb_load_misses.walk_pending
|
||||
7,276,535 dtlb_store_misses.walk_pending
|
||||
2 ept.walk_pending
|
||||
315,140,605 cycles
|
||||
|
||||
2.002333181 seconds time elapsed
|
||||
|
||||
#
|
||||
|
||||
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/1582581564-184429-6-git-send-email-kan.liang@linux.intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json | 3 ++-
|
||||
tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json | 3 ++-
|
||||
tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json | 3 ++-
|
||||
3 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json b/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json
|
||||
index 36c903faed0b..13a703c91db8 100644
|
||||
--- a/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json
|
||||
+++ b/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json
|
||||
@@ -87,7 +87,8 @@
|
||||
"BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses",
|
||||
"MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * (( CPU_CLK_UNHALTED.THREAD_ANY / 2 ) if #SMT_on else cycles) )",
|
||||
"MetricGroup": "TLB",
|
||||
- "MetricName": "Page_Walks_Utilization"
|
||||
+ "MetricName": "Page_Walks_Utilization",
|
||||
+ "MetricConstraint": "NO_NMI_WATCHDOG"
|
||||
},
|
||||
{
|
||||
"BriefDescription": "Average CPU Utilization",
|
||||
diff --git a/tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json b/tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json
|
||||
index 71e9737f4614..91a2422d2ffc 100644
|
||||
--- a/tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json
|
||||
+++ b/tools/perf/pmu-events/arch/x86/skylake/skl-metrics.json
|
||||
@@ -87,7 +87,8 @@
|
||||
"BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses",
|
||||
"MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * (( CPU_CLK_UNHALTED.THREAD_ANY / 2 ) if #SMT_on else cycles) )",
|
||||
"MetricGroup": "TLB",
|
||||
- "MetricName": "Page_Walks_Utilization"
|
||||
+ "MetricName": "Page_Walks_Utilization",
|
||||
+ "MetricConstraint": "NO_NMI_WATCHDOG"
|
||||
},
|
||||
{
|
||||
"BriefDescription": "Average CPU Utilization",
|
||||
diff --git a/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json b/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json
|
||||
index 71e9737f4614..91a2422d2ffc 100644
|
||||
--- a/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json
|
||||
+++ b/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json
|
||||
@@ -87,7 +87,8 @@
|
||||
"BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses",
|
||||
"MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * (( CPU_CLK_UNHALTED.THREAD_ANY / 2 ) if #SMT_on else cycles) )",
|
||||
"MetricGroup": "TLB",
|
||||
- "MetricName": "Page_Walks_Utilization"
|
||||
+ "MetricName": "Page_Walks_Utilization",
|
||||
+ "MetricConstraint": "NO_NMI_WATCHDOG"
|
||||
},
|
||||
{
|
||||
"BriefDescription": "Average CPU Utilization",
|
||||
--
|
||||
2.27.0
|
||||
|
||||
108
patches/0169-perf-expr-Add-expr.c-object.patch
Normal file
108
patches/0169-perf-expr-Add-expr.c-object.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 394191d5b78ee88a058463b156c75919c8969005 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Fri, 28 Feb 2020 10:36:12 +0100
|
||||
Subject: [PATCH 052/201] perf expr: Add expr.c object
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 576a65b6974ddc830a89b6feb6823bd6b5914bde
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=576a65b6974ddc830a89b6feb6823bd6b5914bde
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add generic expr code into new expr.c object.
|
||||
|
||||
The expr.c object will be mainly used in following change that will get
|
||||
rid of the manual flex code,
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Reviewed-by: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200228093616.67125-2-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/Build
|
||||
---
|
||||
tools/perf/util/Build | 1 +
|
||||
tools/perf/util/expr.c | 19 +++++++++++++++++++
|
||||
tools/perf/util/expr.y | 15 ---------------
|
||||
3 files changed, 20 insertions(+), 15 deletions(-)
|
||||
create mode 100644 tools/perf/util/expr.c
|
||||
|
||||
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
|
||||
index de3b99f927ac..a7d2bb7edb2d 100644
|
||||
--- a/tools/perf/util/Build
|
||||
+++ b/tools/perf/util/Build
|
||||
@@ -106,6 +106,7 @@ libperf-y += drv_configs.o
|
||||
libperf-y += units.o
|
||||
libperf-y += time-utils.o
|
||||
libperf-y += expr-bison.o
|
||||
+libperf-y += expr.o
|
||||
libperf-y += branch.o
|
||||
libperf-y += mem2node.o
|
||||
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
new file mode 100644
|
||||
index 000000000000..816b23b2068a
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -0,0 +1,19 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+#include <assert.h>
|
||||
+#include "expr.h"
|
||||
+
|
||||
+/* 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;
|
||||
+}
|
||||
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
|
||||
index e7bd19c384ae..5f75e27d1bd8 100644
|
||||
--- a/tools/perf/util/expr.y
|
||||
+++ b/tools/perf/util/expr.y
|
||||
@@ -167,21 +167,6 @@ static int expr__lex(YYSTYPE *res, const char **pp)
|
||||
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;
|
||||
-}
|
||||
-
|
||||
static bool already_seen(const char *val, const char *one, const char **other,
|
||||
int num_other)
|
||||
{
|
||||
--
|
||||
2.27.0
|
||||
|
||||
562
patches/0170-perf-expr-Move-expr-lexer-to-flex.patch
Normal file
562
patches/0170-perf-expr-Move-expr-lexer-to-flex.patch
Normal file
@ -0,0 +1,562 @@
|
||||
From b0eeeeadefa2356dd425e2fbd721688688bc4f96 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Fri, 28 Feb 2020 10:36:13 +0100
|
||||
Subject: [PATCH 053/201] perf expr: Move expr lexer to flex
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 26226a97724d1671d553b8eb0cd95b0a5557cfb2
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=26226a97724d1671d553b8eb0cd95b0a5557cfb2
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Adding expr flex code instead of the manual parser code. So it's easily
|
||||
extensible in upcoming changes.
|
||||
|
||||
The new flex code is in flex.l object and gets compiled like all the
|
||||
other flexers we use. It's defined as flex reentrant parser.
|
||||
|
||||
It's used by both expr__parse and expr__find_other interfaces by
|
||||
separating the starting point.
|
||||
|
||||
There's no intended change of functionality ;-) the test expr is
|
||||
passing.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Reviewed-by: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200228093616.67125-3-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/Build
|
||||
---
|
||||
tools/perf/util/Build | 10 ++-
|
||||
tools/perf/util/expr.c | 93 +++++++++++++++++++++++
|
||||
tools/perf/util/expr.h | 2 -
|
||||
tools/perf/util/expr.l | 114 +++++++++++++++++++++++++++
|
||||
tools/perf/util/expr.y | 169 ++++++++---------------------------------
|
||||
5 files changed, 247 insertions(+), 141 deletions(-)
|
||||
create mode 100644 tools/perf/util/expr.l
|
||||
|
||||
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
|
||||
index a7d2bb7edb2d..543c73313fda 100644
|
||||
--- a/tools/perf/util/Build
|
||||
+++ b/tools/perf/util/Build
|
||||
@@ -105,6 +105,7 @@ libperf-y += vsprintf.o
|
||||
libperf-y += drv_configs.o
|
||||
libperf-y += units.o
|
||||
libperf-y += time-utils.o
|
||||
+libperf-y += expr-flex.o
|
||||
libperf-y += expr-bison.o
|
||||
libperf-y += expr.o
|
||||
libperf-y += branch.o
|
||||
@@ -171,9 +172,13 @@ $(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-flex.c: util/expr.l $(OUTPUT)util/expr-bison.c
|
||||
+ $(call rule_mkdir)
|
||||
+ $(Q)$(call echo-cmd,flex)$(FLEX) -o $@ --header-file=$(OUTPUT)util/expr-flex.h $(PARSER_DEBUG_FLEX) util/expr.l
|
||||
+
|
||||
$(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__
|
||||
+ $(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)
|
||||
@@ -185,12 +190,14 @@ $(OUTPUT)util/pmu-bison.c: util/pmu.y
|
||||
|
||||
CFLAGS_parse-events-flex.o += -w
|
||||
CFLAGS_pmu-flex.o += -w
|
||||
+CFLAGS_expr-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
|
||||
+$(OUTPUT)util/expr.o: $(OUTPUT)util/expr-flex.c $(OUTPUT)util/expr-bison.c
|
||||
|
||||
CFLAGS_bitmap.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
|
||||
CFLAGS_find_bit.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
|
||||
@@ -198,6 +205,7 @@ CFLAGS_rbtree.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ET
|
||||
CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
|
||||
CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
|
||||
CFLAGS_parse-events.o += -Wno-redundant-decls
|
||||
+CFLAGS_expr.o += -Wno-redundant-decls
|
||||
CFLAGS_header.o += -include $(OUTPUT)PERF-VERSION-FILE
|
||||
|
||||
$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
index 816b23b2068a..b39fd39f10ec 100644
|
||||
--- a/tools/perf/util/expr.c
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -1,6 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
+#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "expr.h"
|
||||
+#include "expr-bison.h"
|
||||
+#define YY_EXTRA_TYPE int
|
||||
+#include "expr-flex.h"
|
||||
+
|
||||
+#ifdef PARSER_DEBUG
|
||||
+extern int expr_debug;
|
||||
+#endif
|
||||
|
||||
/* Caller must make sure id is allocated */
|
||||
void expr__add_id(struct parse_ctx *ctx, const char *name, double val)
|
||||
@@ -17,3 +25,88 @@ void expr__ctx_init(struct parse_ctx *ctx)
|
||||
{
|
||||
ctx->num_ids = 0;
|
||||
}
|
||||
+
|
||||
+static int
|
||||
+__expr__parse(double *val, struct parse_ctx *ctx, const char *expr,
|
||||
+ int start)
|
||||
+{
|
||||
+ YY_BUFFER_STATE buffer;
|
||||
+ void *scanner;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = expr_lex_init_extra(start, &scanner);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ buffer = expr__scan_string(expr, scanner);
|
||||
+
|
||||
+#ifdef PARSER_DEBUG
|
||||
+ expr_debug = 1;
|
||||
+#endif
|
||||
+
|
||||
+ ret = expr_parse(val, ctx, scanner);
|
||||
+
|
||||
+ expr__flush_buffer(buffer, scanner);
|
||||
+ expr__delete_buffer(buffer, scanner);
|
||||
+ expr_lex_destroy(scanner);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int expr__parse(double *final_val, struct parse_ctx *ctx, const char **pp)
|
||||
+{
|
||||
+ return __expr__parse(final_val, ctx, *pp, EXPR_PARSE);
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+already_seen(const char *val, const char *one, const char **other,
|
||||
+ int num_other)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (one && !strcasecmp(one, val))
|
||||
+ return true;
|
||||
+ for (i = 0; i < num_other; i++)
|
||||
+ if (!strcasecmp(other[i], val))
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+int expr__find_other(const char *p, const char *one, const char ***other,
|
||||
+ int *num_other)
|
||||
+{
|
||||
+ int err, i = 0, j = 0;
|
||||
+ struct parse_ctx ctx;
|
||||
+
|
||||
+ expr__ctx_init(&ctx);
|
||||
+ err = __expr__parse(NULL, &ctx, p, EXPR_OTHER);
|
||||
+ if (err)
|
||||
+ return -1;
|
||||
+
|
||||
+ *other = malloc((ctx.num_ids + 1) * sizeof(char *));
|
||||
+ if (!*other)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0, j = 0; i < ctx.num_ids; i++) {
|
||||
+ const char *str = ctx.ids[i].name;
|
||||
+
|
||||
+ if (already_seen(str, one, *other, j))
|
||||
+ continue;
|
||||
+
|
||||
+ str = strdup(str);
|
||||
+ if (!str)
|
||||
+ goto out;
|
||||
+ (*other)[j++] = str;
|
||||
+ }
|
||||
+ (*other)[j] = NULL;
|
||||
+
|
||||
+out:
|
||||
+ if (i != ctx.num_ids) {
|
||||
+ while (--j)
|
||||
+ free((char *) (*other)[i]);
|
||||
+ free(*other);
|
||||
+ err = -1;
|
||||
+ }
|
||||
+
|
||||
+ *num_other = j;
|
||||
+ return err;
|
||||
+}
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index 046160831f90..9332796e6649 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -17,9 +17,7 @@ struct parse_ctx {
|
||||
|
||||
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);
|
||||
|
||||
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
|
||||
new file mode 100644
|
||||
index 000000000000..1928f2a3dddc
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/util/expr.l
|
||||
@@ -0,0 +1,114 @@
|
||||
+%option prefix="expr_"
|
||||
+%option reentrant
|
||||
+%option bison-bridge
|
||||
+
|
||||
+%{
|
||||
+#include <linux/compiler.h>
|
||||
+#include "expr.h"
|
||||
+#include "expr-bison.h"
|
||||
+
|
||||
+char *expr_get_text(yyscan_t yyscanner);
|
||||
+YYSTYPE *expr_get_lval(yyscan_t yyscanner);
|
||||
+
|
||||
+static int __value(YYSTYPE *yylval, char *str, int base, int token)
|
||||
+{
|
||||
+ u64 num;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ num = strtoull(str, NULL, base);
|
||||
+ if (errno)
|
||||
+ return EXPR_ERROR;
|
||||
+
|
||||
+ yylval->num = num;
|
||||
+ return token;
|
||||
+}
|
||||
+
|
||||
+static int value(yyscan_t scanner, int base)
|
||||
+{
|
||||
+ YYSTYPE *yylval = expr_get_lval(scanner);
|
||||
+ char *text = expr_get_text(scanner);
|
||||
+
|
||||
+ return __value(yylval, text, base, NUMBER);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Allow @ instead of / to be able to specify pmu/event/ without
|
||||
+ * conflicts with normal division.
|
||||
+ */
|
||||
+static char *normalize(char *str)
|
||||
+{
|
||||
+ char *ret = str;
|
||||
+ char *dst = str;
|
||||
+
|
||||
+ while (*str) {
|
||||
+ if (*str == '@')
|
||||
+ *dst++ = '/';
|
||||
+ else if (*str == '\\')
|
||||
+ *dst++ = *++str;
|
||||
+ else
|
||||
+ *dst++ = *str;
|
||||
+ str++;
|
||||
+ }
|
||||
+
|
||||
+ *dst = 0x0;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int str(yyscan_t scanner, int token)
|
||||
+{
|
||||
+ YYSTYPE *yylval = expr_get_lval(scanner);
|
||||
+ char *text = expr_get_text(scanner);
|
||||
+
|
||||
+ yylval->str = normalize(strdup(text));
|
||||
+ if (!yylval->str)
|
||||
+ return EXPR_ERROR;
|
||||
+
|
||||
+ yylval->str = normalize(yylval->str);
|
||||
+ return token;
|
||||
+}
|
||||
+%}
|
||||
+
|
||||
+number [0-9]+
|
||||
+
|
||||
+sch [-,=]
|
||||
+spec \\{sch}
|
||||
+sym [0-9a-zA-Z_\.:@]+
|
||||
+symbol {spec}*{sym}*{spec}*{sym}*
|
||||
+
|
||||
+%%
|
||||
+ {
|
||||
+ int start_token;
|
||||
+
|
||||
+ start_token = parse_events_get_extra(yyscanner);
|
||||
+
|
||||
+ if (start_token) {
|
||||
+ parse_events_set_extra(NULL, yyscanner);
|
||||
+ return start_token;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+max { return MAX; }
|
||||
+min { return MIN; }
|
||||
+if { return IF; }
|
||||
+else { return ELSE; }
|
||||
+#smt_on { return SMT_ON; }
|
||||
+{number} { return value(yyscanner, 10); }
|
||||
+{symbol} { return str(yyscanner, ID); }
|
||||
+"|" { return '|'; }
|
||||
+"^" { return '^'; }
|
||||
+"&" { return '&'; }
|
||||
+"-" { return '-'; }
|
||||
+"+" { return '+'; }
|
||||
+"*" { return '*'; }
|
||||
+"/" { return '/'; }
|
||||
+"%" { return '%'; }
|
||||
+"(" { return '('; }
|
||||
+")" { return ')'; }
|
||||
+"," { return ','; }
|
||||
+. { }
|
||||
+%%
|
||||
+
|
||||
+int expr_wrap(void *scanner __maybe_unused)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
|
||||
index 5f75e27d1bd8..c020d794ccc3 100644
|
||||
--- a/tools/perf/util/expr.y
|
||||
+++ b/tools/perf/util/expr.y
|
||||
@@ -1,5 +1,7 @@
|
||||
/* Simple expression parser */
|
||||
%{
|
||||
+#define YYDEBUG 1
|
||||
+#include <stdio.h>
|
||||
#include "util.h"
|
||||
#include "util/debug.h"
|
||||
#define IN_EXPR_Y 1
|
||||
@@ -7,23 +9,23 @@
|
||||
#include "smt.h"
|
||||
#include <string.h>
|
||||
|
||||
-#define MAXIDLEN 256
|
||||
%}
|
||||
|
||||
%define api.pure full
|
||||
|
||||
%parse-param { double *final_val }
|
||||
%parse-param { struct parse_ctx *ctx }
|
||||
-%parse-param { const char **pp }
|
||||
-%lex-param { const char **pp }
|
||||
+%parse-param {void *scanner}
|
||||
+%lex-param {void* scanner}
|
||||
|
||||
%union {
|
||||
- double num;
|
||||
- char id[MAXIDLEN+1];
|
||||
+ double num;
|
||||
+ char *str;
|
||||
}
|
||||
|
||||
+%token EXPR_PARSE EXPR_OTHER EXPR_ERROR
|
||||
%token <num> NUMBER
|
||||
-%token <id> ID
|
||||
+%token <str> ID
|
||||
%token MIN MAX IF ELSE SMT_ON
|
||||
%left MIN MAX IF
|
||||
%left '|'
|
||||
@@ -35,11 +37,9 @@
|
||||
%type <num> expr if_expr
|
||||
|
||||
%{
|
||||
-static int expr__lex(YYSTYPE *res, const char **pp);
|
||||
-
|
||||
-static void expr__error(double *final_val __maybe_unused,
|
||||
+static void expr_error(double *final_val __maybe_unused,
|
||||
struct parse_ctx *ctx __maybe_unused,
|
||||
- const char **pp __maybe_unused,
|
||||
+ void *scanner,
|
||||
const char *s)
|
||||
{
|
||||
pr_debug("%s\n", s);
|
||||
@@ -61,6 +61,27 @@ static int lookup_id(struct parse_ctx *ctx, char *id, double *val)
|
||||
%}
|
||||
%%
|
||||
|
||||
+start:
|
||||
+EXPR_PARSE all_expr
|
||||
+|
|
||||
+EXPR_OTHER all_other
|
||||
+
|
||||
+all_other: all_other other
|
||||
+|
|
||||
+
|
||||
+other: ID
|
||||
+{
|
||||
+ if (ctx->num_ids + 1 >= EXPR_MAX_OTHER) {
|
||||
+ pr_err("failed: way too many variables");
|
||||
+ YYABORT;
|
||||
+ }
|
||||
+
|
||||
+ ctx->ids[ctx->num_ids++].name = $1;
|
||||
+}
|
||||
+|
|
||||
+MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')'
|
||||
+
|
||||
+
|
||||
all_expr: if_expr { *final_val = $1; }
|
||||
;
|
||||
|
||||
@@ -91,131 +112,3 @@ expr: NUMBER
|
||||
;
|
||||
|
||||
%%
|
||||
-
|
||||
-static int expr__symbol(YYSTYPE *res, const char *p, const char **pp)
|
||||
-{
|
||||
- char *dst = res->id;
|
||||
- const char *s = p;
|
||||
-
|
||||
- if (*p == '#')
|
||||
- *dst++ = *p++;
|
||||
-
|
||||
- while (isalnum(*p) || *p == '_' || *p == '.' || *p == ':' || *p == '@' || *p == '\\') {
|
||||
- if (p - s >= MAXIDLEN)
|
||||
- return -1;
|
||||
- /*
|
||||
- * Allow @ instead of / to be able to specify pmu/event/ without
|
||||
- * conflicts with normal division.
|
||||
- */
|
||||
- if (*p == '@')
|
||||
- *dst++ = '/';
|
||||
- else if (*p == '\\')
|
||||
- *dst++ = *++p;
|
||||
- else
|
||||
- *dst++ = *p;
|
||||
- p++;
|
||||
- }
|
||||
- *dst = 0;
|
||||
- *pp = p;
|
||||
- dst = res->id;
|
||||
- switch (dst[0]) {
|
||||
- case 'm':
|
||||
- if (!strcmp(dst, "min"))
|
||||
- return MIN;
|
||||
- if (!strcmp(dst, "max"))
|
||||
- return MAX;
|
||||
- break;
|
||||
- case 'i':
|
||||
- if (!strcmp(dst, "if"))
|
||||
- return IF;
|
||||
- break;
|
||||
- case 'e':
|
||||
- if (!strcmp(dst, "else"))
|
||||
- return ELSE;
|
||||
- break;
|
||||
- case '#':
|
||||
- if (!strcasecmp(dst, "#smt_on"))
|
||||
- return SMT_ON;
|
||||
- break;
|
||||
- }
|
||||
- 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 '#':
|
||||
- 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;
|
||||
-}
|
||||
-
|
||||
-static bool already_seen(const char *val, const char *one, const char **other,
|
||||
- int num_other)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- if (one && !strcasecmp(one, val))
|
||||
- return true;
|
||||
- for (i = 0; i < num_other; i++)
|
||||
- if (!strcasecmp(other[i], val))
|
||||
- return true;
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-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 && !already_seen(val.id, one, *other, num_other)) {
|
||||
- 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;
|
||||
-}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
From 1050f33c27e8ae8ce290d4d712a155054c3656c4 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Fri, 28 Feb 2020 10:36:14 +0100
|
||||
Subject: [PATCH 054/201] perf expr: Increase EXPR_MAX_OTHER to support metrics
|
||||
with more than 15 variables
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 58ca707636dc44c8803a098fb68129f64272f151
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=58ca707636dc44c8803a098fb68129f64272f151
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
We have metrics that define more than 15 variables, like
|
||||
Branch_Misprediction_Cost. Increasing the allowed variables count to 20.
|
||||
|
||||
As Andy pointed out, we can't go too high in here, because some of the
|
||||
code has O(n^2) complexity (already_seen) and we might want to do some
|
||||
other changes (like using hash tables) before increasing the maximum
|
||||
even more.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Reviewed-by: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200228093616.67125-4-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index 9332796e6649..df0a17df0cef 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -2,7 +2,7 @@
|
||||
#ifndef PARSE_CTX_H
|
||||
#define PARSE_CTX_H 1
|
||||
|
||||
-#define EXPR_MAX_OTHER 15
|
||||
+#define EXPR_MAX_OTHER 20
|
||||
#define MAX_PARSE_ID EXPR_MAX_OTHER
|
||||
|
||||
struct parse_id {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
From 767e415d346635928ad64ef12a1bbb8bf35d3192 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Fri, 28 Feb 2020 10:36:15 +0100
|
||||
Subject: [PATCH 055/201] perf expr: Straighten
|
||||
expr__parse()/expr__find_other() interface
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 0f9b1e124bb29719eb1572db74b7893bd616f938
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0f9b1e124bb29719eb1572db74b7893bd616f938
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Now that we have a flex parser we don't need to update the parsed string
|
||||
pointer, so the interface can just be passed the pointer to the
|
||||
expression instead of a pointer to pointer.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Reviewed-by: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200228093616.67125-5-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/expr.c | 6 +++---
|
||||
tools/perf/util/expr.c | 8 ++++----
|
||||
tools/perf/util/expr.h | 4 ++--
|
||||
tools/perf/util/stat-shadow.c | 4 +---
|
||||
4 files changed, 10 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
|
||||
index 9acc1e80b936..153977e91e78 100644
|
||||
--- a/tools/perf/tests/expr.c
|
||||
+++ b/tools/perf/tests/expr.c
|
||||
@@ -8,7 +8,7 @@ static int test(struct parse_ctx *ctx, const char *e, double val2)
|
||||
{
|
||||
double val;
|
||||
|
||||
- if (expr__parse(&val, ctx, &e))
|
||||
+ if (expr__parse(&val, ctx, e))
|
||||
TEST_ASSERT_VAL("parse test failed", 0);
|
||||
TEST_ASSERT_VAL("unexpected value", val == val2);
|
||||
return 0;
|
||||
@@ -42,11 +42,11 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
return ret;
|
||||
|
||||
p = "FOO/0";
|
||||
- ret = expr__parse(&val, &ctx, &p);
|
||||
+ ret = expr__parse(&val, &ctx, p);
|
||||
TEST_ASSERT_VAL("division by zero", ret == 1);
|
||||
|
||||
p = "BAR/";
|
||||
- ret = expr__parse(&val, &ctx, &p);
|
||||
+ ret = expr__parse(&val, &ctx, p);
|
||||
TEST_ASSERT_VAL("missing operand", ret == 1);
|
||||
|
||||
TEST_ASSERT_VAL("find other",
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
index b39fd39f10ec..45b25530db5b 100644
|
||||
--- a/tools/perf/util/expr.c
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -52,9 +52,9 @@ __expr__parse(double *val, struct parse_ctx *ctx, const char *expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int expr__parse(double *final_val, struct parse_ctx *ctx, const char **pp)
|
||||
+int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr)
|
||||
{
|
||||
- return __expr__parse(final_val, ctx, *pp, EXPR_PARSE);
|
||||
+ return __expr__parse(final_val, ctx, expr, EXPR_PARSE);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -71,14 +71,14 @@ already_seen(const char *val, const char *one, const char **other,
|
||||
return false;
|
||||
}
|
||||
|
||||
-int expr__find_other(const char *p, const char *one, const char ***other,
|
||||
+int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
int *num_other)
|
||||
{
|
||||
int err, i = 0, j = 0;
|
||||
struct parse_ctx ctx;
|
||||
|
||||
expr__ctx_init(&ctx);
|
||||
- err = __expr__parse(NULL, &ctx, p, EXPR_OTHER);
|
||||
+ err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER);
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index df0a17df0cef..9377538f4097 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -17,8 +17,8 @@ struct parse_ctx {
|
||||
|
||||
void expr__ctx_init(struct parse_ctx *ctx);
|
||||
void expr__add_id(struct parse_ctx *ctx, const char *id, double val);
|
||||
-int expr__parse(double *final_val, struct parse_ctx *ctx, const char **pp);
|
||||
-int expr__find_other(const char *p, const char *one, const char ***other,
|
||||
+int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr);
|
||||
+int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
int *num_other);
|
||||
|
||||
#endif
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index c9d92c1dac0e..4651e76dfd5e 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -777,9 +777,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
}
|
||||
|
||||
if (!metric_events[i]) {
|
||||
- const char *p = metric_expr;
|
||||
-
|
||||
- if (expr__parse(&ratio, &pctx, &p) == 0) {
|
||||
+ if (expr__parse(&ratio, &pctx, metric_expr) == 0) {
|
||||
char *unit;
|
||||
char metric_bf[64];
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From 118a571d1fc8498e12ed2f2eeac50774616a16b1 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Fri, 28 Feb 2020 10:36:16 +0100
|
||||
Subject: [PATCH 056/201] perf expr: Make expr__parse() return -1 on error
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit d942815a76463fa53b81d3d1c064f76bb3f80ead
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d942815a76463fa53b81d3d1c064f76bb3f80ead
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
To match the error value of the expr__find_other function, so all
|
||||
exported expr functions return the same values:
|
||||
0 on success, -1 on error.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Reviewed-by: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200228093616.67125-6-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/expr.c | 4 ++--
|
||||
tools/perf/util/expr.c | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
|
||||
index 153977e91e78..9fd4ba83fbe0 100644
|
||||
--- a/tools/perf/tests/expr.c
|
||||
+++ b/tools/perf/tests/expr.c
|
||||
@@ -43,11 +43,11 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
|
||||
p = "FOO/0";
|
||||
ret = expr__parse(&val, &ctx, p);
|
||||
- TEST_ASSERT_VAL("division by zero", ret == 1);
|
||||
+ 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("missing operand", ret == -1);
|
||||
|
||||
TEST_ASSERT_VAL("find other",
|
||||
expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", &other, &num_other) == 0);
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
index 45b25530db5b..fd192ddf93c1 100644
|
||||
--- a/tools/perf/util/expr.c
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -54,7 +54,7 @@ __expr__parse(double *val, struct parse_ctx *ctx, const char *expr,
|
||||
|
||||
int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr)
|
||||
{
|
||||
- return __expr__parse(final_val, ctx, expr, EXPR_PARSE);
|
||||
+ return __expr__parse(final_val, ctx, expr, EXPR_PARSE) ? -1 : 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From d7238f2e842192c64a8c45640aa092201b369937 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Tue, 12 May 2020 17:03:18 -0700
|
||||
Subject: [PATCH 057/201] perf expr: Fix memory leaks in metric bison
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 6365757894d5e7ada8a1d074a21fdaf2973dd5ae
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6365757894d5e7ada8a1d074a21fdaf2973dd5ae
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add a destructor for strings to reclaim memory in the event of errors.
|
||||
Free the ID given for a lookup, it was previously strdup-ed in the lex
|
||||
code.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Reviewed-by: Andi Kleen <ak@linux.intel.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200513000318.15166-1-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.y | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
|
||||
index c020d794ccc3..5b1b02f3fafa 100644
|
||||
--- a/tools/perf/util/expr.y
|
||||
+++ b/tools/perf/util/expr.y
|
||||
@@ -26,6 +26,7 @@
|
||||
%token EXPR_PARSE EXPR_OTHER EXPR_ERROR
|
||||
%token <num> NUMBER
|
||||
%token <str> ID
|
||||
+%destructor { free ($$); } <str>
|
||||
%token MIN MAX IF ELSE SMT_ON
|
||||
%left MIN MAX IF
|
||||
%left '|'
|
||||
@@ -93,8 +94,10 @@ if_expr:
|
||||
expr: NUMBER
|
||||
| ID { if (lookup_id(ctx, $1, &$$) < 0) {
|
||||
pr_debug("%s not found\n", $1);
|
||||
+ free($1);
|
||||
YYABORT;
|
||||
}
|
||||
+ free($1);
|
||||
}
|
||||
| expr '|' expr { $$ = (long)$1 | (long)$3; }
|
||||
| expr '&' expr { $$ = (long)$1 & (long)$3; }
|
||||
--
|
||||
2.27.0
|
||||
|
||||
52
patches/0175-perf-expr-Fix-copy-paste-mistake.patch
Normal file
52
patches/0175-perf-expr-Fix-copy-paste-mistake.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 5b9896ba53ce9227752c306b7fe2fa2b66513426 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Sun, 15 Mar 2020 16:56:09 +0100
|
||||
Subject: [PATCH 058/201] perf expr: Fix copy/paste mistake
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 59a08b4b3b1a9374adacd13cd7544c03e5582e0e
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=59a08b4b3b1a9374adacd13cd7544c03e5582e0e
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copy/paste leftover from recent refactor.
|
||||
|
||||
Fixes: 26226a97724d ("perf expr: Move expr lexer to flex")
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Link: http://lore.kernel.org/lkml/20200315155609.603948-1-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.l | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
|
||||
index 1928f2a3dddc..eaad29243c23 100644
|
||||
--- a/tools/perf/util/expr.l
|
||||
+++ b/tools/perf/util/expr.l
|
||||
@@ -79,10 +79,10 @@ symbol {spec}*{sym}*{spec}*{sym}*
|
||||
{
|
||||
int start_token;
|
||||
|
||||
- start_token = parse_events_get_extra(yyscanner);
|
||||
+ start_token = expr_get_extra(yyscanner);
|
||||
|
||||
if (start_token) {
|
||||
- parse_events_set_extra(NULL, yyscanner);
|
||||
+ expr_set_extra(NULL, yyscanner);
|
||||
return start_token;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,199 @@
|
||||
From be0b4351cde5abe0a3e15fa179848131aef5b4b9 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 2 Apr 2020 02:03:34 +0530
|
||||
Subject: [PATCH 059/201] perf expr: Add expr_ prefix for parse_ctx and
|
||||
parse_id
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit aecce63e2b98f28606b063949cca06facf215d6c
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=aecce63e2b98f28606b063949cca06facf215d6c
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Adding expr_ prefix for parse_ctx and parse_id, to straighten out the
|
||||
expr* namespace.
|
||||
|
||||
There's no functional change.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Anju T Sudhakar <anju@linux.vnet.ibm.com>
|
||||
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Joe Mario <jmario@redhat.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
|
||||
Cc: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Mackerras <paulus@ozlabs.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linuxppc-dev@lists.ozlabs.org
|
||||
Link: http://lore.kernel.org/lkml/20200401203340.31402-2-kjain@linux.ibm.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/expr.c | 4 ++--
|
||||
tools/perf/util/expr.c | 10 +++++-----
|
||||
tools/perf/util/expr.h | 12 ++++++------
|
||||
tools/perf/util/expr.y | 6 +++---
|
||||
tools/perf/util/stat-shadow.c | 2 +-
|
||||
5 files changed, 17 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
|
||||
index 9fd4ba83fbe0..279cc9876b72 100644
|
||||
--- a/tools/perf/tests/expr.c
|
||||
+++ b/tools/perf/tests/expr.c
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "tests.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
-static int test(struct parse_ctx *ctx, const char *e, double val2)
|
||||
+static int test(struct expr_parse_ctx *ctx, const char *e, double val2)
|
||||
{
|
||||
double val;
|
||||
|
||||
@@ -20,7 +20,7 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
const char **other;
|
||||
double val;
|
||||
int i, ret;
|
||||
- struct parse_ctx ctx;
|
||||
+ struct expr_parse_ctx ctx;
|
||||
int num_other;
|
||||
|
||||
expr__ctx_init(&ctx);
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
index fd192ddf93c1..c8ccc548a585 100644
|
||||
--- a/tools/perf/util/expr.c
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -11,7 +11,7 @@ extern int expr_debug;
|
||||
#endif
|
||||
|
||||
/* Caller must make sure id is allocated */
|
||||
-void expr__add_id(struct parse_ctx *ctx, const char *name, double val)
|
||||
+void expr__add_id(struct expr_parse_ctx *ctx, const char *name, double val)
|
||||
{
|
||||
int idx;
|
||||
|
||||
@@ -21,13 +21,13 @@ void expr__add_id(struct parse_ctx *ctx, const char *name, double val)
|
||||
ctx->ids[idx].val = val;
|
||||
}
|
||||
|
||||
-void expr__ctx_init(struct parse_ctx *ctx)
|
||||
+void expr__ctx_init(struct expr_parse_ctx *ctx)
|
||||
{
|
||||
ctx->num_ids = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
-__expr__parse(double *val, struct parse_ctx *ctx, const char *expr,
|
||||
+__expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
|
||||
int start)
|
||||
{
|
||||
YY_BUFFER_STATE buffer;
|
||||
@@ -52,7 +52,7 @@ __expr__parse(double *val, struct parse_ctx *ctx, const char *expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr)
|
||||
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr)
|
||||
{
|
||||
return __expr__parse(final_val, ctx, expr, EXPR_PARSE) ? -1 : 0;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
int *num_other)
|
||||
{
|
||||
int err, i = 0, j = 0;
|
||||
- struct parse_ctx ctx;
|
||||
+ struct expr_parse_ctx ctx;
|
||||
|
||||
expr__ctx_init(&ctx);
|
||||
err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER);
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index 9377538f4097..b9e53f2b5844 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -5,19 +5,19 @@
|
||||
#define EXPR_MAX_OTHER 20
|
||||
#define MAX_PARSE_ID EXPR_MAX_OTHER
|
||||
|
||||
-struct parse_id {
|
||||
+struct expr_parse_id {
|
||||
const char *name;
|
||||
double val;
|
||||
};
|
||||
|
||||
-struct parse_ctx {
|
||||
+struct expr_parse_ctx {
|
||||
int num_ids;
|
||||
- struct parse_id ids[MAX_PARSE_ID];
|
||||
+ struct expr_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);
|
||||
-int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr);
|
||||
+void expr__ctx_init(struct expr_parse_ctx *ctx);
|
||||
+void expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
|
||||
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr);
|
||||
int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
int *num_other);
|
||||
|
||||
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
|
||||
index 5b1b02f3fafa..2764b196edc3 100644
|
||||
--- a/tools/perf/util/expr.y
|
||||
+++ b/tools/perf/util/expr.y
|
||||
@@ -14,7 +14,7 @@
|
||||
%define api.pure full
|
||||
|
||||
%parse-param { double *final_val }
|
||||
-%parse-param { struct parse_ctx *ctx }
|
||||
+%parse-param { struct expr_parse_ctx *ctx }
|
||||
%parse-param {void *scanner}
|
||||
%lex-param {void* scanner}
|
||||
|
||||
@@ -39,14 +39,14 @@
|
||||
|
||||
%{
|
||||
static void expr_error(double *final_val __maybe_unused,
|
||||
- struct parse_ctx *ctx __maybe_unused,
|
||||
+ struct expr_parse_ctx *ctx __maybe_unused,
|
||||
void *scanner,
|
||||
const char *s)
|
||||
{
|
||||
pr_debug("%s\n", s);
|
||||
}
|
||||
|
||||
-static int lookup_id(struct parse_ctx *ctx, char *id, double *val)
|
||||
+static int lookup_id(struct expr_parse_ctx *ctx, char *id, double *val)
|
||||
{
|
||||
int i;
|
||||
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index 4651e76dfd5e..682334eacff0 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -729,7 +729,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
struct runtime_stat *st)
|
||||
{
|
||||
print_metric_t print_metric = out->print_metric;
|
||||
- struct parse_ctx pctx;
|
||||
+ struct expr_parse_ctx pctx;
|
||||
double ratio, scale;
|
||||
int i;
|
||||
void *ctxp = out->ctx;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
119
patches/0177-perf-expr-Add-expr_scanner_ctx-object.patch
Normal file
119
patches/0177-perf-expr-Add-expr_scanner_ctx-object.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From 4d059ad799bb7ef10eb6dc7ea47cc1e8e7f5abb5 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Thu, 2 Apr 2020 02:03:35 +0530
|
||||
Subject: [PATCH 060/201] perf expr: Add expr_scanner_ctx object
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 871f9f599db8d9d2387c0717e712af405290edea
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=871f9f599db8d9d2387c0717e712af405290edea
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add the expr_scanner_ctx object to hold user data for the expr scanner.
|
||||
Currently it holds only start_token, Kajol Jain will use it to hold 24x7
|
||||
runtime param.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Anju T Sudhakar <anju@linux.vnet.ibm.com>
|
||||
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Joe Mario <jmario@redhat.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
|
||||
Cc: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Mackerras <paulus@ozlabs.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linuxppc-dev@lists.ozlabs.org
|
||||
Link: http://lore.kernel.org/lkml/20200401203340.31402-3-kjain@linux.ibm.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.c | 6 ++++--
|
||||
tools/perf/util/expr.h | 4 ++++
|
||||
tools/perf/util/expr.l | 10 +++++-----
|
||||
3 files changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
index c8ccc548a585..c3382d58cf40 100644
|
||||
--- a/tools/perf/util/expr.c
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <assert.h>
|
||||
#include "expr.h"
|
||||
#include "expr-bison.h"
|
||||
-#define YY_EXTRA_TYPE int
|
||||
#include "expr-flex.h"
|
||||
|
||||
#ifdef PARSER_DEBUG
|
||||
@@ -30,11 +29,14 @@ static int
|
||||
__expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
|
||||
int start)
|
||||
{
|
||||
+ struct expr_scanner_ctx scanner_ctx = {
|
||||
+ .start_token = start,
|
||||
+ };
|
||||
YY_BUFFER_STATE buffer;
|
||||
void *scanner;
|
||||
int ret;
|
||||
|
||||
- ret = expr_lex_init_extra(start, &scanner);
|
||||
+ ret = expr_lex_init_extra(&scanner_ctx, &scanner);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index b9e53f2b5844..0938ad166ece 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -15,6 +15,10 @@ struct expr_parse_ctx {
|
||||
struct expr_parse_id ids[MAX_PARSE_ID];
|
||||
};
|
||||
|
||||
+struct expr_scanner_ctx {
|
||||
+ int start_token;
|
||||
+};
|
||||
+
|
||||
void expr__ctx_init(struct expr_parse_ctx *ctx);
|
||||
void expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
|
||||
int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr);
|
||||
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
|
||||
index eaad29243c23..2582c2464938 100644
|
||||
--- a/tools/perf/util/expr.l
|
||||
+++ b/tools/perf/util/expr.l
|
||||
@@ -76,13 +76,13 @@ sym [0-9a-zA-Z_\.:@]+
|
||||
symbol {spec}*{sym}*{spec}*{sym}*
|
||||
|
||||
%%
|
||||
- {
|
||||
- int start_token;
|
||||
+ struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
|
||||
|
||||
- start_token = expr_get_extra(yyscanner);
|
||||
+ {
|
||||
+ int start_token = sctx->start_token;
|
||||
|
||||
- if (start_token) {
|
||||
- expr_set_extra(NULL, yyscanner);
|
||||
+ if (sctx->start_token) {
|
||||
+ sctx->start_token = 0;
|
||||
return start_token;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,133 @@
|
||||
From 052632aaedcbfdcac4e2a397dcfbb6fad817b24b Mon Sep 17 00:00:00 2001
|
||||
From: Kajol Jain <kjain@linux.ibm.com>
|
||||
Date: Thu, 2 Apr 2020 02:03:36 +0530
|
||||
Subject: [PATCH 061/201] perf metrictroup: Split the metricgroup__add_metric
|
||||
function
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 47352aba40035ab3fdc50dd03a94456feabed7d8
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=47352aba40035ab3fdc50dd03a94456feabed7d8
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This patch refactors metricgroup__add_metric function where some part of
|
||||
it move to function metricgroup__add_metric_param. No logic change.
|
||||
|
||||
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Anju T Sudhakar <anju@linux.vnet.ibm.com>
|
||||
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Joe Mario <jmario@redhat.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
|
||||
Cc: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Mackerras <paulus@ozlabs.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linuxppc-dev@lists.ozlabs.org
|
||||
Link: http://lore.kernel.org/lkml/20200401203340.31402-4-kjain@linux.ibm.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 60 ++++++++++++++++++++---------------
|
||||
1 file changed, 35 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 4baa9f2040ec..792fecca72e0 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -495,6 +495,39 @@ static bool metricgroup__has_constraint(struct pmu_event *pe)
|
||||
return false;
|
||||
}
|
||||
|
||||
+static int __metricgroup__add_metric(struct strbuf *events,
|
||||
+ struct list_head *group_list, struct pmu_event *pe)
|
||||
+{
|
||||
+
|
||||
+ const char **ids;
|
||||
+ int idnum;
|
||||
+ struct egroup *eg;
|
||||
+
|
||||
+ if (expr__find_other(pe->metric_expr, NULL, &ids, &idnum) < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (events->len > 0)
|
||||
+ strbuf_addf(events, ",");
|
||||
+
|
||||
+ if (metricgroup__has_constraint(pe))
|
||||
+ metricgroup__add_metric_non_group(events, ids, idnum);
|
||||
+ else
|
||||
+ metricgroup__add_metric_weak_group(events, ids, idnum);
|
||||
+
|
||||
+ eg = malloc(sizeof(*eg));
|
||||
+ if (!eg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ eg->ids = ids;
|
||||
+ eg->idnum = idnum;
|
||||
+ eg->metric_name = pe->metric_name;
|
||||
+ eg->metric_expr = pe->metric_expr;
|
||||
+ eg->metric_unit = pe->unit;
|
||||
+ list_add_tail(&eg->nd, group_list);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
struct list_head *group_list)
|
||||
{
|
||||
@@ -514,35 +547,12 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
continue;
|
||||
if (match_metric(pe->metric_group, metric) ||
|
||||
match_metric(pe->metric_name, metric)) {
|
||||
- const char **ids;
|
||||
- int idnum;
|
||||
- struct egroup *eg;
|
||||
|
||||
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
|
||||
|
||||
- if (expr__find_other(pe->metric_expr,
|
||||
- NULL, &ids, &idnum) < 0)
|
||||
- continue;
|
||||
- if (events->len > 0)
|
||||
- strbuf_addf(events, ",");
|
||||
-
|
||||
- if (metricgroup__has_constraint(pe))
|
||||
- metricgroup__add_metric_non_group(events, ids, idnum);
|
||||
- else
|
||||
- metricgroup__add_metric_weak_group(events, ids, idnum);
|
||||
-
|
||||
- eg = malloc(sizeof(struct egroup));
|
||||
- if (!eg) {
|
||||
- ret = -ENOMEM;
|
||||
+ ret = __metricgroup__add_metric(events, group_list, pe);
|
||||
+ if (ret == -ENOMEM)
|
||||
break;
|
||||
- }
|
||||
- eg->ids = ids;
|
||||
- eg->idnum = idnum;
|
||||
- eg->metric_name = pe->metric_name;
|
||||
- eg->metric_expr = pe->metric_expr;
|
||||
- eg->metric_unit = pe->unit;
|
||||
- list_add_tail(&eg->nd, group_list);
|
||||
- ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,450 @@
|
||||
From 9e94b0c96739f13fbe54fcb75d18c328f255ed75 Mon Sep 17 00:00:00 2001
|
||||
From: Kajol Jain <kjain@linux.ibm.com>
|
||||
Date: Thu, 2 Apr 2020 02:03:37 +0530
|
||||
Subject: [PATCH 062/201] perf metricgroups: Enhance JSON/metric infrastructure
|
||||
to handle "?"
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 1e1a873dc67fc748cc319a27603f33db91027730
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e1a873dc67fc748cc319a27603f33db91027730
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Patch enhances current metric infrastructure to handle "?" in the metric
|
||||
expression. The "?" can be use for parameters whose value not known
|
||||
while creating metric events and which can be replace later at runtime
|
||||
to the proper value. It also add flexibility to create multiple events
|
||||
out of single metric event added in JSON file.
|
||||
|
||||
Patch adds function 'arch_get_runtimeparam' which is a arch specific
|
||||
function, returns the count of metric events need to be created. By
|
||||
default it return 1.
|
||||
|
||||
This infrastructure needed for hv_24x7 socket/chip level events.
|
||||
"hv_24x7" chip level events needs specific chip-id to which the data is
|
||||
requested. Function 'arch_get_runtimeparam' implemented in header.c
|
||||
which extract number of sockets from sysfs file "sockets" under
|
||||
"/sys/devices/hv_24x7/interface/".
|
||||
|
||||
With this patch basically we are trying to create as many metric events
|
||||
as define by runtime_param.
|
||||
|
||||
For that one loop is added in function 'metricgroup__add_metric', which
|
||||
create multiple events at run time depend on return value of
|
||||
'arch_get_runtimeparam' and merge that event in 'group_list'.
|
||||
|
||||
To achieve that we are actually passing this parameter value as part of
|
||||
`expr__find_other` function and changing "?" present in metric
|
||||
expression with this value.
|
||||
|
||||
As in our JSON file, there gonna be single metric event, and out of
|
||||
which we are creating multiple events.
|
||||
|
||||
To understand which data count belongs to which parameter value,
|
||||
we also printing param value in generic_metric function.
|
||||
|
||||
For example,
|
||||
|
||||
command:# ./perf stat -M PowerBUS_Frequency -C 0 -I 1000
|
||||
1.000101867 9,356,933 hv_24x7/pm_pb_cyc,chip=0/ # 2.3 GHz PowerBUS_Frequency_0
|
||||
1.000101867 9,366,134 hv_24x7/pm_pb_cyc,chip=1/ # 2.3 GHz PowerBUS_Frequency_1
|
||||
2.000314878 9,365,868 hv_24x7/pm_pb_cyc,chip=0/ # 2.3 GHz PowerBUS_Frequency_0
|
||||
2.000314878 9,366,092 hv_24x7/pm_pb_cyc,chip=1/ # 2.3 GHz PowerBUS_Frequency_1
|
||||
|
||||
So, here _0 and _1 after PowerBUS_Frequency specify parameter value.
|
||||
|
||||
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Anju T Sudhakar <anju@linux.vnet.ibm.com>
|
||||
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Joe Mario <jmario@redhat.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
|
||||
Cc: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Mackerras <paulus@ozlabs.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linuxppc-dev@lists.ozlabs.org
|
||||
Link: http://lore.kernel.org/lkml/20200401203340.31402-5-kjain@linux.ibm.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.h
|
||||
---
|
||||
tools/perf/arch/powerpc/util/header.c | 8 ++++++++
|
||||
tools/perf/tests/expr.c | 8 ++++----
|
||||
tools/perf/util/expr.c | 11 ++++++-----
|
||||
tools/perf/util/expr.h | 5 +++--
|
||||
tools/perf/util/expr.l | 27 +++++++++++++++++++-------
|
||||
tools/perf/util/metricgroup.c | 28 ++++++++++++++++++++++++---
|
||||
tools/perf/util/metricgroup.h | 2 ++
|
||||
tools/perf/util/stat-shadow.c | 17 ++++++++++------
|
||||
8 files changed, 79 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
|
||||
index e46be9ef5a68..0a3816692252 100644
|
||||
--- a/tools/perf/arch/powerpc/util/header.c
|
||||
+++ b/tools/perf/arch/powerpc/util/header.c
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <linux/stringify.h>
|
||||
#include "header.h"
|
||||
#include "util.h"
|
||||
+#include "metricgroup.h"
|
||||
+#include <api/fs/fs.h>
|
||||
|
||||
#define mfspr(rn) ({unsigned long rval; \
|
||||
asm volatile("mfspr %0," __stringify(rn) \
|
||||
@@ -45,3 +47,9 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
|
||||
|
||||
return bufp;
|
||||
}
|
||||
+
|
||||
+int arch_get_runtimeparam(void)
|
||||
+{
|
||||
+ int count;
|
||||
+ return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count;
|
||||
+}
|
||||
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
|
||||
index 279cc9876b72..e7706d93b9fe 100644
|
||||
--- a/tools/perf/tests/expr.c
|
||||
+++ b/tools/perf/tests/expr.c
|
||||
@@ -8,7 +8,7 @@ static int test(struct expr_parse_ctx *ctx, const char *e, double val2)
|
||||
{
|
||||
double val;
|
||||
|
||||
- if (expr__parse(&val, ctx, e))
|
||||
+ if (expr__parse(&val, ctx, e, 1))
|
||||
TEST_ASSERT_VAL("parse test failed", 0);
|
||||
TEST_ASSERT_VAL("unexpected value", val == val2);
|
||||
return 0;
|
||||
@@ -42,15 +42,15 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
return ret;
|
||||
|
||||
p = "FOO/0";
|
||||
- ret = expr__parse(&val, &ctx, p);
|
||||
+ ret = expr__parse(&val, &ctx, p, 1);
|
||||
TEST_ASSERT_VAL("division by zero", ret == -1);
|
||||
|
||||
p = "BAR/";
|
||||
- ret = expr__parse(&val, &ctx, p);
|
||||
+ ret = expr__parse(&val, &ctx, p, 1);
|
||||
TEST_ASSERT_VAL("missing operand", ret == -1);
|
||||
|
||||
TEST_ASSERT_VAL("find other",
|
||||
- expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", &other, &num_other) == 0);
|
||||
+ expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", &other, &num_other, 1) == 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"));
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
index c3382d58cf40..aa631e37ad1e 100644
|
||||
--- a/tools/perf/util/expr.c
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -27,10 +27,11 @@ void expr__ctx_init(struct expr_parse_ctx *ctx)
|
||||
|
||||
static int
|
||||
__expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
|
||||
- int start)
|
||||
+ int start, int runtime)
|
||||
{
|
||||
struct expr_scanner_ctx scanner_ctx = {
|
||||
.start_token = start,
|
||||
+ .runtime = runtime,
|
||||
};
|
||||
YY_BUFFER_STATE buffer;
|
||||
void *scanner;
|
||||
@@ -54,9 +55,9 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr)
|
||||
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr, int runtime)
|
||||
{
|
||||
- return __expr__parse(final_val, ctx, expr, EXPR_PARSE) ? -1 : 0;
|
||||
+ return __expr__parse(final_val, ctx, expr, EXPR_PARSE, runtime) ? -1 : 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -74,13 +75,13 @@ already_seen(const char *val, const char *one, const char **other,
|
||||
}
|
||||
|
||||
int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
- int *num_other)
|
||||
+ int *num_other, int runtime)
|
||||
{
|
||||
int err, i = 0, j = 0;
|
||||
struct expr_parse_ctx ctx;
|
||||
|
||||
expr__ctx_init(&ctx);
|
||||
- err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER);
|
||||
+ err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER, runtime);
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index 0938ad166ece..87d627bb699b 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -17,12 +17,13 @@ struct expr_parse_ctx {
|
||||
|
||||
struct expr_scanner_ctx {
|
||||
int start_token;
|
||||
+ int runtime;
|
||||
};
|
||||
|
||||
void expr__ctx_init(struct expr_parse_ctx *ctx);
|
||||
void expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
|
||||
-int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr);
|
||||
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr, int runtime);
|
||||
int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
- int *num_other);
|
||||
+ int *num_other, int runtime);
|
||||
|
||||
#endif
|
||||
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
|
||||
index 2582c2464938..74b9b59b1aa5 100644
|
||||
--- a/tools/perf/util/expr.l
|
||||
+++ b/tools/perf/util/expr.l
|
||||
@@ -35,7 +35,7 @@ static int value(yyscan_t scanner, int base)
|
||||
* Allow @ instead of / to be able to specify pmu/event/ without
|
||||
* conflicts with normal division.
|
||||
*/
|
||||
-static char *normalize(char *str)
|
||||
+static char *normalize(char *str, int runtime)
|
||||
{
|
||||
char *ret = str;
|
||||
char *dst = str;
|
||||
@@ -45,6 +45,19 @@ static char *normalize(char *str)
|
||||
*dst++ = '/';
|
||||
else if (*str == '\\')
|
||||
*dst++ = *++str;
|
||||
+ else if (*str == '?') {
|
||||
+ char *paramval;
|
||||
+ int i = 0;
|
||||
+ int size = asprintf(¶mval, "%d", runtime);
|
||||
+
|
||||
+ if (size < 0)
|
||||
+ *dst++ = '0';
|
||||
+ else {
|
||||
+ while (i < size)
|
||||
+ *dst++ = paramval[i++];
|
||||
+ free(paramval);
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
*dst++ = *str;
|
||||
str++;
|
||||
@@ -54,16 +67,16 @@ static char *normalize(char *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int str(yyscan_t scanner, int token)
|
||||
+static int str(yyscan_t scanner, int token, int runtime)
|
||||
{
|
||||
YYSTYPE *yylval = expr_get_lval(scanner);
|
||||
char *text = expr_get_text(scanner);
|
||||
|
||||
- yylval->str = normalize(strdup(text));
|
||||
+ yylval->str = normalize(strdup(text), runtime);
|
||||
if (!yylval->str)
|
||||
return EXPR_ERROR;
|
||||
|
||||
- yylval->str = normalize(yylval->str);
|
||||
+ yylval->str = normalize(yylval->str, runtime);
|
||||
return token;
|
||||
}
|
||||
%}
|
||||
@@ -72,8 +85,8 @@ number [0-9]+
|
||||
|
||||
sch [-,=]
|
||||
spec \\{sch}
|
||||
-sym [0-9a-zA-Z_\.:@]+
|
||||
-symbol {spec}*{sym}*{spec}*{sym}*
|
||||
+sym [0-9a-zA-Z_\.:@?]+
|
||||
+symbol {spec}*{sym}*{spec}*{sym}*{spec}*{sym}
|
||||
|
||||
%%
|
||||
struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
|
||||
@@ -93,7 +106,7 @@ if { return IF; }
|
||||
else { return ELSE; }
|
||||
#smt_on { return SMT_ON; }
|
||||
{number} { return value(yyscanner, 10); }
|
||||
-{symbol} { return str(yyscanner, ID); }
|
||||
+{symbol} { return str(yyscanner, ID, sctx->runtime); }
|
||||
"|" { return '|'; }
|
||||
"^" { return '^'; }
|
||||
"&" { return '&'; }
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 792fecca72e0..b4fe2e2f3ca4 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -96,6 +96,7 @@ struct egroup {
|
||||
const char *metric_name;
|
||||
const char *metric_expr;
|
||||
const char *metric_unit;
|
||||
+ int runtime;
|
||||
};
|
||||
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
@@ -211,6 +212,7 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
expr->metric_name = eg->metric_name;
|
||||
expr->metric_unit = eg->metric_unit;
|
||||
expr->metric_events = metric_events;
|
||||
+ expr->runtime = eg->runtime;
|
||||
list_add(&expr->nd, &me->head);
|
||||
}
|
||||
|
||||
@@ -495,15 +497,20 @@ static bool metricgroup__has_constraint(struct pmu_event *pe)
|
||||
return false;
|
||||
}
|
||||
|
||||
+int __weak arch_get_runtimeparam(void)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static int __metricgroup__add_metric(struct strbuf *events,
|
||||
- struct list_head *group_list, struct pmu_event *pe)
|
||||
+ struct list_head *group_list, struct pmu_event *pe, int runtime)
|
||||
{
|
||||
|
||||
const char **ids;
|
||||
int idnum;
|
||||
struct egroup *eg;
|
||||
|
||||
- if (expr__find_other(pe->metric_expr, NULL, &ids, &idnum) < 0)
|
||||
+ if (expr__find_other(pe->metric_expr, NULL, &ids, &idnum, runtime) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (events->len > 0)
|
||||
@@ -523,6 +530,7 @@ static int __metricgroup__add_metric(struct strbuf *events,
|
||||
eg->metric_name = pe->metric_name;
|
||||
eg->metric_expr = pe->metric_expr;
|
||||
eg->metric_unit = pe->unit;
|
||||
+ eg->runtime = runtime;
|
||||
list_add_tail(&eg->nd, group_list);
|
||||
|
||||
return 0;
|
||||
@@ -550,7 +558,21 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
|
||||
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
|
||||
|
||||
- ret = __metricgroup__add_metric(events, group_list, pe);
|
||||
+ if (!strstr(pe->metric_expr, "?")) {
|
||||
+ ret = __metricgroup__add_metric(events, group_list, pe, 1);
|
||||
+ } else {
|
||||
+ int j, count;
|
||||
+
|
||||
+ count = arch_get_runtimeparam();
|
||||
+
|
||||
+ /* This loop is added to create multiple
|
||||
+ * events depend on count value and add
|
||||
+ * those events to group_list.
|
||||
+ */
|
||||
+
|
||||
+ for (j = 0; j < count; j++)
|
||||
+ ret = __metricgroup__add_metric(events, group_list, pe, j);
|
||||
+ }
|
||||
if (ret == -ENOMEM)
|
||||
break;
|
||||
}
|
||||
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
|
||||
index 9c6e6913f905..f2a17a05eb81 100644
|
||||
--- a/tools/perf/util/metricgroup.h
|
||||
+++ b/tools/perf/util/metricgroup.h
|
||||
@@ -22,6 +22,7 @@ struct metric_expr {
|
||||
const char *metric_name;
|
||||
const char *metric_unit;
|
||||
struct perf_evsel **metric_events;
|
||||
+ int runtime;
|
||||
};
|
||||
|
||||
struct metric_event *metricgroup__lookup(struct rblist *metric_events,
|
||||
@@ -34,4 +35,5 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
void metricgroup__print(bool metrics, bool groups, char *filter,
|
||||
bool raw, bool details);
|
||||
bool metricgroup__has_metric(const char *metric);
|
||||
+int arch_get_runtimeparam(void);
|
||||
#endif
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index 682334eacff0..dfa33d1bce53 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -336,7 +336,7 @@ void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list)
|
||||
metric_events = counter->metric_events;
|
||||
if (!metric_events) {
|
||||
if (expr__find_other(counter->metric_expr, counter->name,
|
||||
- &metric_names, &num_metric_names) < 0)
|
||||
+ &metric_names, &num_metric_names, 1) < 0)
|
||||
continue;
|
||||
|
||||
metric_events = calloc(sizeof(struct perf_evsel *),
|
||||
@@ -723,6 +723,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
char *name,
|
||||
const char *metric_name,
|
||||
const char *metric_unit,
|
||||
+ int runtime,
|
||||
double avg,
|
||||
int cpu,
|
||||
struct perf_stat_output_ctx *out,
|
||||
@@ -777,7 +778,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
}
|
||||
|
||||
if (!metric_events[i]) {
|
||||
- if (expr__parse(&ratio, &pctx, metric_expr) == 0) {
|
||||
+ if (expr__parse(&ratio, &pctx, metric_expr, runtime) == 0) {
|
||||
char *unit;
|
||||
char metric_bf[64];
|
||||
|
||||
@@ -786,9 +787,13 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
&unit, &scale) >= 0) {
|
||||
ratio *= scale;
|
||||
}
|
||||
-
|
||||
- scnprintf(metric_bf, sizeof(metric_bf),
|
||||
+ if (strstr(metric_expr, "?"))
|
||||
+ scnprintf(metric_bf, sizeof(metric_bf),
|
||||
+ "%s %s_%d", unit, metric_name, runtime);
|
||||
+ else
|
||||
+ scnprintf(metric_bf, sizeof(metric_bf),
|
||||
"%s %s", unit, metric_name);
|
||||
+
|
||||
print_metric(config, ctxp, NULL, "%8.1f",
|
||||
metric_bf, ratio);
|
||||
} else {
|
||||
@@ -1022,7 +1027,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
print_metric(config, ctxp, NULL, NULL, name, 0);
|
||||
} else if (evsel->metric_expr) {
|
||||
generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name,
|
||||
- evsel->metric_name, NULL, avg, cpu, out, st);
|
||||
+ evsel->metric_name, NULL, 1, avg, cpu, out, st);
|
||||
} else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) {
|
||||
char unit = 'M';
|
||||
char unit_buf[10];
|
||||
@@ -1051,7 +1056,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
out->new_line(config, ctxp);
|
||||
generic_metric(config, mexp->metric_expr, mexp->metric_events,
|
||||
evsel->name, mexp->metric_name,
|
||||
- mexp->metric_unit, avg, cpu, out, st);
|
||||
+ mexp->metric_unit, mexp->runtime, avg, cpu, out, st);
|
||||
}
|
||||
}
|
||||
if (num == 0)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
From 74604ca3049109ef42ef4ed352b712f47de6898f Mon Sep 17 00:00:00 2001
|
||||
From: Kajol Jain <kjain@linux.ibm.com>
|
||||
Date: Thu, 2 Apr 2020 02:03:38 +0530
|
||||
Subject: [PATCH 063/201] perf tests expr: Added test for runtime param in
|
||||
metric expression
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 9022608ec5babbb0fa631234098d52895e7e34d8
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9022608ec5babbb0fa631234098d52895e7e34d8
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Added test case for parsing "?" in metric expression.
|
||||
|
||||
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Anju T Sudhakar <anju@linux.vnet.ibm.com>
|
||||
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Joe Mario <jmario@redhat.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
|
||||
Cc: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Mackerras <paulus@ozlabs.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linuxppc-dev@lists.ozlabs.org
|
||||
Link: http://lore.kernel.org/lkml/20200401203340.31402-6-kjain@linux.ibm.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/expr.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
|
||||
index e7706d93b9fe..d7f74094f935 100644
|
||||
--- a/tools/perf/tests/expr.c
|
||||
+++ b/tools/perf/tests/expr.c
|
||||
@@ -57,6 +57,14 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
TEST_ASSERT_VAL("find other", !strcmp(other[2], "BOZO"));
|
||||
TEST_ASSERT_VAL("find other", other[3] == NULL);
|
||||
|
||||
+ TEST_ASSERT_VAL("find other",
|
||||
+ expr__find_other("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@", NULL,
|
||||
+ &other, &num_other, 3) == 0);
|
||||
+ TEST_ASSERT_VAL("find other", num_other == 2);
|
||||
+ TEST_ASSERT_VAL("find other", !strcmp(other[0], "EVENT1,param=3/"));
|
||||
+ TEST_ASSERT_VAL("find other", !strcmp(other[1], "EVENT2,param=3/"));
|
||||
+ TEST_ASSERT_VAL("find other", other[2] == NULL);
|
||||
+
|
||||
for (i = 0; i < num_other; i++)
|
||||
free((void *)other[i]);
|
||||
free((void *)other);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
122
patches/0181-perf-jevents-Add-some-test-events.patch
Normal file
122
patches/0181-perf-jevents-Add-some-test-events.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From f4a40e041840155d7afdda97249fdcf394814905 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Tue, 17 Mar 2020 19:02:13 +0800
|
||||
Subject: [PATCH 064/201] perf jevents: Add some test events
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit c52db67a74b3a9b834af4588489cfea22ec280a3
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c52db67a74b3a9b834af4588489cfea22ec280a3
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add some test PMU events. The events are randomly chosen from x86 and
|
||||
arm64 JSONs. The events include CPU and uncore events.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: James Clark <james.clark@arm.com>
|
||||
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1584442939-8911-2-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../pmu-events/arch/test/test_cpu/branch.json | 12 +++++++++
|
||||
.../pmu-events/arch/test/test_cpu/other.json | 26 +++++++++++++++++++
|
||||
.../pmu-events/arch/test/test_cpu/uncore.json | 21 +++++++++++++++
|
||||
3 files changed, 59 insertions(+)
|
||||
create mode 100644 tools/perf/pmu-events/arch/test/test_cpu/branch.json
|
||||
create mode 100644 tools/perf/pmu-events/arch/test/test_cpu/other.json
|
||||
create mode 100644 tools/perf/pmu-events/arch/test/test_cpu/uncore.json
|
||||
|
||||
diff --git a/tools/perf/pmu-events/arch/test/test_cpu/branch.json b/tools/perf/pmu-events/arch/test/test_cpu/branch.json
|
||||
new file mode 100644
|
||||
index 000000000000..93ddfd8053ca
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/pmu-events/arch/test/test_cpu/branch.json
|
||||
@@ -0,0 +1,12 @@
|
||||
+[
|
||||
+ {
|
||||
+ "EventName": "bp_l1_btb_correct",
|
||||
+ "EventCode": "0x8a",
|
||||
+ "BriefDescription": "L1 BTB Correction."
|
||||
+ },
|
||||
+ {
|
||||
+ "EventName": "bp_l2_btb_correct",
|
||||
+ "EventCode": "0x8b",
|
||||
+ "BriefDescription": "L2 BTB Correction."
|
||||
+ }
|
||||
+]
|
||||
diff --git a/tools/perf/pmu-events/arch/test/test_cpu/other.json b/tools/perf/pmu-events/arch/test/test_cpu/other.json
|
||||
new file mode 100644
|
||||
index 000000000000..7d53d7ecd723
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/pmu-events/arch/test/test_cpu/other.json
|
||||
@@ -0,0 +1,26 @@
|
||||
+[
|
||||
+ {
|
||||
+ "EventCode": "0x6",
|
||||
+ "Counter": "0,1",
|
||||
+ "UMask": "0x80",
|
||||
+ "EventName": "SEGMENT_REG_LOADS.ANY",
|
||||
+ "SampleAfterValue": "200000",
|
||||
+ "BriefDescription": "Number of segment register loads."
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x9",
|
||||
+ "Counter": "0,1",
|
||||
+ "UMask": "0x20",
|
||||
+ "EventName": "DISPATCH_BLOCKED.ANY",
|
||||
+ "SampleAfterValue": "200000",
|
||||
+ "BriefDescription": "Memory cluster signals to block micro-op dispatch for any reason"
|
||||
+ },
|
||||
+ {
|
||||
+ "EventCode": "0x3A",
|
||||
+ "Counter": "0,1",
|
||||
+ "UMask": "0x0",
|
||||
+ "EventName": "EIST_TRANS",
|
||||
+ "SampleAfterValue": "200000",
|
||||
+ "BriefDescription": "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions"
|
||||
+ }
|
||||
+]
|
||||
\ No newline at end of file
|
||||
diff --git a/tools/perf/pmu-events/arch/test/test_cpu/uncore.json b/tools/perf/pmu-events/arch/test/test_cpu/uncore.json
|
||||
new file mode 100644
|
||||
index 000000000000..d0a890cc814d
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/pmu-events/arch/test/test_cpu/uncore.json
|
||||
@@ -0,0 +1,21 @@
|
||||
+[
|
||||
+ {
|
||||
+ "EventCode": "0x02",
|
||||
+ "EventName": "uncore_hisi_ddrc.flux_wcmd",
|
||||
+ "BriefDescription": "DDRC write commands",
|
||||
+ "PublicDescription": "DDRC write commands",
|
||||
+ "Unit": "hisi_sccl,ddrc"
|
||||
+ },
|
||||
+ {
|
||||
+ "Unit": "CBO",
|
||||
+ "EventCode": "0x22",
|
||||
+ "UMask": "0x81",
|
||||
+ "EventName": "UNC_CBO_XSNP_RESPONSE.MISS_EVICTION",
|
||||
+ "BriefDescription": "A cross-core snoop resulted from L3 Eviction which misses in some processor core.",
|
||||
+ "PublicDescription": "A cross-core snoop resulted from L3 Eviction which misses in some processor core.",
|
||||
+ "Counter": "0,1",
|
||||
+ "CounterMask": "0",
|
||||
+ "Invert": "0",
|
||||
+ "EdgeDetect": "0"
|
||||
+ }
|
||||
+]
|
||||
--
|
||||
2.27.0
|
||||
|
||||
169
patches/0182-perf-jevents-Support-test-events-folder.patch
Normal file
169
patches/0182-perf-jevents-Support-test-events-folder.patch
Normal file
@ -0,0 +1,169 @@
|
||||
From 37a0ab8d2dd9fc5edd3091d2c5843dd327875398 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Tue, 17 Mar 2020 19:02:14 +0800
|
||||
Subject: [PATCH 065/201] perf jevents: Support test events folder
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit d84478088780acdecfcf50a0e52b71cc4ab7c520
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d84478088780acdecfcf50a0e52b71cc4ab7c520
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
With the goal of supporting pmu-events test case, introduce support for
|
||||
a test events folder.
|
||||
|
||||
These test events can be used for testing generation of pmu-event tables
|
||||
and alias creation for any arch.
|
||||
|
||||
When running the pmu-events test case, these test events will be used as
|
||||
the platform-agnostic events, so aliases can be created per-PMU and
|
||||
validated against known expected values.
|
||||
|
||||
To support the test events, add a "testcpu" entry in pmu_events_map[].
|
||||
The pmu-events test will be able to lookup the events map for "testcpu",
|
||||
to verify the generated tables against expected values.
|
||||
|
||||
The resultant generated pmu-events.c will now look like the following:
|
||||
|
||||
struct pmu_event pme_ampere_emag[] = {
|
||||
{
|
||||
.name = "ldrex_spec",
|
||||
.event = "event=0x6c",
|
||||
.desc = "Exclusive operation spe...",
|
||||
.topic = "intrinsic",
|
||||
.long_desc = "Exclusive operation ...",
|
||||
},
|
||||
...
|
||||
};
|
||||
|
||||
struct pmu_event pme_test_cpu[] = {
|
||||
{
|
||||
.name = "uncore_hisi_ddrc.flux_wcmd",
|
||||
.event = "event=0x2",
|
||||
.desc = "DDRC write commands. Unit: hisi_sccl,ddrc ",
|
||||
.topic = "uncore",
|
||||
.long_desc = "DDRC write commands",
|
||||
.pmu = "hisi_sccl,ddrc",
|
||||
},
|
||||
{
|
||||
.name = "unc_cbo_xsnp_response.miss_eviction",
|
||||
.event = "umask=0x81,event=0x22",
|
||||
.desc = "Unit: uncore_cbox A cross-core snoop resulted ...",
|
||||
.topic = "uncore",
|
||||
.long_desc = "A cross-core snoop resulted from L3 ...",
|
||||
.pmu = "uncore_cbox",
|
||||
},
|
||||
{
|
||||
.name = "eist_trans",
|
||||
.event = "umask=0x0,period=200000,event=0x3a",
|
||||
.desc = "Number of Enhanced Intel SpeedStep(R) ...",
|
||||
.topic = "other",
|
||||
},
|
||||
{
|
||||
.name = 0,
|
||||
},
|
||||
};
|
||||
|
||||
struct pmu_events_map pmu_events_map[] = {
|
||||
...
|
||||
{
|
||||
.cpuid = "0x00000000500f0000",
|
||||
.version = "v1",
|
||||
.type = "core",
|
||||
.table = pme_ampere_emag
|
||||
},
|
||||
...
|
||||
{
|
||||
.cpuid = "testcpu",
|
||||
.version = "v1",
|
||||
.type = "core",
|
||||
.table = pme_test_cpu,
|
||||
},
|
||||
{
|
||||
.cpuid = 0,
|
||||
.version = 0,
|
||||
.type = 0,
|
||||
.table = 0,
|
||||
},
|
||||
};
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: James Clark <james.clark@arm.com>
|
||||
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1584442939-8911-3-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/pmu-events/jevents.c | 30 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
|
||||
index 6bf2237fef2d..1f7d4c53631d 100644
|
||||
--- a/tools/perf/pmu-events/jevents.c
|
||||
+++ b/tools/perf/pmu-events/jevents.c
|
||||
@@ -772,6 +772,19 @@ static void print_mapping_table_suffix(FILE *outfp)
|
||||
fprintf(outfp, "};\n");
|
||||
}
|
||||
|
||||
+static void print_mapping_test_table(FILE *outfp)
|
||||
+{
|
||||
+ /*
|
||||
+ * Print the terminating, NULL entry.
|
||||
+ */
|
||||
+ fprintf(outfp, "{\n");
|
||||
+ fprintf(outfp, "\t.cpuid = \"testcpu\",\n");
|
||||
+ fprintf(outfp, "\t.version = \"v1\",\n");
|
||||
+ fprintf(outfp, "\t.type = \"core\",\n");
|
||||
+ fprintf(outfp, "\t.table = pme_test_cpu,\n");
|
||||
+ fprintf(outfp, "},\n");
|
||||
+}
|
||||
+
|
||||
static int process_mapfile(FILE *outfp, char *fpath)
|
||||
{
|
||||
int n = 16384;
|
||||
@@ -849,6 +862,7 @@ static int process_mapfile(FILE *outfp, char *fpath)
|
||||
}
|
||||
|
||||
out:
|
||||
+ print_mapping_test_table(outfp);
|
||||
print_mapping_table_suffix(outfp);
|
||||
fclose(mapfp);
|
||||
free(line);
|
||||
@@ -1169,6 +1183,22 @@ int main(int argc, char *argv[])
|
||||
goto empty_map;
|
||||
}
|
||||
|
||||
+ sprintf(ldirname, "%s/test", start_dirname);
|
||||
+
|
||||
+ rc = nftw(ldirname, process_one_file, maxfds, 0);
|
||||
+ if (rc && verbose) {
|
||||
+ pr_info("%s: Error walking file tree %s rc=%d for test\n",
|
||||
+ prog, ldirname, rc);
|
||||
+ goto empty_map;
|
||||
+ } else if (rc < 0) {
|
||||
+ /* Make build fail */
|
||||
+ free_arch_std_events();
|
||||
+ ret = 1;
|
||||
+ goto out_free_mapfile;
|
||||
+ } else if (rc) {
|
||||
+ goto empty_map;
|
||||
+ }
|
||||
+
|
||||
if (close_table)
|
||||
print_events_table_suffix(eventsfp);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
114
patches/0183-perf-pmu-Refactor-pmu_add_cpu_aliases.patch
Normal file
114
patches/0183-perf-pmu-Refactor-pmu_add_cpu_aliases.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From 11fb15685ec24cd84117e1c2a961838614bfff2a Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Tue, 17 Mar 2020 19:02:15 +0800
|
||||
Subject: [PATCH 066/201] perf pmu: Refactor pmu_add_cpu_aliases()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit e45ad701e784e0eed8a07b537b47afb302c59dab
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e45ad701e784e0eed8a07b537b47afb302c59dab
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Create pmu_add_cpu_aliases_map() from pmu_add_cpu_aliases(), so the caller
|
||||
can pass the map; the pmu-events test would use this since there would
|
||||
be no CPUID matching to a mapfile there.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: James Clark <james.clark@arm.com>
|
||||
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1584442939-8911-4-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/pmu.c
|
||||
---
|
||||
tools/perf/util/pmu.c | 21 +++++++++++++--------
|
||||
tools/perf/util/pmu.h | 3 +++
|
||||
2 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
|
||||
index 2d06db85c135..7053b0c5cdae 100644
|
||||
--- a/tools/perf/util/pmu.c
|
||||
+++ b/tools/perf/util/pmu.c
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "parse-events.h"
|
||||
#include "cpumap.h"
|
||||
#include "header.h"
|
||||
-#include "pmu-events/pmu-events.h"
|
||||
#include "cache.h"
|
||||
#include "string2.h"
|
||||
|
||||
@@ -791,16 +790,11 @@ static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
|
||||
* to the current running CPU. Then, add all PMU events from that table
|
||||
* as aliases.
|
||||
*/
|
||||
-static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
|
||||
+void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu,
|
||||
+ struct pmu_events_map *map)
|
||||
{
|
||||
int i;
|
||||
- struct pmu_events_map *map;
|
||||
const char *name = pmu->name;
|
||||
-
|
||||
- map = perf_pmu__find_map(pmu);
|
||||
- if (!map)
|
||||
- return;
|
||||
-
|
||||
/*
|
||||
* Found a matching PMU events table. Create aliases
|
||||
*/
|
||||
@@ -835,6 +829,17 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
|
||||
}
|
||||
}
|
||||
|
||||
+static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
|
||||
+{
|
||||
+ struct pmu_events_map *map;
|
||||
+
|
||||
+ map = perf_pmu__find_map(pmu);
|
||||
+ if (!map)
|
||||
+ return;
|
||||
+
|
||||
+ pmu_add_cpu_aliases_map(head, pmu, map);
|
||||
+}
|
||||
+
|
||||
struct perf_event_attr * __weak
|
||||
perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
|
||||
{
|
||||
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
|
||||
index a7f1d60c288b..acb6f0ebae08 100644
|
||||
--- a/tools/perf/util/pmu.h
|
||||
+++ b/tools/perf/util/pmu.h
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "evsel.h"
|
||||
#include "parse-events.h"
|
||||
+#include "pmu-events/pmu-events.h"
|
||||
|
||||
enum {
|
||||
PERF_PMU_FORMAT_VALUE_CONFIG,
|
||||
@@ -93,6 +94,8 @@ int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
|
||||
int perf_pmu__test(void);
|
||||
|
||||
struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu);
|
||||
+void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu,
|
||||
+ struct pmu_events_map *map);
|
||||
|
||||
struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
343
patches/0184-perf-test-Add-pmu-events-test.patch
Normal file
343
patches/0184-perf-test-Add-pmu-events-test.patch
Normal file
@ -0,0 +1,343 @@
|
||||
From 7f689e44b98883f5a5a8609cf2d179cb9e03addb Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Tue, 17 Mar 2020 19:02:16 +0800
|
||||
Subject: [PATCH 067/201] perf test: Add pmu-events test
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit a6c925fd3aa2aba043a73b0ad57ffd296e1c42c9
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a6c925fd3aa2aba043a73b0ad57ffd296e1c42c9
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The initial test will verify that the test tables in generated pmu-events.c
|
||||
match against known, expected values.
|
||||
|
||||
For known events added in pmu-events/arch/test, we need to add an entry
|
||||
in test_cpu_aliases_events[] or test_uncore_events[].
|
||||
|
||||
A sample run is as follows for x86:
|
||||
|
||||
john@linux-3c19:~/linux> tools/perf/perf test -vv 10
|
||||
10: PMU event aliases :
|
||||
--- start ---
|
||||
test child forked, pid 5316
|
||||
testing event table bp_l1_btb_correct: pass
|
||||
testing event table bp_l2_btb_correct: pass
|
||||
testing event table segment_reg_loads.any: pass
|
||||
testing event table dispatch_blocked.any: pass
|
||||
testing event table eist_trans: pass
|
||||
testing event table uncore_hisi_ddrc.flux_wcmd: pass
|
||||
testing event table unc_cbo_xsnp_response.miss_eviction: pass
|
||||
test child finished with 0
|
||||
---- end ----
|
||||
PMU event aliases: Ok
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: James Clark <james.clark@arm.com>
|
||||
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
[ Fixup test_cpu_events[] and test_uncore_events[] sentinels to initialize one of its members to NULL, fixing the build in older compilers ]
|
||||
Link: http://lore.kernel.org/lkml/1584442939-8911-5-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/Build | 1 +
|
||||
tools/perf/tests/builtin-test.c | 4 +
|
||||
tools/perf/tests/pmu-events.c | 233 ++++++++++++++++++++++++++++++++
|
||||
tools/perf/tests/tests.h | 1 +
|
||||
4 files changed, 239 insertions(+)
|
||||
create mode 100644 tools/perf/tests/pmu-events.c
|
||||
|
||||
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
|
||||
index e8fc36ed0979..d28758661fb7 100644
|
||||
--- a/tools/perf/tests/Build
|
||||
+++ b/tools/perf/tests/Build
|
||||
@@ -12,6 +12,7 @@ perf-y += evsel-roundtrip-name.o
|
||||
perf-y += evsel-tp-sched.o
|
||||
perf-y += fdarray.o
|
||||
perf-y += pmu.o
|
||||
+perf-y += pmu-events.o
|
||||
perf-y += hists_common.o
|
||||
perf-y += hists_link.o
|
||||
perf-y += hists_filter.o
|
||||
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
|
||||
index c71d19185ab3..729b6235ae43 100644
|
||||
--- a/tools/perf/tests/builtin-test.c
|
||||
+++ b/tools/perf/tests/builtin-test.c
|
||||
@@ -69,6 +69,10 @@ static struct test generic_tests[] = {
|
||||
.desc = "Parse perf pmu format",
|
||||
.func = test__pmu,
|
||||
},
|
||||
+ {
|
||||
+ .desc = "PMU events",
|
||||
+ .func = test__pmu_events,
|
||||
+ },
|
||||
{
|
||||
.desc = "DSO data read",
|
||||
.func = test__dso_data,
|
||||
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
|
||||
new file mode 100644
|
||||
index 000000000000..12fc29746a09
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/tests/pmu-events.c
|
||||
@@ -0,0 +1,233 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+#include "parse-events.h"
|
||||
+#include "pmu.h"
|
||||
+#include "tests.h"
|
||||
+#include <errno.h>
|
||||
+#include <stdio.h>
|
||||
+#include <linux/kernel.h>
|
||||
+
|
||||
+#include "debug.h"
|
||||
+#include "../pmu-events/pmu-events.h"
|
||||
+
|
||||
+struct perf_pmu_test_event {
|
||||
+ struct pmu_event event;
|
||||
+};
|
||||
+static struct perf_pmu_test_event test_cpu_events[] = {
|
||||
+ {
|
||||
+ .event = {
|
||||
+ .name = "bp_l1_btb_correct",
|
||||
+ .event = "event=0x8a",
|
||||
+ .desc = "L1 BTB Correction",
|
||||
+ .topic = "branch",
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .event = {
|
||||
+ .name = "bp_l2_btb_correct",
|
||||
+ .event = "event=0x8b",
|
||||
+ .desc = "L2 BTB Correction",
|
||||
+ .topic = "branch",
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .event = {
|
||||
+ .name = "segment_reg_loads.any",
|
||||
+ .event = "umask=0x80,period=200000,event=0x6",
|
||||
+ .desc = "Number of segment register loads",
|
||||
+ .topic = "other",
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .event = {
|
||||
+ .name = "dispatch_blocked.any",
|
||||
+ .event = "umask=0x20,period=200000,event=0x9",
|
||||
+ .desc = "Memory cluster signals to block micro-op dispatch for any reason",
|
||||
+ .topic = "other",
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .event = {
|
||||
+ .name = "eist_trans",
|
||||
+ .event = "umask=0x0,period=200000,event=0x3a",
|
||||
+ .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions",
|
||||
+ .topic = "other",
|
||||
+ },
|
||||
+ },
|
||||
+ { /* sentinel */
|
||||
+ .event = {
|
||||
+ .name = NULL,
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct perf_pmu_test_event test_uncore_events[] = {
|
||||
+ {
|
||||
+ .event = {
|
||||
+ .name = "uncore_hisi_ddrc.flux_wcmd",
|
||||
+ .event = "event=0x2",
|
||||
+ .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ",
|
||||
+ .topic = "uncore",
|
||||
+ .long_desc = "DDRC write commands",
|
||||
+ .pmu = "hisi_sccl,ddrc",
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .event = {
|
||||
+ .name = "unc_cbo_xsnp_response.miss_eviction",
|
||||
+ .event = "umask=0x81,event=0x22",
|
||||
+ .desc = "Unit: uncore_cbox A cross-core snoop resulted from L3 Eviction which misses in some processor core",
|
||||
+ .topic = "uncore",
|
||||
+ .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core",
|
||||
+ .pmu = "uncore_cbox",
|
||||
+ },
|
||||
+ },
|
||||
+ { /* sentinel */
|
||||
+ .event = {
|
||||
+ .name = NULL,
|
||||
+ },
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+const int total_test_events_size = ARRAY_SIZE(test_uncore_events);
|
||||
+
|
||||
+static bool is_same(const char *reference, const char *test)
|
||||
+{
|
||||
+ if (!reference && !test)
|
||||
+ return true;
|
||||
+
|
||||
+ if (reference && !test)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!reference && test)
|
||||
+ return false;
|
||||
+
|
||||
+ return !strcmp(reference, test);
|
||||
+}
|
||||
+
|
||||
+static struct pmu_events_map *__test_pmu_get_events_map(void)
|
||||
+{
|
||||
+ struct pmu_events_map *map;
|
||||
+
|
||||
+ for (map = &pmu_events_map[0]; map->cpuid; map++) {
|
||||
+ if (!strcmp(map->cpuid, "testcpu"))
|
||||
+ return map;
|
||||
+ }
|
||||
+
|
||||
+ pr_err("could not find test events map\n");
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* Verify generated events from pmu-events.c is as expected */
|
||||
+static int __test_pmu_event_table(void)
|
||||
+{
|
||||
+ struct pmu_events_map *map = __test_pmu_get_events_map();
|
||||
+ struct pmu_event *table;
|
||||
+ int map_events = 0, expected_events;
|
||||
+
|
||||
+ /* ignore 2x sentinels */
|
||||
+ expected_events = ARRAY_SIZE(test_cpu_events) +
|
||||
+ ARRAY_SIZE(test_uncore_events) - 2;
|
||||
+
|
||||
+ if (!map)
|
||||
+ return -1;
|
||||
+
|
||||
+ for (table = map->table; table->name; table++) {
|
||||
+ struct perf_pmu_test_event *test;
|
||||
+ struct pmu_event *te;
|
||||
+ bool found = false;
|
||||
+
|
||||
+ if (table->pmu)
|
||||
+ test = &test_uncore_events[0];
|
||||
+ else
|
||||
+ test = &test_cpu_events[0];
|
||||
+
|
||||
+ te = &test->event;
|
||||
+
|
||||
+ for (; te->name; test++, te = &test->event) {
|
||||
+ if (strcmp(table->name, te->name))
|
||||
+ continue;
|
||||
+ found = true;
|
||||
+ map_events++;
|
||||
+
|
||||
+ if (!is_same(table->desc, te->desc)) {
|
||||
+ pr_debug2("testing event table %s: mismatched desc, %s vs %s\n",
|
||||
+ table->name, table->desc, te->desc);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(table->topic, te->topic)) {
|
||||
+ pr_debug2("testing event table %s: mismatched topic, %s vs %s\n",
|
||||
+ table->name, table->topic,
|
||||
+ te->topic);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(table->long_desc, te->long_desc)) {
|
||||
+ pr_debug2("testing event table %s: mismatched long_desc, %s vs %s\n",
|
||||
+ table->name, table->long_desc,
|
||||
+ te->long_desc);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(table->unit, te->unit)) {
|
||||
+ pr_debug2("testing event table %s: mismatched unit, %s vs %s\n",
|
||||
+ table->name, table->unit,
|
||||
+ te->unit);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(table->perpkg, te->perpkg)) {
|
||||
+ pr_debug2("testing event table %s: mismatched perpkg, %s vs %s\n",
|
||||
+ table->name, table->perpkg,
|
||||
+ te->perpkg);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(table->metric_expr, te->metric_expr)) {
|
||||
+ pr_debug2("testing event table %s: mismatched metric_expr, %s vs %s\n",
|
||||
+ table->name, table->metric_expr,
|
||||
+ te->metric_expr);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(table->metric_name, te->metric_name)) {
|
||||
+ pr_debug2("testing event table %s: mismatched metric_name, %s vs %s\n",
|
||||
+ table->name, table->metric_name,
|
||||
+ te->metric_name);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(table->deprecated, te->deprecated)) {
|
||||
+ pr_debug2("testing event table %s: mismatched deprecated, %s vs %s\n",
|
||||
+ table->name, table->deprecated,
|
||||
+ te->deprecated);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ pr_debug("testing event table %s: pass\n", table->name);
|
||||
+ }
|
||||
+
|
||||
+ if (!found) {
|
||||
+ pr_err("testing event table: could not find event %s\n",
|
||||
+ table->name);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (map_events != expected_events) {
|
||||
+ pr_err("testing event table: found %d, but expected %d\n",
|
||||
+ map_events, expected_events);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+int test__pmu_events(struct test *test __maybe_unused,
|
||||
+ int subtest __maybe_unused)
|
||||
+{
|
||||
+ if (__test_pmu_event_table())
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
|
||||
index 591621b4d564..7c01a7812d21 100644
|
||||
--- a/tools/perf/tests/tests.h
|
||||
+++ b/tools/perf/tests/tests.h
|
||||
@@ -49,6 +49,7 @@ int test__perf_evsel__roundtrip_name_test(struct test *test, int subtest);
|
||||
int test__perf_evsel__tp_sched_test(struct test *test, int subtest);
|
||||
int test__syscall_openat_tp_fields(struct test *test, int subtest);
|
||||
int test__pmu(struct test *test, int subtest);
|
||||
+int test__pmu_events(struct test *test, int subtest);
|
||||
int test__attr(struct test *test, int subtest);
|
||||
int test__dso_data(struct test *test, int subtest);
|
||||
int test__dso_data_cache(struct test *test, int subtest);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
67
patches/0185-perf-pmu-Add-is_pmu_core.patch
Normal file
67
patches/0185-perf-pmu-Add-is_pmu_core.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From 020fdb75674fe4846546b65e819c92c2837fca86 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Tue, 17 Mar 2020 19:02:17 +0800
|
||||
Subject: [PATCH 068/201] perf pmu: Add is_pmu_core()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit d504fae93dd61b734aefc403c7653d958aef655a
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d504fae93dd61b734aefc403c7653d958aef655a
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add a function to decide whether a PMU is a core PMU.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: James Clark <james.clark@arm.com>
|
||||
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1584442939-8911-6-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/pmu.c | 5 +++++
|
||||
tools/perf/util/pmu.h | 1 +
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
|
||||
index 7053b0c5cdae..5f91e68dca66 100644
|
||||
--- a/tools/perf/util/pmu.c
|
||||
+++ b/tools/perf/util/pmu.c
|
||||
@@ -1417,6 +1417,11 @@ static void wordwrap(char *s, int start, int max, int corr)
|
||||
}
|
||||
}
|
||||
|
||||
+bool is_pmu_core(const char *name)
|
||||
+{
|
||||
+ return !strcmp(name, "cpu") || is_arm_pmu_core(name);
|
||||
+}
|
||||
+
|
||||
void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
|
||||
bool long_desc, bool details_flag, bool deprecated)
|
||||
{
|
||||
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
|
||||
index acb6f0ebae08..32db09d5b2b8 100644
|
||||
--- a/tools/perf/util/pmu.h
|
||||
+++ b/tools/perf/util/pmu.h
|
||||
@@ -84,6 +84,7 @@ int perf_pmu__format_parse(char *dir, struct list_head *head);
|
||||
|
||||
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
|
||||
|
||||
+bool is_pmu_core(const char *name);
|
||||
void print_pmu_events(const char *event_glob, bool name_only, bool quiet,
|
||||
bool long_desc, bool details_flag,
|
||||
bool deprecated);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
From c6e974eafd409282375fa753ac456c6235a27522 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Tue, 17 Mar 2020 19:02:18 +0800
|
||||
Subject: [PATCH 069/201] perf pmu: Make pmu_uncore_alias_match() public
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 5b9a50001b2c23f90f2a21db4763f3a9599588c4
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5b9a50001b2c23f90f2a21db4763f3a9599588c4
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The perf pmu-events test will want to use pmu_uncore_alias_match(), so
|
||||
make it public.
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: James Clark <james.clark@arm.com>
|
||||
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1584442939-8911-7-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/pmu.c | 2 +-
|
||||
tools/perf/util/pmu.h | 1 +
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
|
||||
index 5f91e68dca66..7eefbebbf990 100644
|
||||
--- a/tools/perf/util/pmu.c
|
||||
+++ b/tools/perf/util/pmu.c
|
||||
@@ -745,7 +745,7 @@ struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
|
||||
return map;
|
||||
}
|
||||
|
||||
-static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
|
||||
+bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
|
||||
{
|
||||
char *tmp = NULL, *tok, *str;
|
||||
bool res;
|
||||
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
|
||||
index 32db09d5b2b8..79f167db4a33 100644
|
||||
--- a/tools/perf/util/pmu.h
|
||||
+++ b/tools/perf/util/pmu.h
|
||||
@@ -99,6 +99,7 @@ void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu,
|
||||
struct pmu_events_map *map);
|
||||
|
||||
struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu);
|
||||
+bool pmu_uncore_alias_match(const char *pmu_name, const char *name);
|
||||
|
||||
int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
313
patches/0187-perf-test-Test-pmu-events-aliases.patch
Normal file
313
patches/0187-perf-test-Test-pmu-events-aliases.patch
Normal file
@ -0,0 +1,313 @@
|
||||
From 3f1220d13738b5f0d899f47d76bf1fc18e25d860 Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Tue, 17 Mar 2020 19:02:19 +0800
|
||||
Subject: [PATCH 070/201] perf test: Test pmu-events aliases
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.7-rc1
|
||||
commit 956a78356c24c1ac3becf854135dc065b6b74265
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=956a78356c24c1ac3becf854135dc065b6b74265
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add creating event aliases to the pmu-events test.
|
||||
|
||||
So currently we verify that the generated pmu-events.c is as expected for
|
||||
some test events. Now test that we generate aliases as expected for those
|
||||
events during normal operation.
|
||||
|
||||
For that, we cycle through each HW PMU in the system, and use the test
|
||||
events to create aliases, and verify those against known, expected values.
|
||||
|
||||
For core PMUs, we should create an alias for every event in
|
||||
test_cpu_events[].
|
||||
|
||||
However, for uncore PMUs, they need to be matched by the pmu_event.pmu
|
||||
member, so use test_uncore_events[]; so check the match beforehand with
|
||||
pmu_uncore_alias_match().
|
||||
|
||||
A sample run is as follows for my x86 machine:
|
||||
|
||||
john@linux-3c19:~/linux> tools/perf/perf test -vv 10
|
||||
10: PMU events :
|
||||
--- start ---
|
||||
|
||||
...
|
||||
|
||||
testing PMU uncore_arb aliases: no events to match
|
||||
testing PMU cstate_pkg aliases: no events to match
|
||||
skipping testing PMU breakpoint
|
||||
testing aliases PMU uncore_cbox_1: matched event unc_cbo_xsnp_response.miss_eviction
|
||||
testing PMU uncore_cbox_1 aliases: pass
|
||||
testing PMU power aliases: no events to match
|
||||
testing aliases PMU cpu: matched event bp_l1_btb_correct
|
||||
testing aliases PMU cpu: matched event bp_l2_btb_correct
|
||||
testing aliases PMU cpu: matched event segment_reg_loads.any
|
||||
testing aliases PMU cpu: matched event dispatch_blocked.any
|
||||
testing aliases PMU cpu: matched event eist_trans
|
||||
testing PMU cpu aliases: pass
|
||||
testing PMU intel_pt aliases: no events to match
|
||||
skipping testing PMU software
|
||||
skipping testing PMU intel_bts
|
||||
testing PMU uncore_imc aliases: no events to match
|
||||
testing aliases PMU uncore_cbox_0: matched event unc_cbo_xsnp_response.miss_eviction
|
||||
testing PMU uncore_cbox_0 aliases: pass
|
||||
testing PMU cstate_core aliases: no events to match
|
||||
skipping testing PMU tracepoint
|
||||
testing PMU msr aliases: no events to match
|
||||
test child finished with 0
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: James Clark <james.clark@arm.com>
|
||||
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: linuxarm@huawei.com
|
||||
Link: http://lore.kernel.org/lkml/1584442939-8911-8-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/tests/pmu-events.c
|
||||
---
|
||||
tools/perf/tests/pmu-events.c | 148 +++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 147 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
|
||||
index 12fc29746a09..c1f5aeec3a41 100644
|
||||
--- a/tools/perf/tests/pmu-events.c
|
||||
+++ b/tools/perf/tests/pmu-events.c
|
||||
@@ -5,13 +5,24 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <linux/kernel.h>
|
||||
-
|
||||
+#include "util.h"
|
||||
#include "debug.h"
|
||||
#include "../pmu-events/pmu-events.h"
|
||||
|
||||
struct perf_pmu_test_event {
|
||||
struct pmu_event event;
|
||||
+
|
||||
+ /* extra events for aliases */
|
||||
+ const char *alias_str;
|
||||
+
|
||||
+ /*
|
||||
+ * Note: For when PublicDescription does not exist in the JSON, we
|
||||
+ * will have no long_desc in pmu_event.long_desc, but long_desc may
|
||||
+ * be set in the alias.
|
||||
+ */
|
||||
+ const char *alias_long_desc;
|
||||
};
|
||||
+
|
||||
static struct perf_pmu_test_event test_cpu_events[] = {
|
||||
{
|
||||
.event = {
|
||||
@@ -20,6 +31,8 @@ static struct perf_pmu_test_event test_cpu_events[] = {
|
||||
.desc = "L1 BTB Correction",
|
||||
.topic = "branch",
|
||||
},
|
||||
+ .alias_str = "event=0x8a",
|
||||
+ .alias_long_desc = "L1 BTB Correction",
|
||||
},
|
||||
{
|
||||
.event = {
|
||||
@@ -28,6 +41,8 @@ static struct perf_pmu_test_event test_cpu_events[] = {
|
||||
.desc = "L2 BTB Correction",
|
||||
.topic = "branch",
|
||||
},
|
||||
+ .alias_str = "event=0x8b",
|
||||
+ .alias_long_desc = "L2 BTB Correction",
|
||||
},
|
||||
{
|
||||
.event = {
|
||||
@@ -36,6 +51,8 @@ static struct perf_pmu_test_event test_cpu_events[] = {
|
||||
.desc = "Number of segment register loads",
|
||||
.topic = "other",
|
||||
},
|
||||
+ .alias_str = "umask=0x80,(null)=0x30d40,event=0x6",
|
||||
+ .alias_long_desc = "Number of segment register loads",
|
||||
},
|
||||
{
|
||||
.event = {
|
||||
@@ -44,6 +61,8 @@ static struct perf_pmu_test_event test_cpu_events[] = {
|
||||
.desc = "Memory cluster signals to block micro-op dispatch for any reason",
|
||||
.topic = "other",
|
||||
},
|
||||
+ .alias_str = "umask=0x20,(null)=0x30d40,event=0x9",
|
||||
+ .alias_long_desc = "Memory cluster signals to block micro-op dispatch for any reason",
|
||||
},
|
||||
{
|
||||
.event = {
|
||||
@@ -52,6 +71,8 @@ static struct perf_pmu_test_event test_cpu_events[] = {
|
||||
.desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions",
|
||||
.topic = "other",
|
||||
},
|
||||
+ .alias_str = "umask=0,(null)=0x30d40,event=0x3a",
|
||||
+ .alias_long_desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions",
|
||||
},
|
||||
{ /* sentinel */
|
||||
.event = {
|
||||
@@ -70,6 +91,8 @@ static struct perf_pmu_test_event test_uncore_events[] = {
|
||||
.long_desc = "DDRC write commands",
|
||||
.pmu = "hisi_sccl,ddrc",
|
||||
},
|
||||
+ .alias_str = "event=0x2",
|
||||
+ .alias_long_desc = "DDRC write commands",
|
||||
},
|
||||
{
|
||||
.event = {
|
||||
@@ -80,6 +103,8 @@ static struct perf_pmu_test_event test_uncore_events[] = {
|
||||
.long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core",
|
||||
.pmu = "uncore_cbox",
|
||||
},
|
||||
+ .alias_str = "umask=0x81,event=0x22",
|
||||
+ .alias_long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core",
|
||||
},
|
||||
{ /* sentinel */
|
||||
.event = {
|
||||
@@ -223,11 +248,132 @@ static int __test_pmu_event_table(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+static struct perf_pmu_alias *find_alias(const char *test_event, struct list_head *aliases)
|
||||
+{
|
||||
+ struct perf_pmu_alias *alias;
|
||||
+
|
||||
+ list_for_each_entry(alias, aliases, list)
|
||||
+ if (!strcmp(test_event, alias->name))
|
||||
+ return alias;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* Verify aliases are as expected */
|
||||
+static int __test__pmu_event_aliases(char *pmu_name, int *count)
|
||||
+{
|
||||
+ struct perf_pmu_test_event *test;
|
||||
+ struct pmu_event *te;
|
||||
+ struct perf_pmu *pmu;
|
||||
+ LIST_HEAD(aliases);
|
||||
+ int res = 0;
|
||||
+ bool use_uncore_table;
|
||||
+ struct pmu_events_map *map = __test_pmu_get_events_map();
|
||||
+
|
||||
+ if (!map)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (is_pmu_core(pmu_name)) {
|
||||
+ test = &test_cpu_events[0];
|
||||
+ use_uncore_table = false;
|
||||
+ } else {
|
||||
+ test = &test_uncore_events[0];
|
||||
+ use_uncore_table = true;
|
||||
+ }
|
||||
+
|
||||
+ pmu = zalloc(sizeof(*pmu));
|
||||
+ if (!pmu)
|
||||
+ return -1;
|
||||
+
|
||||
+ pmu->name = pmu_name;
|
||||
+
|
||||
+ pmu_add_cpu_aliases_map(&aliases, pmu, map);
|
||||
+
|
||||
+ for (te = &test->event; te->name; test++, te = &test->event) {
|
||||
+ struct perf_pmu_alias *alias = find_alias(te->name, &aliases);
|
||||
+
|
||||
+ if (!alias) {
|
||||
+ bool uncore_match = pmu_uncore_alias_match(pmu_name,
|
||||
+ te->pmu);
|
||||
+
|
||||
+ if (use_uncore_table && !uncore_match) {
|
||||
+ pr_debug3("testing aliases PMU %s: skip matching alias %s\n",
|
||||
+ pmu_name, te->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ pr_debug2("testing aliases PMU %s: no alias, alias_table->name=%s\n",
|
||||
+ pmu_name, te->name);
|
||||
+ res = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(alias->desc, te->desc)) {
|
||||
+ pr_debug2("testing aliases PMU %s: mismatched desc, %s vs %s\n",
|
||||
+ pmu_name, alias->desc, te->desc);
|
||||
+ res = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(alias->long_desc, test->alias_long_desc)) {
|
||||
+ pr_debug2("testing aliases PMU %s: mismatched long_desc, %s vs %s\n",
|
||||
+ pmu_name, alias->long_desc,
|
||||
+ test->alias_long_desc);
|
||||
+ res = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(alias->str, test->alias_str)) {
|
||||
+ pr_debug2("testing aliases PMU %s: mismatched str, %s vs %s\n",
|
||||
+ pmu_name, alias->str, test->alias_str);
|
||||
+ res = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_same(alias->topic, te->topic)) {
|
||||
+ pr_debug2("testing aliases PMU %s: mismatched topic, %s vs %s\n",
|
||||
+ pmu_name, alias->topic, te->topic);
|
||||
+ res = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ (*count)++;
|
||||
+ pr_debug2("testing aliases PMU %s: matched event %s\n",
|
||||
+ pmu_name, alias->name);
|
||||
+ }
|
||||
+
|
||||
+ free(pmu);
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
int test__pmu_events(struct test *test __maybe_unused,
|
||||
int subtest __maybe_unused)
|
||||
{
|
||||
+ struct perf_pmu *pmu = NULL;
|
||||
+
|
||||
if (__test_pmu_event_table())
|
||||
return -1;
|
||||
|
||||
+ while ((pmu = perf_pmu__scan(pmu)) != NULL) {
|
||||
+ int count = 0;
|
||||
+
|
||||
+ if (list_empty(&pmu->format)) {
|
||||
+ pr_debug2("skipping testing PMU %s\n", pmu->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (__test__pmu_event_aliases(pmu->name, &count)) {
|
||||
+ pr_debug("testing PMU %s aliases: failed\n", pmu->name);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (count == 0)
|
||||
+ pr_debug3("testing PMU %s aliases: no events to match\n",
|
||||
+ pmu->name);
|
||||
+ else
|
||||
+ pr_debug("testing PMU %s aliases: pass\n", pmu->name);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
From 305bfee3d03a50055518a3831a790798fee0bd7f Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Fri, 1 May 2020 10:33:22 -0700
|
||||
Subject: [PATCH 071/201] perf expr: Allow for unlimited escaped characters in
|
||||
a symbol
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 5b3141d02645a36ccf9f08a67e08e8186dfef12c
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5b3141d02645a36ccf9f08a67e08e8186dfef12c
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Current expression allows 2 escaped '-,=' characters. However, some
|
||||
metrics require more, for example Haswell DRAM_BW_Use.
|
||||
|
||||
Fixes: 26226a97724d (perf expr: Move expr lexer to flex)
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Tested-by: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Haiyan Song <haiyanx.song@intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200501173333.227162-2-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.l | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
|
||||
index 74b9b59b1aa5..73db6a9ef97e 100644
|
||||
--- a/tools/perf/util/expr.l
|
||||
+++ b/tools/perf/util/expr.l
|
||||
@@ -86,7 +86,7 @@ number [0-9]+
|
||||
sch [-,=]
|
||||
spec \\{sch}
|
||||
sym [0-9a-zA-Z_\.:@?]+
|
||||
-symbol {spec}*{sym}*{spec}*{sym}*{spec}*{sym}
|
||||
+symbol ({spec}|{sym})+
|
||||
|
||||
%%
|
||||
struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
58
patches/0189-perf-expr-Allow-to-be-an-other-token.patch
Normal file
58
patches/0189-perf-expr-Allow-to-be-an-other-token.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 9126755cf32c45235b7a4154c830a9a1e6fa43a4 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Fri, 1 May 2020 10:33:25 -0700
|
||||
Subject: [PATCH 072/201] perf expr: Allow ',' to be an other token
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit cb59fa793e3c837ea6843dcec3bd6a0ea649f06b
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cb59fa793e3c837ea6843dcec3bd6a0ea649f06b
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Corrects parse errors in expr__find_other of expressions with min.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Haiyan Song <haiyanx.song@intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200501173333.227162-5-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.y | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
|
||||
index 2764b196edc3..74c9195860c5 100644
|
||||
--- a/tools/perf/util/expr.y
|
||||
+++ b/tools/perf/util/expr.y
|
||||
@@ -80,7 +80,7 @@ other: ID
|
||||
ctx->ids[ctx->num_ids++].name = $1;
|
||||
}
|
||||
|
|
||||
-MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')'
|
||||
+MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')' | ','
|
||||
|
||||
|
||||
all_expr: if_expr { *final_val = $1; }
|
||||
--
|
||||
2.27.0
|
||||
|
||||
59
patches/0190-perf-expr-Increase-max-other.patch
Normal file
59
patches/0190-perf-expr-Increase-max-other.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 0a1805781415cdde112ceebd08d6b5b1de887257 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Fri, 1 May 2020 10:33:26 -0700
|
||||
Subject: [PATCH 073/201] perf expr: Increase max other
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit f59d3f84a03c54bc394ba9727bf15818e4f86286
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f59d3f84a03c54bc394ba9727bf15818e4f86286
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Large metrics such as Branch_Misprediction_Cost_SMT on x86 broadwell
|
||||
need more space.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Haiyan Song <haiyanx.song@intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200501173333.227162-6-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index 87d627bb699b..40fc452b0f2b 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -2,7 +2,7 @@
|
||||
#ifndef PARSE_CTX_H
|
||||
#define PARSE_CTX_H 1
|
||||
|
||||
-#define EXPR_MAX_OTHER 20
|
||||
+#define EXPR_MAX_OTHER 64
|
||||
#define MAX_PARSE_ID EXPR_MAX_OTHER
|
||||
|
||||
struct expr_parse_id {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
100
patches/0191-perf-expr-Parse-numbers-as-doubles.patch
Normal file
100
patches/0191-perf-expr-Parse-numbers-as-doubles.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From aa1a1e03838793bba152e39f27bffbf05d03b143 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Fri, 1 May 2020 10:33:27 -0700
|
||||
Subject: [PATCH 074/201] perf expr: Parse numbers as doubles
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 7db2fd0b211394be8b4c7caadc943d0d7ca86357
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7db2fd0b211394be8b4c7caadc943d0d7ca86357
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This is expected in expr.y and metrics use floating point values such as
|
||||
x86 broadwell IFetch_Line_Utilization.
|
||||
|
||||
Fixes: 26226a97724d (perf expr: Move expr lexer to flex)
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Tested-by: Kajol Jain <kjain@linux.ibm.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Haiyan Song <haiyanx.song@intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200501173333.227162-7-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/expr.l | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
|
||||
index 73db6a9ef97e..ceab11bea6f9 100644
|
||||
--- a/tools/perf/util/expr.l
|
||||
+++ b/tools/perf/util/expr.l
|
||||
@@ -10,12 +10,12 @@
|
||||
char *expr_get_text(yyscan_t yyscanner);
|
||||
YYSTYPE *expr_get_lval(yyscan_t yyscanner);
|
||||
|
||||
-static int __value(YYSTYPE *yylval, char *str, int base, int token)
|
||||
+static double __value(YYSTYPE *yylval, char *str, int token)
|
||||
{
|
||||
- u64 num;
|
||||
+ double num;
|
||||
|
||||
errno = 0;
|
||||
- num = strtoull(str, NULL, base);
|
||||
+ num = strtod(str, NULL);
|
||||
if (errno)
|
||||
return EXPR_ERROR;
|
||||
|
||||
@@ -23,12 +23,12 @@ static int __value(YYSTYPE *yylval, char *str, int base, int token)
|
||||
return token;
|
||||
}
|
||||
|
||||
-static int value(yyscan_t scanner, int base)
|
||||
+static int value(yyscan_t scanner)
|
||||
{
|
||||
YYSTYPE *yylval = expr_get_lval(scanner);
|
||||
char *text = expr_get_text(scanner);
|
||||
|
||||
- return __value(yylval, text, base, NUMBER);
|
||||
+ return __value(yylval, text, NUMBER);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,7 +81,7 @@ static int str(yyscan_t scanner, int token, int runtime)
|
||||
}
|
||||
%}
|
||||
|
||||
-number [0-9]+
|
||||
+number [0-9]*\.?[0-9]+
|
||||
|
||||
sch [-,=]
|
||||
spec \\{sch}
|
||||
@@ -105,7 +105,7 @@ min { return MIN; }
|
||||
if { return IF; }
|
||||
else { return ELSE; }
|
||||
#smt_on { return SMT_ON; }
|
||||
-{number} { return value(yyscanner, 10); }
|
||||
+{number} { return value(yyscanner); }
|
||||
{symbol} { return str(yyscanner, ID, sctx->runtime); }
|
||||
"|" { return '|'; }
|
||||
"^" { return '^'; }
|
||||
--
|
||||
2.27.0
|
||||
|
||||
311
patches/0192-perf-test-Improve-pmu-event-metric-testing.patch
Normal file
311
patches/0192-perf-test-Improve-pmu-event-metric-testing.patch
Normal file
@ -0,0 +1,311 @@
|
||||
From 44fb932a73686d9d773162e3a9c912b1caf4ce3c Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 13 May 2020 14:29:33 -0700
|
||||
Subject: [PATCH 075/201] perf test: Improve pmu event metric testing
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 06392aaad592cadf4335617a2bb8e45722e3df33
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=06392aaad592cadf4335617a2bb8e45722e3df33
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Break pmu-events test into 2 and add a test to verify that all pmu
|
||||
metric expressions simply parse. Try to parse all metric ids/events,
|
||||
skip/warn if metrics for the current architecture fail to parse. To
|
||||
support warning for a skip, and an ability for a subtest to describe why
|
||||
it skips.
|
||||
|
||||
Tested on power9, skylakex, haswell, broadwell, westmere, sandybridge and
|
||||
ivybridge.
|
||||
|
||||
May skip/warn on other architectures if metrics are invalid. In
|
||||
particular s390 is untested, but its expressions are trivial. The
|
||||
untested architectures with expressions are power8, cascadelakex,
|
||||
tremontx, skylake, jaketown, ivytown and variants of haswell and
|
||||
broadwell.
|
||||
|
||||
v3. addresses review comments from John Garry <john.garry@huawei.com>,
|
||||
Jiri Olsa <jolsa@redhat.com> and Arnaldo Carvalho de Melo
|
||||
<acme@kernel.org>.
|
||||
v2. changes the commit message as event parsing errors no longer cause
|
||||
the test to fail.
|
||||
|
||||
Committer notes:
|
||||
|
||||
Check the return value of strtod() to fix the build in systems where
|
||||
that function is declared with attribute warn_unused_result.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200513212933.41273-1-irogers@google.com
|
||||
[ split from a larger patch ]
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/tests/pmu-events.c
|
||||
---
|
||||
tools/perf/tests/builtin-test.c | 7 ++
|
||||
tools/perf/tests/pmu-events.c | 170 ++++++++++++++++++++++++++++++--
|
||||
tools/perf/tests/tests.h | 3 +
|
||||
3 files changed, 174 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
|
||||
index 729b6235ae43..1925f170478c 100644
|
||||
--- a/tools/perf/tests/builtin-test.c
|
||||
+++ b/tools/perf/tests/builtin-test.c
|
||||
@@ -72,6 +72,13 @@ static struct test generic_tests[] = {
|
||||
{
|
||||
.desc = "PMU events",
|
||||
.func = test__pmu_events,
|
||||
+ .subtest = {
|
||||
+ .skip_if_fail = false,
|
||||
+ .get_nr = test__pmu_events_subtest_get_nr,
|
||||
+ .get_desc = test__pmu_events_subtest_get_desc,
|
||||
+ .skip_reason = test__pmu_events_subtest_skip_reason,
|
||||
+ },
|
||||
+
|
||||
},
|
||||
{
|
||||
.desc = "DSO data read",
|
||||
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
|
||||
index c1f5aeec3a41..233806382300 100644
|
||||
--- a/tools/perf/tests/pmu-events.c
|
||||
+++ b/tools/perf/tests/pmu-events.c
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
+#include "math.h"
|
||||
#include "parse-events.h"
|
||||
#include "pmu.h"
|
||||
#include "tests.h"
|
||||
@@ -8,6 +9,9 @@
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
#include "../pmu-events/pmu-events.h"
|
||||
+#include "util/evlist.h"
|
||||
+#include "util/expr.h"
|
||||
+#include "util/parse-events.h"
|
||||
|
||||
struct perf_pmu_test_event {
|
||||
struct pmu_event event;
|
||||
@@ -144,7 +148,7 @@ static struct pmu_events_map *__test_pmu_get_events_map(void)
|
||||
}
|
||||
|
||||
/* Verify generated events from pmu-events.c is as expected */
|
||||
-static int __test_pmu_event_table(void)
|
||||
+static int test_pmu_event_table(void)
|
||||
{
|
||||
struct pmu_events_map *map = __test_pmu_get_events_map();
|
||||
struct pmu_event *table;
|
||||
@@ -347,14 +351,11 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count)
|
||||
return res;
|
||||
}
|
||||
|
||||
-int test__pmu_events(struct test *test __maybe_unused,
|
||||
- int subtest __maybe_unused)
|
||||
+
|
||||
+static int test_aliases(void)
|
||||
{
|
||||
struct perf_pmu *pmu = NULL;
|
||||
|
||||
- if (__test_pmu_event_table())
|
||||
- return -1;
|
||||
-
|
||||
while ((pmu = perf_pmu__scan(pmu)) != NULL) {
|
||||
int count = 0;
|
||||
|
||||
@@ -377,3 +378,160 @@ int test__pmu_events(struct test *test __maybe_unused,
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+static bool is_number(const char *str)
|
||||
+{
|
||||
+ char *end_ptr;
|
||||
+ double v;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ v = strtod(str, &end_ptr);
|
||||
+ (void)v; // We're not interested in this value, only if it is valid
|
||||
+ return errno == 0 && end_ptr != str;
|
||||
+}
|
||||
+
|
||||
+static int check_parse_id(const char *id, bool same_cpu, struct pmu_event *pe)
|
||||
+{
|
||||
+ struct parse_events_error error;
|
||||
+ struct perf_evlist *evlist;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Numbers are always valid. */
|
||||
+ if (is_number(id))
|
||||
+ return 0;
|
||||
+
|
||||
+ evlist = perf_evlist__new();
|
||||
+ memset(&error, 0, sizeof(error));
|
||||
+ ret = parse_events(evlist, id, &error);
|
||||
+ if (ret && same_cpu) {
|
||||
+ pr_warning("Parse event failed metric '%s' id '%s' expr '%s'\n",
|
||||
+ pe->metric_name, id, pe->metric_expr);
|
||||
+ pr_warning("Error string '%s' help '%s'\n", error.str,
|
||||
+ error.help);
|
||||
+ } else if (ret) {
|
||||
+ pr_debug3("Parse event failed, but for an event that may not be supported by this CPU.\nid '%s' metric '%s' expr '%s'\n",
|
||||
+ id, pe->metric_name, pe->metric_expr);
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ perf_evlist__delete(evlist);
|
||||
+ free(error.str);
|
||||
+ free(error.help);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void expr_failure(const char *msg,
|
||||
+ const struct pmu_events_map *map,
|
||||
+ const struct pmu_event *pe)
|
||||
+{
|
||||
+ pr_debug("%s for map %s %s %s\n",
|
||||
+ msg, map->cpuid, map->version, map->type);
|
||||
+ pr_debug("On metric %s\n", pe->metric_name);
|
||||
+ pr_debug("On expression %s\n", pe->metric_expr);
|
||||
+}
|
||||
+
|
||||
+static int test_parsing(void)
|
||||
+{
|
||||
+ struct pmu_events_map *cpus_map = perf_pmu__find_map(NULL);
|
||||
+ struct pmu_events_map *map;
|
||||
+ struct pmu_event *pe;
|
||||
+ int i, j, k;
|
||||
+ const char **ids;
|
||||
+ int idnum;
|
||||
+ int ret = 0;
|
||||
+ struct expr_parse_ctx ctx;
|
||||
+ double result;
|
||||
+
|
||||
+ i = 0;
|
||||
+ for (;;) {
|
||||
+ map = &pmu_events_map[i++];
|
||||
+ if (!map->table)
|
||||
+ break;
|
||||
+ j = 0;
|
||||
+ for (;;) {
|
||||
+ pe = &map->table[j++];
|
||||
+ if (!pe->name && !pe->metric_group && !pe->metric_name)
|
||||
+ break;
|
||||
+ if (!pe->metric_expr)
|
||||
+ continue;
|
||||
+ if (expr__find_other(pe->metric_expr, NULL,
|
||||
+ &ids, &idnum, 0) < 0) {
|
||||
+ expr_failure("Parse other failed", map, pe);
|
||||
+ ret++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ expr__ctx_init(&ctx);
|
||||
+
|
||||
+ /*
|
||||
+ * Add all ids with a made up value. The value may
|
||||
+ * trigger divide by zero when subtracted and so try to
|
||||
+ * make them unique.
|
||||
+ */
|
||||
+ for (k = 0; k < idnum; k++)
|
||||
+ expr__add_id(&ctx, ids[k], k + 1);
|
||||
+
|
||||
+ for (k = 0; k < idnum; k++) {
|
||||
+ if (check_parse_id(ids[k], map == cpus_map, pe))
|
||||
+ ret++;
|
||||
+ }
|
||||
+
|
||||
+ if (expr__parse(&result, &ctx, pe->metric_expr, 0)) {
|
||||
+ expr_failure("Parse failed", map, pe);
|
||||
+ ret++;
|
||||
+ }
|
||||
+ for (k = 0; k < idnum; k++)
|
||||
+ zfree(&ids[k]);
|
||||
+ free(ids);
|
||||
+ }
|
||||
+ }
|
||||
+ /* TODO: fail when not ok */
|
||||
+ return ret == 0 ? TEST_OK : TEST_SKIP;
|
||||
+}
|
||||
+
|
||||
+static const struct {
|
||||
+ int (*func)(void);
|
||||
+ const char *desc;
|
||||
+} pmu_events_testcase_table[] = {
|
||||
+ {
|
||||
+ .func = test_pmu_event_table,
|
||||
+ .desc = "PMU event table sanity",
|
||||
+ },
|
||||
+ {
|
||||
+ .func = test_aliases,
|
||||
+ .desc = "PMU event map aliases",
|
||||
+ },
|
||||
+ {
|
||||
+ .func = test_parsing,
|
||||
+ .desc = "Parsing of PMU event table metrics",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+const char *test__pmu_events_subtest_get_desc(int subtest)
|
||||
+{
|
||||
+ if (subtest < 0 ||
|
||||
+ subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table))
|
||||
+ return NULL;
|
||||
+ return pmu_events_testcase_table[subtest].desc;
|
||||
+}
|
||||
+
|
||||
+const char *test__pmu_events_subtest_skip_reason(int subtest)
|
||||
+{
|
||||
+ if (subtest < 0 ||
|
||||
+ subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table))
|
||||
+ return NULL;
|
||||
+ if (pmu_events_testcase_table[subtest].func != test_parsing)
|
||||
+ return NULL;
|
||||
+ return "some metrics failed";
|
||||
+}
|
||||
+
|
||||
+int test__pmu_events_subtest_get_nr(void)
|
||||
+{
|
||||
+ return (int)ARRAY_SIZE(pmu_events_testcase_table);
|
||||
+}
|
||||
+
|
||||
+int test__pmu_events(struct test *test __maybe_unused, int subtest)
|
||||
+{
|
||||
+ if (subtest < 0 ||
|
||||
+ subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table))
|
||||
+ return TEST_FAIL;
|
||||
+ return pmu_events_testcase_table[subtest].func();
|
||||
+}
|
||||
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
|
||||
index 7c01a7812d21..7d2997c9fca7 100644
|
||||
--- a/tools/perf/tests/tests.h
|
||||
+++ b/tools/perf/tests/tests.h
|
||||
@@ -50,6 +50,9 @@ int test__perf_evsel__tp_sched_test(struct test *test, int subtest);
|
||||
int test__syscall_openat_tp_fields(struct test *test, int subtest);
|
||||
int test__pmu(struct test *test, int subtest);
|
||||
int test__pmu_events(struct test *test, int subtest);
|
||||
+const char *test__pmu_events_subtest_get_desc(int subtest);
|
||||
+const char *test__pmu_events_subtest_skip_reason(int subtest);
|
||||
+int test__pmu_events_subtest_get_nr(void);
|
||||
int test__attr(struct test *test, int subtest);
|
||||
int test__dso_data(struct test *test, int subtest);
|
||||
int test__dso_data_cache(struct test *test, int subtest);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
From 2fcba35dbd7a5173a3e38190b5fb8e659d6ed091 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 13 May 2020 14:29:33 -0700
|
||||
Subject: [PATCH 076/201] perf test: Provide a subtest callback to ask for the
|
||||
reason for skipping a subtest
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 3b536651eeb7667808de7651f0858c932a3c4138
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3b536651eeb7667808de7651f0858c932a3c4138
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Now subtests can inform why a test was skipped. The upcoming patch
|
||||
improvint PMU event metric testing will use it.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200513212933.41273-1-irogers@google.com
|
||||
[ split from a larger patch ]
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/builtin-test.c | 11 +++++++++--
|
||||
tools/perf/tests/tests.h | 1 +
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
|
||||
index 1925f170478c..b4b1e34aaef4 100644
|
||||
--- a/tools/perf/tests/builtin-test.c
|
||||
+++ b/tools/perf/tests/builtin-test.c
|
||||
@@ -406,8 +406,15 @@ static int test_and_print(struct test *t, bool force_skip, int subtest)
|
||||
case TEST_OK:
|
||||
pr_info(" Ok\n");
|
||||
break;
|
||||
- case TEST_SKIP:
|
||||
- color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
|
||||
+ case TEST_SKIP: {
|
||||
+ const char *skip_reason = NULL;
|
||||
+ if (t->subtest.skip_reason)
|
||||
+ skip_reason = t->subtest.skip_reason(subtest);
|
||||
+ if (skip_reason)
|
||||
+ color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", skip_reason);
|
||||
+ else
|
||||
+ color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
|
||||
+ }
|
||||
break;
|
||||
case TEST_FAIL:
|
||||
default:
|
||||
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
|
||||
index 7d2997c9fca7..897ca3e7812c 100644
|
||||
--- a/tools/perf/tests/tests.h
|
||||
+++ b/tools/perf/tests/tests.h
|
||||
@@ -34,6 +34,7 @@ struct test {
|
||||
bool skip_if_fail;
|
||||
int (*get_nr)(void);
|
||||
const char *(*get_desc)(int subtest);
|
||||
+ const char *(*skip_reason)(int subtest);
|
||||
} subtest;
|
||||
bool (*is_supported)(void);
|
||||
void *priv;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
825
patches/0194-perf-expr-Migrate-expr-ids-table-to-a-hashmap.patch
Normal file
825
patches/0194-perf-expr-Migrate-expr-ids-table-to-a-hashmap.patch
Normal file
@ -0,0 +1,825 @@
|
||||
From 8282a38ff6fc730bed66c3ce0f5db1be05813f6d Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Fri, 15 May 2020 15:17:32 -0700
|
||||
Subject: [PATCH 077/201] perf expr: Migrate expr ids table to a hashmap
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit ded80bda8bc9bb65a344b79b36d5acf45a907b25
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ded80bda8bc9bb65a344b79b36d5acf45a907b25
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Use a hashmap between a char* string and a double* value. While bpf's
|
||||
hashmap entries are size_t in size, we can't guarantee sizeof(size_t) >=
|
||||
sizeof(double). Avoid a memory allocation when gathering ids by making
|
||||
0.0 a special value encoded as NULL.
|
||||
|
||||
Original map suggestion by Andi Kleen:
|
||||
|
||||
https://lore.kernel.org/lkml/20200224210308.GQ160988@tassilo.jf.intel.com/
|
||||
|
||||
and seconded by Jiri Olsa:
|
||||
|
||||
https://lore.kernel.org/lkml/20200423112915.GH1136647@krava/
|
||||
|
||||
Committer notes:
|
||||
|
||||
There are fixes that need to land upstream before we can use libbpf's
|
||||
headers, for now use our copy unconditionally, since the data structures
|
||||
at this point are exactly the same, no problem.
|
||||
|
||||
When the fixes for libbpf's hashmap land upstream, we can fix this up.
|
||||
|
||||
Testing it:
|
||||
|
||||
Building with LIBBPF=1, i.e. the default:
|
||||
|
||||
$ perf -vv | grep -i bpf
|
||||
bpf: [ on ] # HAVE_LIBBPF_SUPPORT
|
||||
$ nm ~/bin/perf | grep -i libbpf_ | wc -l
|
||||
39
|
||||
$ nm ~/bin/perf | grep -i hashmap_ | wc -l
|
||||
17
|
||||
$
|
||||
|
||||
Explicitely building without LIBBPF:
|
||||
|
||||
$ perf -vv | grep -i bpf
|
||||
bpf: [ OFF ] # HAVE_LIBBPF_SUPPORT
|
||||
$
|
||||
$ nm ~/bin/perf | grep -i libbpf_ | wc -l
|
||||
0
|
||||
$ nm ~/bin/perf | grep -i hashmap_ | wc -l
|
||||
9
|
||||
$
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Alexei Starovoitov <ast@kernel.org>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: John Fastabend <john.fastabend@gmail.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Leo Yan <leo.yan@linaro.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Martin KaFai Lau <kafai@fb.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Yonghong Song <yhs@fb.com>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: kp singh <kpsingh@chromium.org>
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200515221732.44078-8-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
tools/perf/util/stat-shadow.c
|
||||
---
|
||||
tools/perf/tests/expr.c | 44 ++++++------
|
||||
tools/perf/tests/pmu-events.c | 25 +++----
|
||||
tools/perf/util/expr.c | 129 +++++++++++++++++++---------------
|
||||
tools/perf/util/expr.h | 29 ++++----
|
||||
tools/perf/util/expr.y | 22 +-----
|
||||
tools/perf/util/metricgroup.c | 92 +++++++++++-------------
|
||||
tools/perf/util/stat-shadow.c | 49 ++++++++-----
|
||||
7 files changed, 200 insertions(+), 190 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
|
||||
index d7f74094f935..13c4243110d8 100644
|
||||
--- a/tools/perf/tests/expr.c
|
||||
+++ b/tools/perf/tests/expr.c
|
||||
@@ -17,15 +17,13 @@ static int test(struct expr_parse_ctx *ctx, const char *e, double val2)
|
||||
int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
{
|
||||
const char *p;
|
||||
- const char **other;
|
||||
- double val;
|
||||
- int i, ret;
|
||||
+ double val, *val_ptr;
|
||||
+ int ret;
|
||||
struct expr_parse_ctx ctx;
|
||||
- int num_other;
|
||||
|
||||
expr__ctx_init(&ctx);
|
||||
- expr__add_id(&ctx, "FOO", 1);
|
||||
- expr__add_id(&ctx, "BAR", 2);
|
||||
+ expr__add_id(&ctx, strdup("FOO"), 1);
|
||||
+ expr__add_id(&ctx, strdup("BAR"), 2);
|
||||
|
||||
ret = test(&ctx, "1+1", 2);
|
||||
ret |= test(&ctx, "FOO+BAR", 3);
|
||||
@@ -49,25 +47,29 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
ret = expr__parse(&val, &ctx, p, 1);
|
||||
TEST_ASSERT_VAL("missing operand", ret == -1);
|
||||
|
||||
+ expr__ctx_clear(&ctx);
|
||||
TEST_ASSERT_VAL("find other",
|
||||
- expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", &other, &num_other, 1) == 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);
|
||||
+ expr__find_other("FOO + BAR + BAZ + BOZO", "FOO",
|
||||
+ &ctx, 1) == 0);
|
||||
+ TEST_ASSERT_VAL("find other", hashmap__size(&ctx.ids) == 3);
|
||||
+ TEST_ASSERT_VAL("find other", hashmap__find(&ctx.ids, "BAR",
|
||||
+ (void **)&val_ptr));
|
||||
+ TEST_ASSERT_VAL("find other", hashmap__find(&ctx.ids, "BAZ",
|
||||
+ (void **)&val_ptr));
|
||||
+ TEST_ASSERT_VAL("find other", hashmap__find(&ctx.ids, "BOZO",
|
||||
+ (void **)&val_ptr));
|
||||
|
||||
+ expr__ctx_clear(&ctx);
|
||||
TEST_ASSERT_VAL("find other",
|
||||
- expr__find_other("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@", NULL,
|
||||
- &other, &num_other, 3) == 0);
|
||||
- TEST_ASSERT_VAL("find other", num_other == 2);
|
||||
- TEST_ASSERT_VAL("find other", !strcmp(other[0], "EVENT1,param=3/"));
|
||||
- TEST_ASSERT_VAL("find other", !strcmp(other[1], "EVENT2,param=3/"));
|
||||
- TEST_ASSERT_VAL("find other", other[2] == NULL);
|
||||
+ expr__find_other("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@",
|
||||
+ NULL, &ctx, 3) == 0);
|
||||
+ TEST_ASSERT_VAL("find other", hashmap__size(&ctx.ids) == 2);
|
||||
+ TEST_ASSERT_VAL("find other", hashmap__find(&ctx.ids, "EVENT1,param=3/",
|
||||
+ (void **)&val_ptr));
|
||||
+ TEST_ASSERT_VAL("find other", hashmap__find(&ctx.ids, "EVENT2,param=3/",
|
||||
+ (void **)&val_ptr));
|
||||
|
||||
- for (i = 0; i < num_other; i++)
|
||||
- free((void *)other[i]);
|
||||
- free((void *)other);
|
||||
+ expr__ctx_clear(&ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
|
||||
index 233806382300..41dab7e36761 100644
|
||||
--- a/tools/perf/tests/pmu-events.c
|
||||
+++ b/tools/perf/tests/pmu-events.c
|
||||
@@ -435,8 +435,6 @@ static int test_parsing(void)
|
||||
struct pmu_events_map *map;
|
||||
struct pmu_event *pe;
|
||||
int i, j, k;
|
||||
- const char **ids;
|
||||
- int idnum;
|
||||
int ret = 0;
|
||||
struct expr_parse_ctx ctx;
|
||||
double result;
|
||||
@@ -448,29 +446,34 @@ static int test_parsing(void)
|
||||
break;
|
||||
j = 0;
|
||||
for (;;) {
|
||||
+ struct hashmap_entry *cur;
|
||||
+ size_t bkt;
|
||||
+
|
||||
pe = &map->table[j++];
|
||||
if (!pe->name && !pe->metric_group && !pe->metric_name)
|
||||
break;
|
||||
if (!pe->metric_expr)
|
||||
continue;
|
||||
- if (expr__find_other(pe->metric_expr, NULL,
|
||||
- &ids, &idnum, 0) < 0) {
|
||||
+ expr__ctx_init(&ctx);
|
||||
+ if (expr__find_other(pe->metric_expr, NULL, &ctx, 0)
|
||||
+ < 0) {
|
||||
expr_failure("Parse other failed", map, pe);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
- expr__ctx_init(&ctx);
|
||||
|
||||
/*
|
||||
* Add all ids with a made up value. The value may
|
||||
* trigger divide by zero when subtracted and so try to
|
||||
* make them unique.
|
||||
*/
|
||||
- for (k = 0; k < idnum; k++)
|
||||
- expr__add_id(&ctx, ids[k], k + 1);
|
||||
+ k = 1;
|
||||
+ hashmap__for_each_entry((&ctx.ids), cur, bkt)
|
||||
+ expr__add_id(&ctx, strdup(cur->key), k++);
|
||||
|
||||
- for (k = 0; k < idnum; k++) {
|
||||
- if (check_parse_id(ids[k], map == cpus_map, pe))
|
||||
+ hashmap__for_each_entry((&ctx.ids), cur, bkt) {
|
||||
+ if (check_parse_id(cur->key, map == cpus_map,
|
||||
+ pe))
|
||||
ret++;
|
||||
}
|
||||
|
||||
@@ -478,9 +481,7 @@ static int test_parsing(void)
|
||||
expr_failure("Parse failed", map, pe);
|
||||
ret++;
|
||||
}
|
||||
- for (k = 0; k < idnum; k++)
|
||||
- zfree(&ids[k]);
|
||||
- free(ids);
|
||||
+ expr__ctx_clear(&ctx);
|
||||
}
|
||||
}
|
||||
/* TODO: fail when not ok */
|
||||
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
|
||||
index aa631e37ad1e..8ab40b42d3e6 100644
|
||||
--- a/tools/perf/util/expr.c
|
||||
+++ b/tools/perf/util/expr.c
|
||||
@@ -4,25 +4,76 @@
|
||||
#include "expr.h"
|
||||
#include "expr-bison.h"
|
||||
#include "expr-flex.h"
|
||||
+#include <linux/kernel.h>
|
||||
|
||||
#ifdef PARSER_DEBUG
|
||||
extern int expr_debug;
|
||||
#endif
|
||||
|
||||
+static size_t key_hash(const void *key, void *ctx __maybe_unused)
|
||||
+{
|
||||
+ const char *str = (const char *)key;
|
||||
+ size_t hash = 0;
|
||||
+
|
||||
+ while (*str != '\0') {
|
||||
+ hash *= 31;
|
||||
+ hash += *str;
|
||||
+ str++;
|
||||
+ }
|
||||
+ return hash;
|
||||
+}
|
||||
+
|
||||
+static bool key_equal(const void *key1, const void *key2,
|
||||
+ void *ctx __maybe_unused)
|
||||
+{
|
||||
+ return !strcmp((const char *)key1, (const char *)key2);
|
||||
+}
|
||||
+
|
||||
/* Caller must make sure id is allocated */
|
||||
-void expr__add_id(struct expr_parse_ctx *ctx, const char *name, double val)
|
||||
+int expr__add_id(struct expr_parse_ctx *ctx, const char *name, double val)
|
||||
{
|
||||
- int idx;
|
||||
+ double *val_ptr = NULL, *old_val = NULL;
|
||||
+ char *old_key = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (val != 0.0) {
|
||||
+ val_ptr = malloc(sizeof(double));
|
||||
+ if (!val_ptr)
|
||||
+ return -ENOMEM;
|
||||
+ *val_ptr = val;
|
||||
+ }
|
||||
+ ret = hashmap__set(&ctx->ids, name, val_ptr,
|
||||
+ (const void **)&old_key, (void **)&old_val);
|
||||
+ free(old_key);
|
||||
+ free(old_val);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int expr__get_id(struct expr_parse_ctx *ctx, const char *id, double *val_ptr)
|
||||
+{
|
||||
+ double *data;
|
||||
|
||||
- assert(ctx->num_ids < MAX_PARSE_ID);
|
||||
- idx = ctx->num_ids++;
|
||||
- ctx->ids[idx].name = name;
|
||||
- ctx->ids[idx].val = val;
|
||||
+ if (!hashmap__find(&ctx->ids, id, (void **)&data))
|
||||
+ return -1;
|
||||
+ *val_ptr = (data == NULL) ? 0.0 : *data;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void expr__ctx_init(struct expr_parse_ctx *ctx)
|
||||
{
|
||||
- ctx->num_ids = 0;
|
||||
+ hashmap__init(&ctx->ids, key_hash, key_equal, NULL);
|
||||
+}
|
||||
+
|
||||
+void expr__ctx_clear(struct expr_parse_ctx *ctx)
|
||||
+{
|
||||
+ struct hashmap_entry *cur;
|
||||
+ size_t bkt;
|
||||
+
|
||||
+ hashmap__for_each_entry((&ctx->ids), cur, bkt) {
|
||||
+ free((char *)cur->key);
|
||||
+ free(cur->value);
|
||||
+ }
|
||||
+ hashmap__clear(&ctx->ids);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -55,61 +106,25 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr, int runtime)
|
||||
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
|
||||
+ const char *expr, int runtime)
|
||||
{
|
||||
return __expr__parse(final_val, ctx, expr, EXPR_PARSE, runtime) ? -1 : 0;
|
||||
}
|
||||
|
||||
-static bool
|
||||
-already_seen(const char *val, const char *one, const char **other,
|
||||
- int num_other)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- if (one && !strcasecmp(one, val))
|
||||
- return true;
|
||||
- for (i = 0; i < num_other; i++)
|
||||
- if (!strcasecmp(other[i], val))
|
||||
- return true;
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
- int *num_other, int runtime)
|
||||
+int expr__find_other(const char *expr, const char *one,
|
||||
+ struct expr_parse_ctx *ctx, int runtime)
|
||||
{
|
||||
- int err, i = 0, j = 0;
|
||||
- struct expr_parse_ctx ctx;
|
||||
-
|
||||
- expr__ctx_init(&ctx);
|
||||
- err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER, runtime);
|
||||
- if (err)
|
||||
- return -1;
|
||||
-
|
||||
- *other = malloc((ctx.num_ids + 1) * sizeof(char *));
|
||||
- if (!*other)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- for (i = 0, j = 0; i < ctx.num_ids; i++) {
|
||||
- const char *str = ctx.ids[i].name;
|
||||
-
|
||||
- if (already_seen(str, one, *other, j))
|
||||
- continue;
|
||||
-
|
||||
- str = strdup(str);
|
||||
- if (!str)
|
||||
- goto out;
|
||||
- (*other)[j++] = str;
|
||||
- }
|
||||
- (*other)[j] = NULL;
|
||||
-
|
||||
-out:
|
||||
- if (i != ctx.num_ids) {
|
||||
- while (--j)
|
||||
- free((char *) (*other)[i]);
|
||||
- free(*other);
|
||||
- err = -1;
|
||||
+ double *old_val = NULL;
|
||||
+ char *old_key = NULL;
|
||||
+ int ret = __expr__parse(NULL, ctx, expr, EXPR_OTHER, runtime);
|
||||
+
|
||||
+ if (one) {
|
||||
+ hashmap__delete(&ctx->ids, one,
|
||||
+ (const void **)&old_key, (void **)&old_val);
|
||||
+ free(old_key);
|
||||
+ free(old_val);
|
||||
}
|
||||
|
||||
- *num_other = j;
|
||||
- return err;
|
||||
+ return ret;
|
||||
}
|
||||
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
|
||||
index 40fc452b0f2b..8a2c1074f90f 100644
|
||||
--- a/tools/perf/util/expr.h
|
||||
+++ b/tools/perf/util/expr.h
|
||||
@@ -2,17 +2,17 @@
|
||||
#ifndef PARSE_CTX_H
|
||||
#define PARSE_CTX_H 1
|
||||
|
||||
-#define EXPR_MAX_OTHER 64
|
||||
-#define MAX_PARSE_ID EXPR_MAX_OTHER
|
||||
-
|
||||
-struct expr_parse_id {
|
||||
- const char *name;
|
||||
- double val;
|
||||
-};
|
||||
+// There are fixes that need to land upstream before we can use libbpf's headers,
|
||||
+// for now use our copy uncoditionally, since the data structures at this point
|
||||
+// are exactly the same, no problem.
|
||||
+//#ifdef HAVE_LIBBPF_SUPPORT
|
||||
+//#include <bpf/hashmap.h>
|
||||
+//#else
|
||||
+#include "util/hashmap.h"
|
||||
+//#endif
|
||||
|
||||
struct expr_parse_ctx {
|
||||
- int num_ids;
|
||||
- struct expr_parse_id ids[MAX_PARSE_ID];
|
||||
+ struct hashmap ids;
|
||||
};
|
||||
|
||||
struct expr_scanner_ctx {
|
||||
@@ -21,9 +21,12 @@ struct expr_scanner_ctx {
|
||||
};
|
||||
|
||||
void expr__ctx_init(struct expr_parse_ctx *ctx);
|
||||
-void expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
|
||||
-int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr, int runtime);
|
||||
-int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
- int *num_other, int runtime);
|
||||
+void expr__ctx_clear(struct expr_parse_ctx *ctx);
|
||||
+int expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
|
||||
+int expr__get_id(struct expr_parse_ctx *ctx, const char *id, double *val_ptr);
|
||||
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
|
||||
+ const char *expr, int runtime);
|
||||
+int expr__find_other(const char *expr, const char *one,
|
||||
+ struct expr_parse_ctx *ids, int runtime);
|
||||
|
||||
#endif
|
||||
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
|
||||
index 74c9195860c5..924df4e1c477 100644
|
||||
--- a/tools/perf/util/expr.y
|
||||
+++ b/tools/perf/util/expr.y
|
||||
@@ -46,19 +46,6 @@ static void expr_error(double *final_val __maybe_unused,
|
||||
pr_debug("%s\n", s);
|
||||
}
|
||||
|
||||
-static int lookup_id(struct expr_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;
|
||||
-}
|
||||
-
|
||||
%}
|
||||
%%
|
||||
|
||||
@@ -72,12 +59,7 @@ all_other: all_other other
|
||||
|
||||
other: ID
|
||||
{
|
||||
- if (ctx->num_ids + 1 >= EXPR_MAX_OTHER) {
|
||||
- pr_err("failed: way too many variables");
|
||||
- YYABORT;
|
||||
- }
|
||||
-
|
||||
- ctx->ids[ctx->num_ids++].name = $1;
|
||||
+ expr__add_id(ctx, $1, 0.0);
|
||||
}
|
||||
|
|
||||
MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')' | ','
|
||||
@@ -92,7 +74,7 @@ if_expr:
|
||||
;
|
||||
|
||||
expr: NUMBER
|
||||
- | ID { if (lookup_id(ctx, $1, &$$) < 0) {
|
||||
+ | ID { if (expr__get_id(ctx, $1, &$$)) {
|
||||
pr_debug("%s not found\n", $1);
|
||||
free($1);
|
||||
YYABORT;
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index b4fe2e2f3ca4..bd1b54b30a87 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -91,8 +91,7 @@ static void metricgroup__rblist_init(struct rblist *metric_events)
|
||||
|
||||
struct egroup {
|
||||
struct list_head nd;
|
||||
- int idnum;
|
||||
- const char **ids;
|
||||
+ struct expr_parse_ctx pctx;
|
||||
const char *metric_name;
|
||||
const char *metric_expr;
|
||||
const char *metric_unit;
|
||||
@@ -100,19 +99,21 @@ struct egroup {
|
||||
};
|
||||
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
- const char **ids,
|
||||
- int idnum,
|
||||
+ struct expr_parse_ctx *pctx,
|
||||
struct perf_evsel **metric_events,
|
||||
bool *evlist_used)
|
||||
{
|
||||
struct perf_evsel *ev;
|
||||
- int i = 0, j = 0;
|
||||
bool leader_found;
|
||||
+ const size_t idnum = hashmap__size(&pctx->ids);
|
||||
+ size_t i = 0;
|
||||
+ int j = 0;
|
||||
+ double *val_ptr;
|
||||
|
||||
evlist__for_each_entry (perf_evlist, ev) {
|
||||
if (evlist_used[j++])
|
||||
continue;
|
||||
- if (!strcmp(ev->name, ids[i])) {
|
||||
+ if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) {
|
||||
if (!metric_events[i])
|
||||
metric_events[i] = ev;
|
||||
i++;
|
||||
@@ -123,14 +124,6 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
i = 0;
|
||||
memset(metric_events, 0,
|
||||
sizeof(struct perf_evsel *) * idnum);
|
||||
-
|
||||
- if (!strcmp(ev->name, ids[i])) {
|
||||
- if (!metric_events[i])
|
||||
- metric_events[i] = ev;
|
||||
- i++;
|
||||
- if (i == idnum)
|
||||
- break;
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,20 +174,21 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
list_for_each_entry (eg, groups, nd) {
|
||||
struct perf_evsel **metric_events;
|
||||
|
||||
- metric_events = calloc(sizeof(void *), eg->idnum + 1);
|
||||
+ metric_events = calloc(sizeof(void *),
|
||||
+ hashmap__size(&eg->pctx.ids) + 1);
|
||||
if (!metric_events) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
- evsel = find_evsel_group(perf_evlist, eg->ids, eg->idnum,
|
||||
- metric_events, evlist_used);
|
||||
+ evsel = find_evsel_group(perf_evlist, &eg->pctx, metric_events,
|
||||
+ evlist_used);
|
||||
if (!evsel) {
|
||||
pr_debug("Cannot resolve %s: %s\n",
|
||||
eg->metric_name, eg->metric_expr);
|
||||
free(metric_events);
|
||||
continue;
|
||||
}
|
||||
- for (i = 0; i < eg->idnum; i++)
|
||||
+ for (i = 0; metric_events[i]; i++)
|
||||
metric_events[i]->collect_stat = true;
|
||||
me = metricgroup__lookup(metric_events_list, evsel, true);
|
||||
if (!me) {
|
||||
@@ -425,20 +419,20 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
|
||||
}
|
||||
|
||||
static void metricgroup__add_metric_weak_group(struct strbuf *events,
|
||||
- const char **ids,
|
||||
- int idnum)
|
||||
+ struct expr_parse_ctx *ctx)
|
||||
{
|
||||
+ struct hashmap_entry *cur;
|
||||
+ size_t bkt, i = 0;
|
||||
bool no_group = false;
|
||||
- int i;
|
||||
|
||||
- for (i = 0; i < idnum; i++) {
|
||||
- pr_debug("found event %s\n", ids[i]);
|
||||
+ hashmap__for_each_entry((&ctx->ids), cur, bkt) {
|
||||
+ pr_debug("found event %s\n", (const char *)cur->key);
|
||||
/*
|
||||
* Duration time maps to a software event and can make
|
||||
* groups not count. Always use it outside a
|
||||
* group.
|
||||
*/
|
||||
- if (!strcmp(ids[i], "duration_time")) {
|
||||
+ if (!strcmp(cur->key, "duration_time")) {
|
||||
if (i > 0)
|
||||
strbuf_addf(events, "}:W,");
|
||||
strbuf_addf(events, "duration_time");
|
||||
@@ -447,21 +441,22 @@ static void metricgroup__add_metric_weak_group(struct strbuf *events,
|
||||
}
|
||||
strbuf_addf(events, "%s%s",
|
||||
i == 0 || no_group ? "{" : ",",
|
||||
- ids[i]);
|
||||
+ (const char *)cur->key);
|
||||
no_group = false;
|
||||
+ i++;
|
||||
}
|
||||
if (!no_group)
|
||||
strbuf_addf(events, "}:W");
|
||||
}
|
||||
|
||||
static void metricgroup__add_metric_non_group(struct strbuf *events,
|
||||
- const char **ids,
|
||||
- int idnum)
|
||||
+ struct expr_parse_ctx *ctx)
|
||||
{
|
||||
- int i;
|
||||
+ struct hashmap_entry *cur;
|
||||
+ size_t bkt;
|
||||
|
||||
- for (i = 0; i < idnum; i++)
|
||||
- strbuf_addf(events, ",%s", ids[i]);
|
||||
+ hashmap__for_each_entry((&ctx->ids), cur, bkt)
|
||||
+ strbuf_addf(events, ",%s", (const char *)cur->key);
|
||||
}
|
||||
|
||||
static void metricgroup___watchdog_constraint_hint(const char *name, bool foot)
|
||||
@@ -505,32 +500,32 @@ int __weak arch_get_runtimeparam(void)
|
||||
static int __metricgroup__add_metric(struct strbuf *events,
|
||||
struct list_head *group_list, struct pmu_event *pe, int runtime)
|
||||
{
|
||||
-
|
||||
- const char **ids;
|
||||
- int idnum;
|
||||
struct egroup *eg;
|
||||
|
||||
- if (expr__find_other(pe->metric_expr, NULL, &ids, &idnum, runtime) < 0)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (events->len > 0)
|
||||
- strbuf_addf(events, ",");
|
||||
-
|
||||
- if (metricgroup__has_constraint(pe))
|
||||
- metricgroup__add_metric_non_group(events, ids, idnum);
|
||||
- else
|
||||
- metricgroup__add_metric_weak_group(events, ids, idnum);
|
||||
-
|
||||
eg = malloc(sizeof(*eg));
|
||||
if (!eg)
|
||||
return -ENOMEM;
|
||||
|
||||
- eg->ids = ids;
|
||||
- eg->idnum = idnum;
|
||||
+ expr__ctx_init(&eg->pctx);
|
||||
eg->metric_name = pe->metric_name;
|
||||
eg->metric_expr = pe->metric_expr;
|
||||
eg->metric_unit = pe->unit;
|
||||
eg->runtime = runtime;
|
||||
+
|
||||
+ if (expr__find_other(pe->metric_expr, NULL, &eg->pctx, runtime) < 0) {
|
||||
+ expr__ctx_clear(&eg->pctx);
|
||||
+ free(eg);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (events->len > 0)
|
||||
+ strbuf_addf(events, ",");
|
||||
+
|
||||
+ if (metricgroup__has_constraint(pe))
|
||||
+ metricgroup__add_metric_non_group(events, &eg->pctx);
|
||||
+ else
|
||||
+ metricgroup__add_metric_weak_group(events, &eg->pctx);
|
||||
+
|
||||
list_add_tail(&eg->nd, group_list);
|
||||
|
||||
return 0;
|
||||
@@ -613,12 +608,9 @@ static int metricgroup__add_metric_list(const char *list, struct strbuf *events,
|
||||
static void metricgroup__free_egroups(struct list_head *group_list)
|
||||
{
|
||||
struct egroup *eg, *egtmp;
|
||||
- int i;
|
||||
|
||||
list_for_each_entry_safe (eg, egtmp, group_list, nd) {
|
||||
- for (i = 0; i < eg->idnum; i++)
|
||||
- free((char *)eg->ids[i]);
|
||||
- free(eg->ids);
|
||||
+ expr__ctx_clear(&eg->pctx);
|
||||
list_del_init(&eg->nd);
|
||||
free(eg);
|
||||
}
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index dfa33d1bce53..8c8e1f7ea2e2 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -323,35 +323,46 @@ 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;
|
||||
+ struct expr_parse_ctx ctx;
|
||||
+ struct hashmap_entry *cur;
|
||||
+ size_t bkt;
|
||||
int i;
|
||||
- int num_metric_names;
|
||||
|
||||
+ expr__ctx_init(&ctx);
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
bool invalid = false;
|
||||
|
||||
leader = counter->leader;
|
||||
if (!counter->metric_expr)
|
||||
continue;
|
||||
+
|
||||
+ expr__ctx_clear(&ctx);
|
||||
metric_events = counter->metric_events;
|
||||
if (!metric_events) {
|
||||
- if (expr__find_other(counter->metric_expr, counter->name,
|
||||
- &metric_names, &num_metric_names, 1) < 0)
|
||||
+ if (expr__find_other(counter->metric_expr,
|
||||
+ counter->name,
|
||||
+ &ctx, 1) < 0)
|
||||
continue;
|
||||
|
||||
metric_events = calloc(sizeof(struct perf_evsel *),
|
||||
- num_metric_names + 1);
|
||||
- if (!metric_events)
|
||||
+ hashmap__size(&ctx.ids) + 1);
|
||||
+ if (!metric_events) {
|
||||
+ expr__ctx_clear(&ctx);
|
||||
return;
|
||||
+ }
|
||||
counter->metric_events = metric_events;
|
||||
}
|
||||
|
||||
- for (i = 0; i < num_metric_names; i++) {
|
||||
+ i = 0;
|
||||
+ hashmap__for_each_entry((&ctx.ids), cur, bkt) {
|
||||
+ const char *metric_name = (const char *)cur->key;
|
||||
+
|
||||
found = false;
|
||||
if (leader) {
|
||||
/* Search in group */
|
||||
for_each_group_member (oc, leader) {
|
||||
- if (!strcasecmp(oc->name, metric_names[i]) &&
|
||||
+ if (!strcasecmp(oc->name,
|
||||
+ metric_name) &&
|
||||
!oc->collect_stat) {
|
||||
found = true;
|
||||
break;
|
||||
@@ -360,7 +371,8 @@ void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list)
|
||||
}
|
||||
if (!found) {
|
||||
/* Search ignoring groups */
|
||||
- oc = perf_stat__find_event(evsel_list, metric_names[i]);
|
||||
+ oc = perf_stat__find_event(evsel_list,
|
||||
+ metric_name);
|
||||
}
|
||||
if (!oc) {
|
||||
/* Deduping one is good enough to handle duplicated PMUs. */
|
||||
@@ -373,27 +385,28 @@ void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list)
|
||||
* of events. So we ask the user instead to add the missing
|
||||
* events.
|
||||
*/
|
||||
- if (!printed || strcasecmp(printed, metric_names[i])) {
|
||||
+ if (!printed ||
|
||||
+ strcasecmp(printed, metric_name)) {
|
||||
fprintf(stderr,
|
||||
"Add %s event to groups to get metric expression for %s\n",
|
||||
- metric_names[i],
|
||||
+ metric_name,
|
||||
counter->name);
|
||||
- printed = strdup(metric_names[i]);
|
||||
+ printed = strdup(metric_name);
|
||||
}
|
||||
invalid = true;
|
||||
continue;
|
||||
}
|
||||
- metric_events[i] = oc;
|
||||
+ 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;
|
||||
}
|
||||
}
|
||||
+ expr__ctx_clear(&ctx);
|
||||
}
|
||||
|
||||
static double runtime_stat_avg(struct runtime_stat *st,
|
||||
@@ -738,7 +751,10 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
|
||||
expr__ctx_init(&pctx);
|
||||
/* Must be first id entry */
|
||||
- expr__add_id(&pctx, name, avg);
|
||||
+ n = strdup(name);
|
||||
+ if (!n)
|
||||
+ return;
|
||||
+ expr__add_id(&pctx, n, avg);
|
||||
for (i = 0; metric_events[i]; i++) {
|
||||
struct saved_value *v;
|
||||
struct stats *stats;
|
||||
@@ -811,8 +827,7 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
} else
|
||||
print_metric(config, ctxp, NULL, NULL, "", 0);
|
||||
|
||||
- for (i = 1; i < pctx.num_ids; i++)
|
||||
- free((void *)pctx.ids[i].name);
|
||||
+ expr__ctx_clear(&pctx);
|
||||
}
|
||||
|
||||
void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
From bea495f5119ce30bcfa4725b87aa639e10b803ef Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 00:28:08 -0700
|
||||
Subject: [PATCH 078/201] perf metricgroup: Make 'evlist_used' variable a
|
||||
bitmap instead of array of bools
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 45db55f2ef5e98ef096096efad975dc684a9493f
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=45db55f2ef5e98ef096096efad975dc684a9493f
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Use a bitmap rather than an array of bools.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520072814.128267-2-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 18 ++++++++----------
|
||||
1 file changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index bd1b54b30a87..4a5baf5719c4 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -101,7 +101,7 @@ struct egroup {
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
struct expr_parse_ctx *pctx,
|
||||
struct perf_evsel **metric_events,
|
||||
- bool *evlist_used)
|
||||
+ unsigned long *evlist_used)
|
||||
{
|
||||
struct perf_evsel *ev;
|
||||
bool leader_found;
|
||||
@@ -111,7 +111,7 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
double *val_ptr;
|
||||
|
||||
evlist__for_each_entry (perf_evlist, ev) {
|
||||
- if (evlist_used[j++])
|
||||
+ if (test_bit(j++, evlist_used))
|
||||
continue;
|
||||
if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) {
|
||||
if (!metric_events[i])
|
||||
@@ -147,7 +147,7 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
j++;
|
||||
}
|
||||
ev = metric_events[i];
|
||||
- evlist_used[ev->idx] = true;
|
||||
+ set_bit(ev->idx, evlist_used);
|
||||
}
|
||||
|
||||
return metric_events[0];
|
||||
@@ -163,13 +163,11 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
int ret = 0;
|
||||
struct egroup *eg;
|
||||
struct perf_evsel *evsel;
|
||||
- bool *evlist_used;
|
||||
+ unsigned long *evlist_used;
|
||||
|
||||
- evlist_used = calloc(perf_evlist->nr_entries, sizeof(bool));
|
||||
- if (!evlist_used) {
|
||||
- ret = -ENOMEM;
|
||||
- return ret;
|
||||
- }
|
||||
+ evlist_used = bitmap_alloc(perf_evlist->nr_entries);
|
||||
+ if (!evlist_used)
|
||||
+ return -ENOMEM;
|
||||
|
||||
list_for_each_entry (eg, groups, nd) {
|
||||
struct perf_evsel **metric_events;
|
||||
@@ -210,7 +208,7 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
list_add(&expr->nd, &me->head);
|
||||
}
|
||||
|
||||
- free(evlist_used);
|
||||
+ bitmap_free(evlist_used);
|
||||
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
From 9600c58c83d3c192fb75d43cb4f52e5b2fc25f19 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 11:20:05 -0700
|
||||
Subject: [PATCH 079/201] perf metricgroup: Always place duration_time last
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 4e21c13aca38b69c4470b68ef29d198802e7d74e
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4e21c13aca38b69c4470b68ef29d198802e7d74e
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
If a metric contains the duration_time event then the event is placed
|
||||
outside of the metric's group of events. Rather than split the group,
|
||||
make it so the duration_time is immediately after the group.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520182011.32236-2-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 18 +++++++++---------
|
||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 4a5baf5719c4..9f803fd81c8f 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -420,8 +420,8 @@ static void metricgroup__add_metric_weak_group(struct strbuf *events,
|
||||
struct expr_parse_ctx *ctx)
|
||||
{
|
||||
struct hashmap_entry *cur;
|
||||
- size_t bkt, i = 0;
|
||||
- bool no_group = false;
|
||||
+ size_t bkt;
|
||||
+ bool no_group = true, has_duration = false;
|
||||
|
||||
hashmap__for_each_entry((&ctx->ids), cur, bkt) {
|
||||
pr_debug("found event %s\n", (const char *)cur->key);
|
||||
@@ -431,20 +431,20 @@ static void metricgroup__add_metric_weak_group(struct strbuf *events,
|
||||
* group.
|
||||
*/
|
||||
if (!strcmp(cur->key, "duration_time")) {
|
||||
- if (i > 0)
|
||||
- strbuf_addf(events, "}:W,");
|
||||
- strbuf_addf(events, "duration_time");
|
||||
- no_group = true;
|
||||
+ has_duration = true;
|
||||
continue;
|
||||
}
|
||||
strbuf_addf(events, "%s%s",
|
||||
- i == 0 || no_group ? "{" : ",",
|
||||
+ no_group ? "{" : ",",
|
||||
(const char *)cur->key);
|
||||
no_group = false;
|
||||
- i++;
|
||||
}
|
||||
- if (!no_group)
|
||||
+ if (!no_group) {
|
||||
strbuf_addf(events, "}:W");
|
||||
+ if (has_duration)
|
||||
+ strbuf_addf(events, ",duration_time");
|
||||
+ } else if (has_duration)
|
||||
+ strbuf_addf(events, "duration_time");
|
||||
}
|
||||
|
||||
static void metricgroup__add_metric_non_group(struct strbuf *events,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
From 41adaa29c3f367b5a536ccd0a6b0550b469a5618 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 11:20:06 -0700
|
||||
Subject: [PATCH 080/201] perf metricgroup: Use early return in add_metric
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 908103991a9970a8e033e9f3aedd092a2c993f49
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=908103991a9970a8e033e9f3aedd092a2c993f49
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Use early return in metricgroup__add_metric and try to make the intent
|
||||
of the returns more intention revealing.
|
||||
|
||||
Suggested-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520182011.32236-3-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 22 +++++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 9f803fd81c8f..dafabead253b 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -534,7 +534,8 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
{
|
||||
struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
struct pmu_event *pe;
|
||||
- int i, ret = -EINVAL;
|
||||
+ int i, ret;
|
||||
+ bool has_match = false;
|
||||
|
||||
if (!map)
|
||||
return 0;
|
||||
@@ -542,17 +543,23 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
for (i = 0; ; i++) {
|
||||
pe = &map->table[i];
|
||||
|
||||
- if (!pe->name && !pe->metric_group && !pe->metric_name)
|
||||
+ if (!pe->name && !pe->metric_group && !pe->metric_name) {
|
||||
+ /* End of pmu events. */
|
||||
+ if (!has_match)
|
||||
+ return -EINVAL;
|
||||
break;
|
||||
+ }
|
||||
if (!pe->metric_expr)
|
||||
continue;
|
||||
if (match_metric(pe->metric_group, metric) ||
|
||||
match_metric(pe->metric_name, metric)) {
|
||||
-
|
||||
+ has_match = true;
|
||||
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
|
||||
|
||||
if (!strstr(pe->metric_expr, "?")) {
|
||||
ret = __metricgroup__add_metric(events, group_list, pe, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
} else {
|
||||
int j, count;
|
||||
|
||||
@@ -563,14 +570,15 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
* those events to group_list.
|
||||
*/
|
||||
|
||||
- for (j = 0; j < count; j++)
|
||||
+ for (j = 0; j < count; j++) {
|
||||
ret = __metricgroup__add_metric(events, group_list, pe, j);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
- if (ret == -ENOMEM)
|
||||
- break;
|
||||
}
|
||||
}
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int metricgroup__add_metric_list(const char *list, struct strbuf *events,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
144
patches/0198-perf-metricgroup-Delay-events-string-creation.patch
Normal file
144
patches/0198-perf-metricgroup-Delay-events-string-creation.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From fb520c75e6f1ad6fdd10ffe290bd3ba05748713d Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 11:20:07 -0700
|
||||
Subject: [PATCH 081/201] perf metricgroup: Delay events string creation
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 7f9eca51c1e8e5acc4264f960c2cdec150f597f9
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7f9eca51c1e8e5acc4264f960c2cdec150f597f9
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Currently event groups are placed into groups_list at the same time as
|
||||
the events string containing the events is built. Separate these two
|
||||
operations and build the groups_list first, then the event string from
|
||||
the groups_list. This adds an ability to reorder the groups_list that
|
||||
will be used in a later patch.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520182011.32236-4-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 33 +++++++++++++++++++++------------
|
||||
1 file changed, 21 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index dafabead253b..14b9e897cc74 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -96,6 +96,7 @@ struct egroup {
|
||||
const char *metric_expr;
|
||||
const char *metric_unit;
|
||||
int runtime;
|
||||
+ bool has_constraint;
|
||||
};
|
||||
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
@@ -495,8 +496,8 @@ int __weak arch_get_runtimeparam(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int __metricgroup__add_metric(struct strbuf *events,
|
||||
- struct list_head *group_list, struct pmu_event *pe, int runtime)
|
||||
+static int __metricgroup__add_metric(struct list_head *group_list,
|
||||
+ struct pmu_event *pe, int runtime)
|
||||
{
|
||||
struct egroup *eg;
|
||||
|
||||
@@ -509,6 +510,7 @@ static int __metricgroup__add_metric(struct strbuf *events,
|
||||
eg->metric_expr = pe->metric_expr;
|
||||
eg->metric_unit = pe->unit;
|
||||
eg->runtime = runtime;
|
||||
+ eg->has_constraint = metricgroup__has_constraint(pe);
|
||||
|
||||
if (expr__find_other(pe->metric_expr, NULL, &eg->pctx, runtime) < 0) {
|
||||
expr__ctx_clear(&eg->pctx);
|
||||
@@ -516,14 +518,6 @@ static int __metricgroup__add_metric(struct strbuf *events,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (events->len > 0)
|
||||
- strbuf_addf(events, ",");
|
||||
-
|
||||
- if (metricgroup__has_constraint(pe))
|
||||
- metricgroup__add_metric_non_group(events, &eg->pctx);
|
||||
- else
|
||||
- metricgroup__add_metric_weak_group(events, &eg->pctx);
|
||||
-
|
||||
list_add_tail(&eg->nd, group_list);
|
||||
|
||||
return 0;
|
||||
@@ -534,6 +528,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
{
|
||||
struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
struct pmu_event *pe;
|
||||
+ struct egroup *eg;
|
||||
int i, ret;
|
||||
bool has_match = false;
|
||||
|
||||
@@ -557,7 +552,8 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
|
||||
|
||||
if (!strstr(pe->metric_expr, "?")) {
|
||||
- ret = __metricgroup__add_metric(events, group_list, pe, 1);
|
||||
+ ret = __metricgroup__add_metric(group_list,
|
||||
+ pe, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
@@ -571,13 +567,26 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
*/
|
||||
|
||||
for (j = 0; j < count; j++) {
|
||||
- ret = __metricgroup__add_metric(events, group_list, pe, j);
|
||||
+ ret = __metricgroup__add_metric(
|
||||
+ group_list, pe, j);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+ list_for_each_entry(eg, group_list, nd) {
|
||||
+ if (events->len > 0)
|
||||
+ strbuf_addf(events, ",");
|
||||
+
|
||||
+ if (eg->has_constraint) {
|
||||
+ metricgroup__add_metric_non_group(events,
|
||||
+ &eg->pctx);
|
||||
+ } else {
|
||||
+ metricgroup__add_metric_weak_group(events,
|
||||
+ &eg->pctx);
|
||||
+ }
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
From 32ef39b64d9bef122fb265827f281911991c8412 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 11:20:08 -0700
|
||||
Subject: [PATCH 082/201] perf metricgroup: Order event groups by size
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 6bf2102bec4e600e72f87569d2c8e01a3efb340e
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bf2102bec4e600e72f87569d2c8e01a3efb340e
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
When adding event groups to the group list, insert them in size order.
|
||||
This performs an insertion sort on the group list. By placing the
|
||||
largest groups at the front of the group list it is possible to see if a
|
||||
larger group contains the same events as a later group. This can make
|
||||
the later group redundant - it can reuse the events from the large
|
||||
group. A later patch will add this sharing.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520182011.32236-5-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 16 +++++++++++++++-
|
||||
1 file changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 14b9e897cc74..c9ff1be3a992 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -518,7 +518,21 @@ static int __metricgroup__add_metric(struct list_head *group_list,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- list_add_tail(&eg->nd, group_list);
|
||||
+ if (list_empty(group_list))
|
||||
+ list_add(&eg->nd, group_list);
|
||||
+ else {
|
||||
+ struct list_head *pos;
|
||||
+
|
||||
+ /* Place the largest groups at the front. */
|
||||
+ list_for_each_prev(pos, group_list) {
|
||||
+ struct egroup *old = list_entry(pos, struct egroup, nd);
|
||||
+
|
||||
+ if (hashmap__size(&eg->pctx.ids) <=
|
||||
+ hashmap__size(&old->pctx.ids))
|
||||
+ break;
|
||||
+ }
|
||||
+ list_add(&eg->nd, pos);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,254 @@
|
||||
From 44f2d339d18d722e5afd9beccb4474fc0ed60412 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 11:20:09 -0700
|
||||
Subject: [PATCH 083/201] perf metricgroup: Remove duped metric group events
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 2440689d62e93574ca71c87129f7d523ddff7679
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2440689d62e93574ca71c87129f7d523ddff7679
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
A metric group contains multiple metrics. These metrics may use the same
|
||||
events. If metrics use separate events then it leads to more
|
||||
multiplexing and overall metric counts fail to sum to 100%.
|
||||
|
||||
Modify how metrics are associated with events so that if the events in
|
||||
an earlier group satisfy the current metric, the same events are used.
|
||||
A record of used events is kept and at the end of processing unnecessary
|
||||
events are eliminated.
|
||||
|
||||
Before:
|
||||
|
||||
$ perf stat -a -M TopDownL1 sleep 1
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
920,211,343 uops_issued.any # 0.5 Backend_Bound (16.56%)
|
||||
1,977,733,128 idq_uops_not_delivered.core (16.56%)
|
||||
51,668,510 int_misc.recovery_cycles (16.56%)
|
||||
732,305,692 uops_retired.retire_slots (16.56%)
|
||||
1,497,621,849 cycles (16.56%)
|
||||
721,098,274 uops_issued.any # 0.1 Bad_Speculation (16.79%)
|
||||
1,332,681,791 cycles (16.79%)
|
||||
552,475,482 uops_retired.retire_slots (16.79%)
|
||||
47,708,340 int_misc.recovery_cycles (16.79%)
|
||||
1,383,713,292 cycles
|
||||
# 0.4 Frontend_Bound (16.76%)
|
||||
2,013,757,701 idq_uops_not_delivered.core (16.76%)
|
||||
1,373,363,790 cycles
|
||||
# 0.1 Retiring (33.54%)
|
||||
577,302,589 uops_retired.retire_slots (33.54%)
|
||||
392,766,987 inst_retired.any # 0.3 IPC (50.24%)
|
||||
1,351,873,350 cpu_clk_unhalted.thread (50.24%)
|
||||
1,332,510,318 cycles
|
||||
# 5330041272.0 SLOTS (49.90%)
|
||||
|
||||
1.006336145 seconds time elapsed
|
||||
|
||||
After:
|
||||
|
||||
$ perf stat -a -M TopDownL1 sleep 1
|
||||
|
||||
Performance counter stats for 'system wide':
|
||||
|
||||
765,949,145 uops_issued.any # 0.1 Bad_Speculation
|
||||
# 0.5 Backend_Bound (50.09%)
|
||||
1,883,830,591 idq_uops_not_delivered.core # 0.3 Frontend_Bound (50.09%)
|
||||
48,237,080 int_misc.recovery_cycles (50.09%)
|
||||
581,798,385 uops_retired.retire_slots # 0.1 Retiring (50.09%)
|
||||
1,361,628,527 cycles
|
||||
# 5446514108.0 SLOTS (50.09%)
|
||||
391,415,714 inst_retired.any # 0.3 IPC (49.91%)
|
||||
1,336,486,781 cpu_clk_unhalted.thread (49.91%)
|
||||
|
||||
1.005469298 seconds time elapsed
|
||||
|
||||
Note: Bad_Speculation + Backend_Bound + Frontend_Bound + Retiring = 100%
|
||||
after, where as before it is 110%. After there are 2 groups, whereas
|
||||
before there are 6. After the cycles event appears once, before it
|
||||
appeared 5 times.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520182011.32236-6-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 91 ++++++++++++++++++++++++-----------
|
||||
1 file changed, 62 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index c9ff1be3a992..65f96cfa4183 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -99,36 +99,72 @@ struct egroup {
|
||||
bool has_constraint;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * Find a group of events in perf_evlist that correpond to those from a parsed
|
||||
+ * metric expression.
|
||||
+ * @perf_evlist: a list of events something like: {metric1 leader, metric1
|
||||
+ * sibling, metric1 sibling}:W,duration_time,{metric2 leader, metric2 sibling,
|
||||
+ * metric2 sibling}:W,duration_time
|
||||
+ * @pctx: the parse context for the metric expression.
|
||||
+ * @has_constraint: is there a contraint on the group of events? In which case
|
||||
+ * the events won't be grouped.
|
||||
+ * @metric_events: out argument, null terminated array of evsel's associated
|
||||
+ * with the metric.
|
||||
+ * @evlist_used: in/out argument, bitmap tracking which evlist events are used.
|
||||
+ * @return the first metric event or NULL on failure.
|
||||
+ */
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
struct expr_parse_ctx *pctx,
|
||||
+ bool has_constraint,
|
||||
struct perf_evsel **metric_events,
|
||||
unsigned long *evlist_used)
|
||||
{
|
||||
- struct perf_evsel *ev;
|
||||
- bool leader_found;
|
||||
- const size_t idnum = hashmap__size(&pctx->ids);
|
||||
- size_t i = 0;
|
||||
- int j = 0;
|
||||
+ struct perf_evsel *ev, *current_leader = NULL;
|
||||
double *val_ptr;
|
||||
+ int i = 0, matched_events = 0, events_to_match;
|
||||
+ const int idnum = (int)hashmap__size(&pctx->ids);
|
||||
+
|
||||
+ /* duration_time is grouped separately. */
|
||||
+ if (!has_constraint &&
|
||||
+ hashmap__find(&pctx->ids, "duration_time", (void **)&val_ptr))
|
||||
+ events_to_match = idnum - 1;
|
||||
+ else
|
||||
+ events_to_match = idnum;
|
||||
|
||||
evlist__for_each_entry (perf_evlist, ev) {
|
||||
- if (test_bit(j++, evlist_used))
|
||||
+ /*
|
||||
+ * Events with a constraint aren't grouped and match the first
|
||||
+ * events available.
|
||||
+ */
|
||||
+ if (has_constraint && ev->weak_group)
|
||||
continue;
|
||||
- if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) {
|
||||
- if (!metric_events[i])
|
||||
- metric_events[i] = ev;
|
||||
- i++;
|
||||
- if (i == idnum)
|
||||
- break;
|
||||
- } else {
|
||||
- /* Discard the whole match and start again */
|
||||
- i = 0;
|
||||
+ if (!has_constraint && ev->leader != current_leader) {
|
||||
+ /*
|
||||
+ * Start of a new group, discard the whole match and
|
||||
+ * start again.
|
||||
+ */
|
||||
+ matched_events = 0;
|
||||
memset(metric_events, 0,
|
||||
sizeof(struct perf_evsel *) * idnum);
|
||||
+ current_leader = ev->leader;
|
||||
}
|
||||
+ if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr))
|
||||
+ metric_events[matched_events++] = ev;
|
||||
+ if (matched_events == events_to_match)
|
||||
+ break;
|
||||
}
|
||||
|
||||
- if (i != idnum) {
|
||||
+ if (events_to_match != idnum) {
|
||||
+ /* Add the first duration_time. */
|
||||
+ evlist__for_each_entry(perf_evlist, ev) {
|
||||
+ if (!strcmp(ev->name, "duration_time")) {
|
||||
+ metric_events[matched_events++] = ev;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (matched_events != idnum) {
|
||||
/* Not whole match */
|
||||
return NULL;
|
||||
}
|
||||
@@ -136,18 +172,8 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
metric_events[idnum] = NULL;
|
||||
|
||||
for (i = 0; i < idnum; i++) {
|
||||
- leader_found = false;
|
||||
- evlist__for_each_entry(perf_evlist, ev) {
|
||||
- if (!leader_found && (ev == metric_events[i]))
|
||||
- leader_found = true;
|
||||
-
|
||||
- if (leader_found &&
|
||||
- !strcmp(ev->name, metric_events[i]->name)) {
|
||||
- ev->metric_leader = metric_events[i];
|
||||
- }
|
||||
- j++;
|
||||
- }
|
||||
ev = metric_events[i];
|
||||
+ ev->metric_leader = ev;
|
||||
set_bit(ev->idx, evlist_used);
|
||||
}
|
||||
|
||||
@@ -163,7 +189,7 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
struct egroup *eg;
|
||||
- struct perf_evsel *evsel;
|
||||
+ struct perf_evsel *evsel, *tmp;
|
||||
unsigned long *evlist_used;
|
||||
|
||||
evlist_used = bitmap_alloc(perf_evlist->nr_entries);
|
||||
@@ -179,7 +205,8 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
- evsel = find_evsel_group(perf_evlist, &eg->pctx, metric_events,
|
||||
+ evsel = find_evsel_group(perf_evlist, &eg->pctx,
|
||||
+ eg->has_constraint, metric_events,
|
||||
evlist_used);
|
||||
if (!evsel) {
|
||||
pr_debug("Cannot resolve %s: %s\n",
|
||||
@@ -209,6 +236,12 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
list_add(&expr->nd, &me->head);
|
||||
}
|
||||
|
||||
+ evlist__for_each_entry_safe(perf_evlist, tmp, evsel) {
|
||||
+ if (!test_bit(evsel->idx, evlist_used)) {
|
||||
+ perf_evlist__remove(perf_evlist, evsel);
|
||||
+ perf_evsel__delete(evsel);
|
||||
+ }
|
||||
+ }
|
||||
bitmap_free(evlist_used);
|
||||
|
||||
return ret;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,365 @@
|
||||
From af2d642045c3d5f3a7ab5a25c95b119f065cb94e Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 11:20:10 -0700
|
||||
Subject: [PATCH 084/201] perf metricgroup: Add options to not group or merge
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 05530a7921c0f5149a01e34c4e031c5b18bdc1cc
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=05530a7921c0f5149a01e34c4e031c5b18bdc1cc
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add --metric-no-group that causes all events within metrics to not be
|
||||
grouped. This can allow the event to get more time when multiplexed, but
|
||||
may also lower accuracy.
|
||||
Add --metric-no-merge option. By default events in different metrics may
|
||||
be shared if the group of events for one metric is the same or larger
|
||||
than that of the second. Sharing may increase or lower accuracy and so
|
||||
is now configurable.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520182011.32236-7-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
tools/perf/util/stat.h
|
||||
---
|
||||
tools/perf/Documentation/perf-stat.txt | 19 +++++++
|
||||
tools/perf/builtin-stat.c | 11 ++++-
|
||||
tools/perf/util/metricgroup.c | 68 ++++++++++++++++++++------
|
||||
tools/perf/util/metricgroup.h | 6 ++-
|
||||
tools/perf/util/stat.h | 20 ++++----
|
||||
5 files changed, 96 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
|
||||
index b10a90b6a718..a5c61d03db59 100644
|
||||
--- a/tools/perf/Documentation/perf-stat.txt
|
||||
+++ b/tools/perf/Documentation/perf-stat.txt
|
||||
@@ -217,6 +217,25 @@ filter out the startup phase of the program, which is often very different.
|
||||
|
||||
Print statistics of transactional execution if supported.
|
||||
|
||||
+--metric-no-group::
|
||||
+By default, events to compute a metric are placed in weak groups. The
|
||||
+group tries to enforce scheduling all or none of the events. The
|
||||
+--metric-no-group option places events outside of groups and may
|
||||
+increase the chance of the event being scheduled - leading to more
|
||||
+accuracy. However, as events may not be scheduled together accuracy
|
||||
+for metrics like instructions per cycle can be lower - as both metrics
|
||||
+may no longer be being measured at the same time.
|
||||
+
|
||||
+--metric-no-merge::
|
||||
+By default metric events in different weak groups can be shared if one
|
||||
+group contains all the events needed by another. In such cases one
|
||||
+group will be eliminated reducing event multiplexing and making it so
|
||||
+that certain groups of metrics sum to 100%. A downside to sharing a
|
||||
+group is that the group may require multiplexing and so accuracy for a
|
||||
+small group that need not have multiplexing is lowered. This option
|
||||
+forbids the event merging logic from sharing events between groups and
|
||||
+may be used to increase accuracy in this case.
|
||||
+
|
||||
STAT RECORD
|
||||
-----------
|
||||
Stores stat data into perf data file.
|
||||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
|
||||
index 0d8943ead576..56f62a9d0f0d 100644
|
||||
--- a/tools/perf/builtin-stat.c
|
||||
+++ b/tools/perf/builtin-stat.c
|
||||
@@ -1981,7 +1981,10 @@ static int parse_metric_groups(const struct option *opt,
|
||||
const char *str,
|
||||
int unset __maybe_unused)
|
||||
{
|
||||
- return metricgroup__parse_groups(opt, str, &stat_config.metric_events);
|
||||
+ return metricgroup__parse_groups(opt, str,
|
||||
+ stat_config.metric_no_group,
|
||||
+ stat_config.metric_no_merge,
|
||||
+ &stat_config.metric_events);
|
||||
}
|
||||
|
||||
static struct option stat_options[] = {
|
||||
@@ -2054,6 +2057,10 @@ static struct option stat_options[] = {
|
||||
"ms to wait before starting measurement after program start"),
|
||||
OPT_CALLBACK_NOOPT(0, "metric-only", &metric_only, NULL,
|
||||
"Only print computed metrics. No raw values", enable_metric_only),
|
||||
+ OPT_BOOLEAN(0, "metric-no-group", &stat_config.metric_no_group,
|
||||
+ "don't group metric events, impacts multiplexing"),
|
||||
+ OPT_BOOLEAN(0, "metric-no-merge", &stat_config.metric_no_merge,
|
||||
+ "don't try to share events between metrics in a group"),
|
||||
OPT_BOOLEAN(0, "topdown", &topdown_run,
|
||||
"measure topdown level 1 statistics"),
|
||||
OPT_BOOLEAN(0, "smi-cost", &smi_cost,
|
||||
@@ -2437,6 +2444,8 @@ static int add_default_attributes(void)
|
||||
struct option opt = { .value = &evsel_list };
|
||||
|
||||
return metricgroup__parse_groups(&opt, "transaction",
|
||||
+ stat_config.metric_no_group,
|
||||
+ stat_config.metric_no_merge,
|
||||
&stat_config.metric_events);
|
||||
}
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 65f96cfa4183..249233acb715 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -101,11 +101,15 @@ struct egroup {
|
||||
|
||||
/**
|
||||
* Find a group of events in perf_evlist that correpond to those from a parsed
|
||||
- * metric expression.
|
||||
+ * metric expression. Note, as find_evsel_group is called in the same order as
|
||||
+ * perf_evlist was constructed, metric_no_merge doesn't need to test for
|
||||
+ * underfilling a group.
|
||||
* @perf_evlist: a list of events something like: {metric1 leader, metric1
|
||||
* sibling, metric1 sibling}:W,duration_time,{metric2 leader, metric2 sibling,
|
||||
* metric2 sibling}:W,duration_time
|
||||
* @pctx: the parse context for the metric expression.
|
||||
+ * @metric_no_merge: don't attempt to share events for the metric with other
|
||||
+ * metrics.
|
||||
* @has_constraint: is there a contraint on the group of events? In which case
|
||||
* the events won't be grouped.
|
||||
* @metric_events: out argument, null terminated array of evsel's associated
|
||||
@@ -115,6 +119,7 @@ struct egroup {
|
||||
*/
|
||||
static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
struct expr_parse_ctx *pctx,
|
||||
+ bool metric_no_merge,
|
||||
bool has_constraint,
|
||||
struct perf_evsel **metric_events,
|
||||
unsigned long *evlist_used)
|
||||
@@ -138,6 +143,9 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
*/
|
||||
if (has_constraint && ev->weak_group)
|
||||
continue;
|
||||
+ /* Ignore event if already used and merging is disabled. */
|
||||
+ if (metric_no_merge && test_bit(ev->idx, evlist_used))
|
||||
+ continue;
|
||||
if (!has_constraint && ev->leader != current_leader) {
|
||||
/*
|
||||
* Start of a new group, discard the whole match and
|
||||
@@ -148,8 +156,23 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
sizeof(struct perf_evsel *) * idnum);
|
||||
current_leader = ev->leader;
|
||||
}
|
||||
- if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr))
|
||||
+ if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) {
|
||||
+ if (has_constraint) {
|
||||
+ /*
|
||||
+ * Events aren't grouped, ensure the same event
|
||||
+ * isn't matched from two groups.
|
||||
+ */
|
||||
+ for (i = 0; i < matched_events; i++) {
|
||||
+ if (!strcmp(ev->name,
|
||||
+ metric_events[i]->name)) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (i != matched_events)
|
||||
+ continue;
|
||||
+ }
|
||||
metric_events[matched_events++] = ev;
|
||||
+ }
|
||||
if (matched_events == events_to_match)
|
||||
break;
|
||||
}
|
||||
@@ -181,6 +204,7 @@ static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist,
|
||||
}
|
||||
|
||||
static int metricgroup__setup_events(struct list_head *groups,
|
||||
+ bool metric_no_merge,
|
||||
struct perf_evlist *perf_evlist,
|
||||
struct rblist *metric_events_list)
|
||||
{
|
||||
@@ -206,8 +230,9 @@ static int metricgroup__setup_events(struct list_head *groups,
|
||||
break;
|
||||
}
|
||||
evsel = find_evsel_group(perf_evlist, &eg->pctx,
|
||||
- eg->has_constraint, metric_events,
|
||||
- evlist_used);
|
||||
+ metric_no_merge,
|
||||
+ eg->has_constraint, metric_events,
|
||||
+ evlist_used);
|
||||
if (!evsel) {
|
||||
pr_debug("Cannot resolve %s: %s\n",
|
||||
eg->metric_name, eg->metric_expr);
|
||||
@@ -530,7 +555,9 @@ int __weak arch_get_runtimeparam(void)
|
||||
}
|
||||
|
||||
static int __metricgroup__add_metric(struct list_head *group_list,
|
||||
- struct pmu_event *pe, int runtime)
|
||||
+ struct pmu_event *pe,
|
||||
+ bool metric_no_group,
|
||||
+ int runtime)
|
||||
{
|
||||
struct egroup *eg;
|
||||
|
||||
@@ -543,7 +570,7 @@ static int __metricgroup__add_metric(struct list_head *group_list,
|
||||
eg->metric_expr = pe->metric_expr;
|
||||
eg->metric_unit = pe->unit;
|
||||
eg->runtime = runtime;
|
||||
- eg->has_constraint = metricgroup__has_constraint(pe);
|
||||
+ eg->has_constraint = metric_no_group || metricgroup__has_constraint(pe);
|
||||
|
||||
if (expr__find_other(pe->metric_expr, NULL, &eg->pctx, runtime) < 0) {
|
||||
expr__ctx_clear(&eg->pctx);
|
||||
@@ -570,7 +597,8 @@ static int __metricgroup__add_metric(struct list_head *group_list,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
+static int metricgroup__add_metric(const char *metric, bool metric_no_group,
|
||||
+ struct strbuf *events,
|
||||
struct list_head *group_list)
|
||||
{
|
||||
struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
@@ -600,7 +628,9 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
|
||||
if (!strstr(pe->metric_expr, "?")) {
|
||||
ret = __metricgroup__add_metric(group_list,
|
||||
- pe, 1);
|
||||
+ pe,
|
||||
+ metric_no_group,
|
||||
+ 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
@@ -615,7 +645,8 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
|
||||
for (j = 0; j < count; j++) {
|
||||
ret = __metricgroup__add_metric(
|
||||
- group_list, pe, j);
|
||||
+ group_list, pe,
|
||||
+ metric_no_group, j);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -637,7 +668,8 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int metricgroup__add_metric_list(const char *list, struct strbuf *events,
|
||||
+static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
|
||||
+ struct strbuf *events,
|
||||
struct list_head *group_list)
|
||||
{
|
||||
char *llist, *nlist, *p;
|
||||
@@ -652,7 +684,8 @@ static int metricgroup__add_metric_list(const char *list, struct strbuf *events,
|
||||
strbuf_addf(events, "%s", "");
|
||||
|
||||
while ((p = strsep(&llist, ",")) != NULL) {
|
||||
- ret = metricgroup__add_metric(p, events, group_list);
|
||||
+ ret = metricgroup__add_metric(p, metric_no_group, events,
|
||||
+ group_list);
|
||||
if (ret == -EINVAL) {
|
||||
fprintf(stderr, "Cannot find metric or group `%s'\n",
|
||||
p);
|
||||
@@ -679,8 +712,10 @@ static void metricgroup__free_egroups(struct list_head *group_list)
|
||||
}
|
||||
|
||||
int metricgroup__parse_groups(const struct option *opt,
|
||||
- const char *str,
|
||||
- struct rblist *metric_events)
|
||||
+ const char *str,
|
||||
+ bool metric_no_group,
|
||||
+ bool metric_no_merge,
|
||||
+ struct rblist *metric_events)
|
||||
{
|
||||
struct parse_events_error parse_error;
|
||||
struct perf_evlist *perf_evlist = *(struct perf_evlist **)opt->value;
|
||||
@@ -690,7 +725,8 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
|
||||
if (metric_events->nr_entries == 0)
|
||||
metricgroup__rblist_init(metric_events);
|
||||
- ret = metricgroup__add_metric_list(str, &extra_events, &group_list);
|
||||
+ ret = metricgroup__add_metric_list(str, metric_no_group,
|
||||
+ &extra_events, &group_list);
|
||||
if (ret)
|
||||
return ret;
|
||||
pr_debug("adding %s\n", extra_events.buf);
|
||||
@@ -701,8 +737,8 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
goto out;
|
||||
}
|
||||
strbuf_release(&extra_events);
|
||||
- ret = metricgroup__setup_events(&group_list, perf_evlist,
|
||||
- metric_events);
|
||||
+ ret = metricgroup__setup_events(&group_list, metric_no_merge,
|
||||
+ perf_evlist, metric_events);
|
||||
out:
|
||||
metricgroup__free_egroups(&group_list);
|
||||
return ret;
|
||||
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
|
||||
index f2a17a05eb81..b6dfd7d09b9c 100644
|
||||
--- a/tools/perf/util/metricgroup.h
|
||||
+++ b/tools/perf/util/metricgroup.h
|
||||
@@ -29,8 +29,10 @@ struct metric_event *metricgroup__lookup(struct rblist *metric_events,
|
||||
struct perf_evsel *evsel,
|
||||
bool create);
|
||||
int metricgroup__parse_groups(const struct option *opt,
|
||||
- const char *str,
|
||||
- struct rblist *metric_events);
|
||||
+ const char *str,
|
||||
+ bool metric_no_group,
|
||||
+ bool metric_no_merge,
|
||||
+ struct rblist *metric_events);
|
||||
|
||||
void metricgroup__print(bool metrics, bool groups, char *filter,
|
||||
bool raw, bool details);
|
||||
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
|
||||
index 8a7d8425acf8..fbbc47ed5d3f 100644
|
||||
--- a/tools/perf/util/stat.h
|
||||
+++ b/tools/perf/util/stat.h
|
||||
@@ -85,15 +85,17 @@ struct runtime_stat {
|
||||
};
|
||||
|
||||
struct perf_stat_config {
|
||||
- enum aggr_mode aggr_mode;
|
||||
- bool scale;
|
||||
- FILE *output;
|
||||
- unsigned int interval;
|
||||
- unsigned int timeout;
|
||||
- int times;
|
||||
- struct runtime_stat *stats;
|
||||
- int stats_num;
|
||||
- struct rblist metric_events;
|
||||
+ enum aggr_mode aggr_mode;
|
||||
+ bool scale;
|
||||
+ bool metric_no_group;
|
||||
+ bool metric_no_merge;
|
||||
+ FILE *output;
|
||||
+ unsigned int interval;
|
||||
+ unsigned int timeout;
|
||||
+ int times;
|
||||
+ struct runtime_stat *stats;
|
||||
+ int stats_num;
|
||||
+ struct rblist metric_events;
|
||||
};
|
||||
|
||||
void update_stats(struct stats *stats, u64 val);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From 5c7b42272956bf76e7e0c7bbb0c8a752e246e9ee Mon Sep 17 00:00:00 2001
|
||||
From: Ian Rogers <irogers@google.com>
|
||||
Date: Wed, 20 May 2020 11:20:11 -0700
|
||||
Subject: [PATCH 085/201] perf metricgroup: Remove unnecessary ',' from events
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit e2ce1059b0b3d032aa07cc51c24d28ec498feb5f
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e2ce1059b0b3d032aa07cc51c24d28ec498feb5f
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Remove unnecessary commas from events before they are parsed. This
|
||||
avoids ',' being echoed by parse-events.l.
|
||||
|
||||
Signed-off-by: Ian Rogers <irogers@google.com>
|
||||
Acked-by: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Andrii Nakryiko <andriin@fb.com>
|
||||
Cc: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Cc: Jin Yao <yao.jin@linux.intel.com>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Kajol Jain <kjain@linux.ibm.com>
|
||||
Cc: Kan Liang <kan.liang@linux.intel.com>
|
||||
Cc: Kim Phillips <kim.phillips@amd.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Paul Clarke <pc@us.ibm.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Song Liu <songliubraving@fb.com>
|
||||
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Vince Weaver <vincent.weaver@maine.edu>
|
||||
Cc: bpf@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Link: http://lore.kernel.org/lkml/20200520182011.32236-8-irogers@google.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 249233acb715..8fa4b98f6231 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -511,9 +511,14 @@ static void metricgroup__add_metric_non_group(struct strbuf *events,
|
||||
{
|
||||
struct hashmap_entry *cur;
|
||||
size_t bkt;
|
||||
+ bool first = true;
|
||||
|
||||
- hashmap__for_each_entry((&ctx->ids), cur, bkt)
|
||||
- strbuf_addf(events, ",%s", (const char *)cur->key);
|
||||
+ hashmap__for_each_entry((&ctx->ids), cur, bkt) {
|
||||
+ if (!first)
|
||||
+ strbuf_addf(events, ",");
|
||||
+ strbuf_addf(events, "%s", (const char *)cur->key);
|
||||
+ first = false;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void metricgroup___watchdog_constraint_hint(const char *name, bool foot)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,190 @@
|
||||
From b77372524aa141ad73960c45cac590e344cda3d7 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@redhat.com>
|
||||
Date: Fri, 17 Apr 2020 00:14:05 +0200
|
||||
Subject: [PATCH 086/201] perf parser: Add support to specify rXXX event with
|
||||
pmu
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 3a6c51e4d66cf2fbc05583247b2d2f1179e8a74c
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3a6c51e4d66cf2fbc05583247b2d2f1179e8a74c
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The current rXXXX event specification creates event under PERF_TYPE_RAW
|
||||
pmu type. This change allows to use rXXXX within pmu syntax, so it's
|
||||
type is used via the following syntax:
|
||||
|
||||
-e 'cpu/r3c/'
|
||||
-e 'cpum_cf/r0/'
|
||||
|
||||
The XXXX number goes directly to perf_event_attr::config the same way as
|
||||
in '-e rXXXX' event. The perf_event_attr::type is filled with pmu type.
|
||||
|
||||
Committer testing:
|
||||
|
||||
So, lets see what goes in perf_event_attr::config for, say, the
|
||||
'instructions' PERF_TYPE_HARDWARE (0) event, first we should look at how
|
||||
to encode this event as a PERF_TYPE_RAW event for this specific CPU, an
|
||||
AMD Ryzen 5:
|
||||
|
||||
# cat /sys/devices/cpu/events/instructions
|
||||
event=0xc0
|
||||
#
|
||||
|
||||
Then try with it _and_ the instruction, just to see that they are close
|
||||
enough:
|
||||
|
||||
# perf stat -e rc0,instructions sleep 1
|
||||
|
||||
Performance counter stats for 'sleep 1':
|
||||
|
||||
919,794 rc0
|
||||
919,898 instructions
|
||||
|
||||
1.000754579 seconds time elapsed
|
||||
|
||||
0.000715000 seconds user
|
||||
0.000000000 seconds sys
|
||||
#
|
||||
|
||||
Now we should try, before this patch, the PMU event encoding:
|
||||
|
||||
# perf stat -e cpu/rc0/ sleep 1
|
||||
event syntax error: 'cpu/rc0/'
|
||||
\___ unknown term
|
||||
|
||||
valid terms: event,edge,inv,umask,cmask,config,config1,config2,name,period,percore
|
||||
#
|
||||
|
||||
Now with this patch, the three ways of specifying the 'instructions' CPU
|
||||
counter are accepted:
|
||||
|
||||
# perf stat -e cpu/rc0/,rc0,instructions sleep 1
|
||||
|
||||
Performance counter stats for 'sleep 1':
|
||||
|
||||
892,948 cpu/rc0/
|
||||
893,052 rc0
|
||||
893,156 instructions
|
||||
|
||||
1.000931819 seconds time elapsed
|
||||
|
||||
0.000916000 seconds user
|
||||
0.000000000 seconds sys
|
||||
|
||||
#
|
||||
|
||||
Requested-by: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Tested-by: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
|
||||
Cc: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200416221405.437788-1-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/tests/parse-events.c
|
||||
tools/perf/util/parse-events.l
|
||||
---
|
||||
tools/perf/Documentation/perf-list.txt | 5 +++++
|
||||
tools/perf/tests/parse-events.c | 17 ++++++++++++++++-
|
||||
tools/perf/util/parse-events.l | 1 +
|
||||
tools/perf/util/parse-events.y | 9 +++++++++
|
||||
4 files changed, 31 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
|
||||
index 54d16b4d1ede..b040247d4cb8 100644
|
||||
--- a/tools/perf/Documentation/perf-list.txt
|
||||
+++ b/tools/perf/Documentation/perf-list.txt
|
||||
@@ -116,6 +116,11 @@ raw encoding of 0x1A8 can be used:
|
||||
perf stat -e r1a8 -a sleep 1
|
||||
perf record -e r1a8 ...
|
||||
|
||||
+It's also possible to use pmu syntax:
|
||||
+
|
||||
+ perf record -e r1a8 -a sleep 1
|
||||
+ perf record -e cpu/r1a8/ ...
|
||||
+
|
||||
You should refer to the processor specific documentation for getting these
|
||||
details. Some of them are referenced in the SEE ALSO section below.
|
||||
|
||||
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
|
||||
index 8f3c80e13584..b379368b6d62 100644
|
||||
--- a/tools/perf/tests/parse-events.c
|
||||
+++ b/tools/perf/tests/parse-events.c
|
||||
@@ -1356,6 +1356,16 @@ static int test__checkevent_complex_name(struct perf_evlist *evlist)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int test__checkevent_raw_pmu(struct perf_evlist *evlist)
|
||||
+{
|
||||
+ struct perf_evsel *evsel = perf_evlist__first(evlist);
|
||||
+
|
||||
+ TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
||||
+ TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
|
||||
+ TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int test__sym_event_slash(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
||||
@@ -1750,7 +1760,12 @@ static struct evlist_test test__events_pmu[] = {
|
||||
.name = "cpu/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks',period=0x1,event=0x2/ukp",
|
||||
.check = test__checkevent_complex_name,
|
||||
.id = 3,
|
||||
- }
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "software/r1a/",
|
||||
+ .check = test__checkevent_raw_pmu,
|
||||
+ .id = 4,
|
||||
+ },
|
||||
};
|
||||
|
||||
struct terms_test {
|
||||
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
|
||||
index d8c82cd8d610..3719ab1fefb9 100644
|
||||
--- a/tools/perf/util/parse-events.l
|
||||
+++ b/tools/perf/util/parse-events.l
|
||||
@@ -282,6 +282,7 @@ inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
|
||||
no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
|
||||
overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
|
||||
no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
|
||||
+r{num_raw_hex} { return raw(yyscanner); }
|
||||
, { return ','; }
|
||||
"/" { BEGIN(INITIAL); return '/'; }
|
||||
{name_minus} { return str(yyscanner, PE_NAME); }
|
||||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
|
||||
index b940b621b14e..ff913778a7d4 100644
|
||||
--- a/tools/perf/util/parse-events.y
|
||||
+++ b/tools/perf/util/parse-events.y
|
||||
@@ -575,6 +575,15 @@ event_term
|
||||
}
|
||||
|
||||
event_term:
|
||||
+PE_RAW
|
||||
+{
|
||||
+ struct parse_events_term *term;
|
||||
+
|
||||
+ ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_CONFIG,
|
||||
+ NULL, $1, false, &@1, NULL));
|
||||
+ $$ = term;
|
||||
+}
|
||||
+|
|
||||
PE_NAME '=' PE_NAME
|
||||
{
|
||||
struct parse_events_term *term;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
86
patches/0204-perf-tools-Allow-r0x-HEX-event-syntax.patch
Normal file
86
patches/0204-perf-tools-Allow-r0x-HEX-event-syntax.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From 5a898b8919815faf58618a42a600d117e631bc83 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Sat, 25 Jul 2020 14:19:58 +0200
|
||||
Subject: [PATCH 087/201] perf tools: Allow r0x<HEX> event syntax
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit c33cdf541181fae3dbcfbd79e40b11b0efe8c3d8
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c33cdf541181fae3dbcfbd79e40b11b0efe8c3d8
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add support to specify raw event with 'r0<HEX>' syntax within pmu term
|
||||
syntax like:
|
||||
|
||||
-e cpu/r0xdead/
|
||||
|
||||
It will be used to specify raw events in cases where they conflict with
|
||||
real pmu terms, like 'read', which is valid raw event syntax, but also a
|
||||
possible pmu term name as reported by Jin Yao.
|
||||
|
||||
Reported-by: Jin Yao <yao.jin@linux.intel.com>
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200725121959.1181869-1-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/Documentation/perf-list.txt | 1 +
|
||||
tools/perf/tests/parse-events.c | 5 +++++
|
||||
tools/perf/util/parse-events.l | 1 +
|
||||
3 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
|
||||
index b040247d4cb8..d8671953e992 100644
|
||||
--- a/tools/perf/Documentation/perf-list.txt
|
||||
+++ b/tools/perf/Documentation/perf-list.txt
|
||||
@@ -120,6 +120,7 @@ It's also possible to use pmu syntax:
|
||||
|
||||
perf record -e r1a8 -a sleep 1
|
||||
perf record -e cpu/r1a8/ ...
|
||||
+ perf record -e cpu/r0x1a8/ ...
|
||||
|
||||
You should refer to the processor specific documentation for getting these
|
||||
details. Some of them are referenced in the SEE ALSO section below.
|
||||
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
|
||||
index b379368b6d62..95cdc0d01a19 100644
|
||||
--- a/tools/perf/tests/parse-events.c
|
||||
+++ b/tools/perf/tests/parse-events.c
|
||||
@@ -1766,6 +1766,11 @@ static struct evlist_test test__events_pmu[] = {
|
||||
.check = test__checkevent_raw_pmu,
|
||||
.id = 4,
|
||||
},
|
||||
+ {
|
||||
+ .name = "software/r0x1a/",
|
||||
+ .check = test__checkevent_raw_pmu,
|
||||
+ .id = 4,
|
||||
+ },
|
||||
};
|
||||
|
||||
struct terms_test {
|
||||
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
|
||||
index 3719ab1fefb9..e7f00b5c123d 100644
|
||||
--- a/tools/perf/util/parse-events.l
|
||||
+++ b/tools/perf/util/parse-events.l
|
||||
@@ -283,6 +283,7 @@ no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
|
||||
overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
|
||||
no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
|
||||
r{num_raw_hex} { return raw(yyscanner); }
|
||||
+r0x{num_raw_hex} { return raw(yyscanner); }
|
||||
, { return ','; }
|
||||
"/" { BEGIN(INITIAL); return '/'; }
|
||||
{name_minus} { return str(yyscanner, PE_NAME); }
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
From bf4aa0d85a33f2d2714946ac8d8da7e8a45ed488 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Mon, 25 May 2020 00:42:07 +0200
|
||||
Subject: [PATCH 088/201] perf stat: Do not pass avg to generic_metric
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 5f09ca5a1484632d1d3dc533d626d12c4370dbbc
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5f09ca5a1484632d1d3dc533d626d12c4370dbbc
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
There's no need to pass the given evsel's count to metric data, because
|
||||
it will be pushed again within the following metric_events loop.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ian Rogers <irogers@google.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200524224219.234847-3-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/stat-shadow.c | 10 ++--------
|
||||
1 file changed, 2 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
|
||||
index 8c8e1f7ea2e2..40af5b4feb00 100644
|
||||
--- a/tools/perf/util/stat-shadow.c
|
||||
+++ b/tools/perf/util/stat-shadow.c
|
||||
@@ -737,7 +737,6 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
const char *metric_name,
|
||||
const char *metric_unit,
|
||||
int runtime,
|
||||
- double avg,
|
||||
int cpu,
|
||||
struct perf_stat_output_ctx *out,
|
||||
struct runtime_stat *st)
|
||||
@@ -750,11 +749,6 @@ static void generic_metric(struct perf_stat_config *config,
|
||||
char *n, *pn;
|
||||
|
||||
expr__ctx_init(&pctx);
|
||||
- /* Must be first id entry */
|
||||
- n = strdup(name);
|
||||
- if (!n)
|
||||
- return;
|
||||
- expr__add_id(&pctx, n, avg);
|
||||
for (i = 0; metric_events[i]; i++) {
|
||||
struct saved_value *v;
|
||||
struct stats *stats;
|
||||
@@ -1042,7 +1036,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
print_metric(config, ctxp, NULL, NULL, name, 0);
|
||||
} else if (evsel->metric_expr) {
|
||||
generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name,
|
||||
- evsel->metric_name, NULL, 1, avg, cpu, out, st);
|
||||
+ evsel->metric_name, NULL, 1, cpu, out, st);
|
||||
} else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) {
|
||||
char unit = 'M';
|
||||
char unit_buf[10];
|
||||
@@ -1071,7 +1065,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
||||
out->new_line(config, ctxp);
|
||||
generic_metric(config, mexp->metric_expr, mexp->metric_events,
|
||||
evsel->name, mexp->metric_name,
|
||||
- mexp->metric_unit, mexp->runtime, avg, cpu, out, st);
|
||||
+ mexp->metric_unit, mexp->runtime, cpu, out, st);
|
||||
}
|
||||
}
|
||||
if (num == 0)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,136 @@
|
||||
From d9408ff297274978db3e6905ef70a3d25fa4029a Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Mon, 25 May 2020 00:42:08 +0200
|
||||
Subject: [PATCH 089/201] perf parse: Add 'struct parse_events_state' pointer
|
||||
to scanner
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit 1244a32736f8f6a12e0959aa897813744122d690
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1244a32736f8f6a12e0959aa897813744122d690
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
We need to pass more data to the scanner so let's start with having it
|
||||
to take pointer to 'struct parse_events_state' object instead of just
|
||||
start token.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ian Rogers <irogers@google.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200524224219.234847-4-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
tools/perf/util/parse-events.c | 15 +++++++++------
|
||||
tools/perf/util/parse-events.h | 1 +
|
||||
tools/perf/util/parse-events.l | 8 ++++----
|
||||
3 files changed, 14 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index 8b9b13b6e901..67ae5069737b 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "debug.h"
|
||||
#include <api/fs/tracing_path.h>
|
||||
#include "parse-events-bison.h"
|
||||
-#define YY_EXTRA_TYPE int
|
||||
+#define YY_EXTRA_TYPE void*
|
||||
#include "parse-events-flex.h"
|
||||
#include "pmu.h"
|
||||
#include "thread_map.h"
|
||||
@@ -1820,13 +1820,14 @@ perf_pmu__parse_check(const char *name)
|
||||
return r ? r->type : PMU_EVENT_SYMBOL_ERR;
|
||||
}
|
||||
|
||||
-static int parse_events__scanner(const char *str, void *parse_state, int start_token)
|
||||
+static int parse_events__scanner(const char *str,
|
||||
+ struct parse_events_state *parse_state)
|
||||
{
|
||||
YY_BUFFER_STATE buffer;
|
||||
void *scanner;
|
||||
int ret;
|
||||
|
||||
- ret = parse_events_lex_init_extra(start_token, &scanner);
|
||||
+ ret = parse_events_lex_init_extra(parse_state, &scanner);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1849,11 +1850,12 @@ static int parse_events__scanner(const char *str, void *parse_state, int start_t
|
||||
int parse_events_terms(struct list_head *terms, const char *str)
|
||||
{
|
||||
struct parse_events_state parse_state = {
|
||||
- .terms = NULL,
|
||||
+ .terms = NULL,
|
||||
+ .stoken = PE_START_TERMS,
|
||||
};
|
||||
int ret;
|
||||
|
||||
- ret = parse_events__scanner(str, &parse_state, PE_START_TERMS);
|
||||
+ ret = parse_events__scanner(str, &parse_state);
|
||||
if (!ret) {
|
||||
list_splice(parse_state.terms, terms);
|
||||
zfree(&parse_state.terms);
|
||||
@@ -1872,10 +1874,11 @@ int parse_events(struct perf_evlist *evlist, const char *str,
|
||||
.idx = evlist->nr_entries,
|
||||
.error = err,
|
||||
.evlist = evlist,
|
||||
+ .stoken = PE_START_EVENTS,
|
||||
};
|
||||
int ret;
|
||||
|
||||
- ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS);
|
||||
+ ret = parse_events__scanner(str, &parse_state);
|
||||
perf_pmu__parse_cleanup();
|
||||
|
||||
if (!ret && list_empty(&parse_state.list)) {
|
||||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
||||
index 52be0b3b26f7..306f636aad96 100644
|
||||
--- a/tools/perf/util/parse-events.h
|
||||
+++ b/tools/perf/util/parse-events.h
|
||||
@@ -119,6 +119,7 @@ struct parse_events_state {
|
||||
struct parse_events_error *error;
|
||||
struct perf_evlist *evlist;
|
||||
struct list_head *terms;
|
||||
+ int stoken;
|
||||
};
|
||||
|
||||
void parse_events__shrink_config_terms(void);
|
||||
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
|
||||
index e7f00b5c123d..15ac319d94fa 100644
|
||||
--- a/tools/perf/util/parse-events.l
|
||||
+++ b/tools/perf/util/parse-events.l
|
||||
@@ -209,10 +209,10 @@ modifier_bp [rwx]{1,3}
|
||||
%%
|
||||
|
||||
%{
|
||||
- {
|
||||
- int start_token;
|
||||
+ struct parse_events_state *_parse_state = parse_events_get_extra(yyscanner);
|
||||
|
||||
- start_token = parse_events_get_extra(yyscanner);
|
||||
+ {
|
||||
+ int start_token = _parse_state->stoken;
|
||||
|
||||
if (start_token == PE_START_TERMS)
|
||||
BEGIN(config);
|
||||
@@ -220,7 +220,7 @@ modifier_bp [rwx]{1,3}
|
||||
BEGIN(event);
|
||||
|
||||
if (start_token) {
|
||||
- parse_events_set_extra(NULL, yyscanner);
|
||||
+ _parse_state->stoken = 0;
|
||||
/*
|
||||
* The flex parser does not init locations variable
|
||||
* via the scan_string interface, so we need do the
|
||||
--
|
||||
2.27.0
|
||||
|
||||
217
patches/0207-perf-tools-Fix-term-parsing-for-raw-syntax.patch
Normal file
217
patches/0207-perf-tools-Fix-term-parsing-for-raw-syntax.patch
Normal file
@ -0,0 +1,217 @@
|
||||
From dd55ddc72730188206769fd3a43738f50919109f Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Sun, 26 Jul 2020 09:52:44 +0200
|
||||
Subject: [PATCH 090/201] perf tools: Fix term parsing for raw syntax
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit 4929e95a1400e45b4b5a87fd3ce10273444187d4
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4929e95a1400e45b4b5a87fd3ce10273444187d4
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Jin Yao reported issue with possible conflict between raw events and
|
||||
term values in pmu event syntax.
|
||||
|
||||
Currently following syntax is resolved as raw event with 0xead value:
|
||||
|
||||
uncore_imc_free_running/read/
|
||||
|
||||
instead of using 'read' term from uncore_imc_free_running pmu, because
|
||||
'read' is correct raw event syntax with 0xead value.
|
||||
|
||||
To solve this issue we do following:
|
||||
|
||||
- check existing terms during rXXXX syntax processing
|
||||
and make them priority in case of conflict
|
||||
|
||||
- allow pmu/r0x1234/ syntax to be able to specify conflicting
|
||||
raw event (implemented in previous patch)
|
||||
|
||||
Also add automated tests for this and perf_pmu__parse_cleanup call to
|
||||
parse_events_terms, so the test gets properly cleaned up.
|
||||
|
||||
Fixes: 3a6c51e4d66c ("perf parser: Add support to specify rXXX event with pmu")
|
||||
Reported-by: Jin Yao <yao.jin@linux.intel.com>
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Tested-by: Jin Yao <yao.jin@linux.intel.com>
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Cc: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Link: http://lore.kernel.org/lkml/20200726075244.1191481-2-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/tests/parse-events.c | 37 ++++++++++++++++++++++++++++++++-
|
||||
tools/perf/util/parse-events.c | 28 +++++++++++++++++++++++++
|
||||
tools/perf/util/parse-events.h | 2 ++
|
||||
tools/perf/util/parse-events.l | 19 ++++++++++-------
|
||||
4 files changed, 77 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
|
||||
index 95cdc0d01a19..4ca5e569a05f 100644
|
||||
--- a/tools/perf/tests/parse-events.c
|
||||
+++ b/tools/perf/tests/parse-events.c
|
||||
@@ -631,6 +631,34 @@ static int test__checkterms_simple(struct list_head *terms)
|
||||
TEST_ASSERT_VAL("wrong val", term->val.num == 1);
|
||||
TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask"));
|
||||
|
||||
+ /*
|
||||
+ * read
|
||||
+ *
|
||||
+ * The perf_pmu__test_parse_init injects 'read' term into
|
||||
+ * perf_pmu_events_list, so 'read' is evaluated as read term
|
||||
+ * and not as raw event with 'ead' hex value.
|
||||
+ */
|
||||
+ term = list_entry(term->list.next, struct parse_events_term, list);
|
||||
+ TEST_ASSERT_VAL("wrong type term",
|
||||
+ term->type_term == PARSE_EVENTS__TERM_TYPE_USER);
|
||||
+ TEST_ASSERT_VAL("wrong type val",
|
||||
+ term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
|
||||
+ TEST_ASSERT_VAL("wrong val", term->val.num == 1);
|
||||
+ TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "read"));
|
||||
+
|
||||
+ /*
|
||||
+ * r0xead
|
||||
+ *
|
||||
+ * To be still able to pass 'ead' value with 'r' syntax,
|
||||
+ * we added support to parse 'r0xHEX' event.
|
||||
+ */
|
||||
+ term = list_entry(term->list.next, struct parse_events_term, list);
|
||||
+ TEST_ASSERT_VAL("wrong type term",
|
||||
+ term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG);
|
||||
+ TEST_ASSERT_VAL("wrong type val",
|
||||
+ term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
|
||||
+ TEST_ASSERT_VAL("wrong val", term->val.num == 0xead);
|
||||
+ TEST_ASSERT_VAL("wrong config", !term->config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1781,7 +1809,7 @@ struct terms_test {
|
||||
|
||||
static struct terms_test test__terms[] = {
|
||||
[0] = {
|
||||
- .str = "config=10,config1,config2=3,umask=1",
|
||||
+ .str = "config=10,config1,config2=3,umask=1,read,r0xead",
|
||||
.check = test__checkterms_simple,
|
||||
},
|
||||
};
|
||||
@@ -1840,6 +1868,13 @@ static int test_term(struct terms_test *t)
|
||||
|
||||
INIT_LIST_HEAD(&terms);
|
||||
|
||||
+ /*
|
||||
+ * The perf_pmu__test_parse_init prepares perf_pmu_events_list
|
||||
+ * which gets freed in parse_events_terms.
|
||||
+ */
|
||||
+ if (perf_pmu__test_parse_init())
|
||||
+ return -1;
|
||||
+
|
||||
ret = parse_events_terms(&terms, t->str);
|
||||
if (ret) {
|
||||
pr_debug("failed to parse terms '%s', err %d\n",
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index 67ae5069737b..328d133933bf 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -1796,6 +1796,32 @@ static void perf_pmu__parse_init(void)
|
||||
perf_pmu__parse_cleanup();
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * This function injects special term in
|
||||
+ * perf_pmu_events_list so the test code
|
||||
+ * can check on this functionality.
|
||||
+ */
|
||||
+int perf_pmu__test_parse_init(void)
|
||||
+{
|
||||
+ struct perf_pmu_event_symbol *list;
|
||||
+
|
||||
+ list = malloc(sizeof(*list) * 1);
|
||||
+ if (!list)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ list->type = PMU_EVENT_SYMBOL;
|
||||
+ list->symbol = strdup("read");
|
||||
+
|
||||
+ if (!list->symbol) {
|
||||
+ free(list);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ perf_pmu_events_list = list;
|
||||
+ perf_pmu_events_list_num = 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
enum perf_pmu_event_symbol_type
|
||||
perf_pmu__parse_check(const char *name)
|
||||
{
|
||||
@@ -1856,6 +1882,8 @@ int parse_events_terms(struct list_head *terms, const char *str)
|
||||
int ret;
|
||||
|
||||
ret = parse_events__scanner(str, &parse_state);
|
||||
+ perf_pmu__parse_cleanup();
|
||||
+
|
||||
if (!ret) {
|
||||
list_splice(parse_state.terms, terms);
|
||||
zfree(&parse_state.terms);
|
||||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
||||
index 306f636aad96..28af56c9939f 100644
|
||||
--- a/tools/perf/util/parse-events.h
|
||||
+++ b/tools/perf/util/parse-events.h
|
||||
@@ -237,4 +237,6 @@ static inline bool is_sdt_event(char *str __maybe_unused)
|
||||
}
|
||||
#endif /* HAVE_LIBELF_SUPPORT */
|
||||
|
||||
+int perf_pmu__test_parse_init(void);
|
||||
+
|
||||
#endif /* __PERF_PARSE_EVENTS_H */
|
||||
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
|
||||
index 15ac319d94fa..1ff9f8805410 100644
|
||||
--- a/tools/perf/util/parse-events.l
|
||||
+++ b/tools/perf/util/parse-events.l
|
||||
@@ -41,14 +41,6 @@ static int value(yyscan_t scanner, int base)
|
||||
return __value(yylval, text, base, PE_VALUE);
|
||||
}
|
||||
|
||||
-static int raw(yyscan_t scanner)
|
||||
-{
|
||||
- YYSTYPE *yylval = parse_events_get_lval(scanner);
|
||||
- char *text = parse_events_get_text(scanner);
|
||||
-
|
||||
- return __value(yylval, text + 1, 16, PE_RAW);
|
||||
-}
|
||||
-
|
||||
static int str(yyscan_t scanner, int token)
|
||||
{
|
||||
YYSTYPE *yylval = parse_events_get_lval(scanner);
|
||||
@@ -72,6 +64,17 @@ static int str(yyscan_t scanner, int token)
|
||||
return token;
|
||||
}
|
||||
|
||||
+static int raw(yyscan_t scanner)
|
||||
+{
|
||||
+ YYSTYPE *yylval = parse_events_get_lval(scanner);
|
||||
+ char *text = parse_events_get_text(scanner);
|
||||
+
|
||||
+ if (perf_pmu__parse_check(text) == PMU_EVENT_SYMBOL)
|
||||
+ return str(scanner, PE_NAME);
|
||||
+
|
||||
+ return __value(yylval, text + 1, 16, PE_RAW);
|
||||
+}
|
||||
+
|
||||
static bool isbpf_suffix(char *text)
|
||||
{
|
||||
int len = strlen(text);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
188
patches/0208-perf-tools-Add-fake-pmu-support.patch
Normal file
188
patches/0208-perf-tools-Add-fake-pmu-support.patch
Normal file
@ -0,0 +1,188 @@
|
||||
From cfab54eab73c970afecf43fe5e2126e20caaf27a Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Tue, 2 Jun 2020 23:47:29 +0200
|
||||
Subject: [PATCH 091/201] perf tools: Add fake pmu support
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit 387ad33fe710758a8e1b860819a7452bceb4329a
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=387ad33fe710758a8e1b860819a7452bceb4329a
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add a way to create a pmu event without the actual PMU being in place.
|
||||
|
||||
This way we can test metrics defined for any processor.
|
||||
|
||||
The interface is to define fake_pmu in struct parse_events_state data.
|
||||
It will be used only in tests via special interface function added in
|
||||
following changes.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-2-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/parse-events.c
|
||||
tools/perf/util/parse-events.h
|
||||
---
|
||||
tools/perf/util/parse-events.c | 6 ++---
|
||||
tools/perf/util/parse-events.h | 1 +
|
||||
tools/perf/util/parse-events.l | 8 +++++--
|
||||
tools/perf/util/parse-events.y | 41 ++++++++++++++++++++++++++++++++--
|
||||
4 files changed, 49 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index 328d133933bf..f3fe4ed4a9ea 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -1266,7 +1266,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
||||
bool use_uncore_alias;
|
||||
LIST_HEAD(config_terms);
|
||||
|
||||
- pmu = perf_pmu__find(name);
|
||||
+ pmu = parse_state->fake_pmu ?: perf_pmu__find(name);
|
||||
if (!pmu) {
|
||||
if (asprintf(&err->str,
|
||||
"Cannot find PMU `%s'. Missing kernel support?",
|
||||
@@ -1297,7 +1297,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
||||
}
|
||||
}
|
||||
|
||||
- if (perf_pmu__check_alias(pmu, head_config, &info))
|
||||
+ if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &info))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
@@ -1310,7 +1310,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
||||
if (get_config_terms(head_config, &config_terms))
|
||||
return -ENOMEM;
|
||||
|
||||
- if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
|
||||
+ if (!parse_state->fake_pmu && perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
|
||||
struct perf_evsel_config_term *pos, *tmp;
|
||||
|
||||
list_for_each_entry_safe(pos, tmp, &config_terms, list) {
|
||||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
||||
index 28af56c9939f..c78809837f29 100644
|
||||
--- a/tools/perf/util/parse-events.h
|
||||
+++ b/tools/perf/util/parse-events.h
|
||||
@@ -120,6 +120,7 @@ struct parse_events_state {
|
||||
struct perf_evlist *evlist;
|
||||
struct list_head *terms;
|
||||
int stoken;
|
||||
+ struct perf_pmu *fake_pmu;
|
||||
};
|
||||
|
||||
void parse_events__shrink_config_terms(void);
|
||||
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
|
||||
index 1ff9f8805410..83ccfea42e9b 100644
|
||||
--- a/tools/perf/util/parse-events.l
|
||||
+++ b/tools/perf/util/parse-events.l
|
||||
@@ -132,12 +132,16 @@ do { \
|
||||
yyless(0); \
|
||||
} while (0)
|
||||
|
||||
-static int pmu_str_check(yyscan_t scanner)
|
||||
+static int pmu_str_check(yyscan_t scanner, struct parse_events_state *parse_state)
|
||||
{
|
||||
YYSTYPE *yylval = parse_events_get_lval(scanner);
|
||||
char *text = parse_events_get_text(scanner);
|
||||
|
||||
yylval->str = strdup(text);
|
||||
+
|
||||
+ if (parse_state->fake_pmu)
|
||||
+ return PE_PMU_EVENT_FAKE;
|
||||
+
|
||||
switch (perf_pmu__parse_check(text)) {
|
||||
case PMU_EVENT_SYMBOL_PREFIX:
|
||||
return PE_PMU_EVENT_PRE;
|
||||
@@ -372,7 +376,7 @@ r{num_raw_hex} { return raw(yyscanner); }
|
||||
{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
|
||||
{bpf_object} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_OBJECT); }
|
||||
{bpf_source} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_SOURCE); }
|
||||
-{name} { return pmu_str_check(yyscanner); }
|
||||
+{name} { return pmu_str_check(yyscanner, _parse_state); }
|
||||
{name_tag} { return str(yyscanner, PE_NAME); }
|
||||
"/" { BEGIN(config); return '/'; }
|
||||
- { return '-'; }
|
||||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
|
||||
index ff913778a7d4..f03da974770c 100644
|
||||
--- a/tools/perf/util/parse-events.y
|
||||
+++ b/tools/perf/util/parse-events.y
|
||||
@@ -59,7 +59,7 @@ static void inc_group_count(struct list_head *list,
|
||||
%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
|
||||
%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
|
||||
%token PE_ERROR
|
||||
-%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
|
||||
+%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
|
||||
%token PE_ARRAY_ALL PE_ARRAY_RANGE
|
||||
%token PE_DRV_CFG_TERM
|
||||
%type <num> PE_VALUE
|
||||
@@ -76,7 +76,7 @@ static void inc_group_count(struct list_head *list,
|
||||
%type <str> PE_MODIFIER_EVENT
|
||||
%type <str> PE_MODIFIER_BP
|
||||
%type <str> PE_EVENT_NAME
|
||||
-%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
|
||||
+%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
|
||||
%type <str> PE_DRV_CFG_TERM
|
||||
%type <num> value_sym
|
||||
%type <head> event_config
|
||||
@@ -301,6 +301,43 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
|
||||
YYABORT;
|
||||
$$ = list;
|
||||
}
|
||||
+|
|
||||
+PE_PMU_EVENT_FAKE sep_dc
|
||||
+{
|
||||
+ struct list_head *list;
|
||||
+ int err;
|
||||
+
|
||||
+ list = alloc_list();
|
||||
+ if (!list)
|
||||
+ YYABORT;
|
||||
+
|
||||
+ err = parse_events_add_pmu(_parse_state, list, $1, NULL, false, false);
|
||||
+ free($1);
|
||||
+ if (err < 0) {
|
||||
+ free(list);
|
||||
+ YYABORT;
|
||||
+ }
|
||||
+ $$ = list;
|
||||
+}
|
||||
+|
|
||||
+PE_PMU_EVENT_FAKE opt_pmu_config
|
||||
+{
|
||||
+ struct list_head *list;
|
||||
+ int err;
|
||||
+
|
||||
+ list = alloc_list();
|
||||
+ if (!list)
|
||||
+ YYABORT;
|
||||
+
|
||||
+ err = parse_events_add_pmu(_parse_state, list, $1, $2, false, false);
|
||||
+ free($1);
|
||||
+ parse_events_terms__delete($2);
|
||||
+ if (err < 0) {
|
||||
+ free(list);
|
||||
+ YYABORT;
|
||||
+ }
|
||||
+ $$ = list;
|
||||
+}
|
||||
|
||||
value_sym:
|
||||
PE_VALUE_SYM_HW
|
||||
--
|
||||
2.27.0
|
||||
|
||||
99
patches/0209-perf-tests-Factor-check_parse_id-function.patch
Normal file
99
patches/0209-perf-tests-Factor-check_parse_id-function.patch
Normal file
@ -0,0 +1,99 @@
|
||||
From e55faa87583d6afabe8506954c5f0ace70c5051a Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Tue, 2 Jun 2020 23:47:31 +0200
|
||||
Subject: [PATCH 092/201] perf tests: Factor check_parse_id function
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit 34bacc9578de2893ab6301cea89ea001d8e4cf5b
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34bacc9578de2893ab6301cea89ea001d8e4cf5b
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Separating the generic part of check_parse_id function,
|
||||
so it can be used in following changes for the new test.
|
||||
|
||||
Committer notes:
|
||||
|
||||
Fix this error:
|
||||
|
||||
tests/pmu-events.c:413:40: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
|
||||
struct parse_events_error error = { 0 };
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-4-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/tests/pmu-events.c
|
||||
---
|
||||
tools/perf/tests/pmu-events.c | 20 ++++++++++++++------
|
||||
1 file changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
|
||||
index 41dab7e36761..7269bdeeda2c 100644
|
||||
--- a/tools/perf/tests/pmu-events.c
|
||||
+++ b/tools/perf/tests/pmu-events.c
|
||||
@@ -390,9 +390,8 @@ static bool is_number(const char *str)
|
||||
return errno == 0 && end_ptr != str;
|
||||
}
|
||||
|
||||
-static int check_parse_id(const char *id, bool same_cpu, struct pmu_event *pe)
|
||||
+static int check_parse_id(const char *id, struct parse_events_error *error)
|
||||
{
|
||||
- struct parse_events_error error;
|
||||
struct perf_evlist *evlist;
|
||||
int ret;
|
||||
|
||||
@@ -401,8 +400,18 @@ static int check_parse_id(const char *id, bool same_cpu, struct pmu_event *pe)
|
||||
return 0;
|
||||
|
||||
evlist = perf_evlist__new();
|
||||
- memset(&error, 0, sizeof(error));
|
||||
- ret = parse_events(evlist, id, &error);
|
||||
+ if (!evlist)
|
||||
+ return -ENOMEM;
|
||||
+ ret = parse_events(evlist, id, error);
|
||||
+ perf_evlist__delete(evlist);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int check_parse_cpu(const char *id, bool same_cpu, struct pmu_event *pe)
|
||||
+{
|
||||
+ struct parse_events_error error = { .idx = 0, };
|
||||
+
|
||||
+ int ret = check_parse_id(id, &error);
|
||||
if (ret && same_cpu) {
|
||||
pr_warning("Parse event failed metric '%s' id '%s' expr '%s'\n",
|
||||
pe->metric_name, id, pe->metric_expr);
|
||||
@@ -413,7 +422,6 @@ static int check_parse_id(const char *id, bool same_cpu, struct pmu_event *pe)
|
||||
id, pe->metric_name, pe->metric_expr);
|
||||
ret = 0;
|
||||
}
|
||||
- perf_evlist__delete(evlist);
|
||||
free(error.str);
|
||||
free(error.help);
|
||||
return ret;
|
||||
@@ -472,7 +480,7 @@ static int test_parsing(void)
|
||||
expr__add_id(&ctx, strdup(cur->key), k++);
|
||||
|
||||
hashmap__for_each_entry((&ctx.ids), cur, bkt) {
|
||||
- if (check_parse_id(cur->key, map == cpus_map,
|
||||
+ if (check_parse_cpu(cur->key, map == cpus_map,
|
||||
pe))
|
||||
ret++;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
From 42dc1676164d4ab890ebe2cf704136e49429ad00 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Wed, 3 Jun 2020 12:32:55 -0300
|
||||
Subject: [PATCH 093/201] perf parse: Provide a way to pass a fake_pmu to
|
||||
parse_events()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit 3bf91aa5aa493b2ac24ffcfc93ffe861bf03685f
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3bf91aa5aa493b2ac24ffcfc93ffe861bf03685f
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This is an alternative patch to what Jiri sent that instead of changing
|
||||
all callers to parse_events() for allowing to pass a fake_pmu, provide
|
||||
another function specifically for that.
|
||||
|
||||
From Jiri's patch:
|
||||
|
||||
This way it's possible to parse events from PMUs which are not present
|
||||
in the system. It's available only for testing purposes coming in
|
||||
following changes, so all the current users set fake_pmu argument as
|
||||
false.
|
||||
|
||||
Based-on-a-patch-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-3-jolsa@kernel.org
|
||||
Acked-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ian Rogers <irogers@google.com>
|
||||
Cc: Ingo Molnar <mingo@kernel.org>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/parse-events.c
|
||||
tools/perf/util/parse-events.h
|
||||
---
|
||||
tools/perf/util/parse-events.c | 15 ++++++++-------
|
||||
tools/perf/util/parse-events.h | 12 ++++++++++--
|
||||
2 files changed, 18 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
||||
index f3fe4ed4a9ea..b96fe0525b1b 100644
|
||||
--- a/tools/perf/util/parse-events.c
|
||||
+++ b/tools/perf/util/parse-events.c
|
||||
@@ -1894,15 +1894,16 @@ int parse_events_terms(struct list_head *terms, const char *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int parse_events(struct perf_evlist *evlist, const char *str,
|
||||
- struct parse_events_error *err)
|
||||
+int __parse_events(struct perf_evlist *evlist, const char *str,
|
||||
+ struct parse_events_error *err, struct perf_pmu *fake_pmu)
|
||||
{
|
||||
struct parse_events_state parse_state = {
|
||||
- .list = LIST_HEAD_INIT(parse_state.list),
|
||||
- .idx = evlist->nr_entries,
|
||||
- .error = err,
|
||||
- .evlist = evlist,
|
||||
- .stoken = PE_START_EVENTS,
|
||||
+ .list = LIST_HEAD_INIT(parse_state.list),
|
||||
+ .idx = evlist->nr_entries,
|
||||
+ .error = err,
|
||||
+ .evlist = evlist,
|
||||
+ .stoken = PE_START_EVENTS,
|
||||
+ .fake_pmu = fake_pmu,
|
||||
};
|
||||
int ret;
|
||||
|
||||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
||||
index c78809837f29..ffe0c04c6cdb 100644
|
||||
--- a/tools/perf/util/parse-events.h
|
||||
+++ b/tools/perf/util/parse-events.h
|
||||
@@ -17,6 +17,7 @@ struct perf_evlist;
|
||||
struct parse_events_error;
|
||||
|
||||
struct option;
|
||||
+struct perf_pmu;
|
||||
|
||||
struct tracepoint_path {
|
||||
char *system;
|
||||
@@ -31,8 +32,15 @@ bool have_tracepoints(struct list_head *evlist);
|
||||
const char *event_type(int type);
|
||||
|
||||
int parse_events_option(const struct option *opt, const char *str, int unset);
|
||||
-int parse_events(struct perf_evlist *evlist, const char *str,
|
||||
- struct parse_events_error *error);
|
||||
+int __parse_events(struct perf_evlist *evlist, const char *str, struct parse_events_error *error,
|
||||
+ struct perf_pmu *fake_pmu);
|
||||
+
|
||||
+static inline int parse_events(struct perf_evlist *evlist, const char *str,
|
||||
+ struct parse_events_error *err)
|
||||
+{
|
||||
+ return __parse_events(evlist, str, err, NULL);
|
||||
+}
|
||||
+
|
||||
int parse_events_terms(struct list_head *terms, const char *str);
|
||||
int parse_filter(const struct option *opt, const char *str, int unset);
|
||||
int exclude_perf(const struct option *opt, const char *arg, int unset);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
From 5f51ac014c4ff646e1347b1e3dd7a8ee1419c23a Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Tue, 9 Jun 2020 13:23:24 -0300
|
||||
Subject: [PATCH 094/201] perf pmu: Add a perf_pmu__fake object to use with
|
||||
__parse_events()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit e46fc8d9dd352c88fec49b140008958d2dc1efe1
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e46fc8d9dd352c88fec49b140008958d2dc1efe1
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
When wanting to use the support in __parse_events() for fake pmus, just
|
||||
pass it.
|
||||
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ian Rogers <irogers@google.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/pmu.c | 2 ++
|
||||
tools/perf/util/pmu.h | 2 ++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
|
||||
index 7eefbebbf990..7217b8fac00d 100644
|
||||
--- a/tools/perf/util/pmu.c
|
||||
+++ b/tools/perf/util/pmu.c
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "cache.h"
|
||||
#include "string2.h"
|
||||
|
||||
+struct perf_pmu perf_pmu__fake;
|
||||
+
|
||||
struct perf_pmu_format {
|
||||
char *name;
|
||||
int value;
|
||||
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
|
||||
index 79f167db4a33..c44c4a701bf4 100644
|
||||
--- a/tools/perf/util/pmu.h
|
||||
+++ b/tools/perf/util/pmu.h
|
||||
@@ -33,6 +33,8 @@ struct perf_pmu {
|
||||
int (*set_drv_config) (struct perf_evsel_config_term *term);
|
||||
};
|
||||
|
||||
+extern struct perf_pmu perf_pmu__fake;
|
||||
+
|
||||
struct perf_pmu_info {
|
||||
const char *unit;
|
||||
const char *metric_expr;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
252
patches/0212-perf-tests-Add-another-metric-parsing-test.patch
Normal file
252
patches/0212-perf-tests-Add-another-metric-parsing-test.patch
Normal file
@ -0,0 +1,252 @@
|
||||
From a19b089ceb882c3e227f45080a2047c2b1744acd Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Wed, 3 Jun 2020 12:51:15 -0300
|
||||
Subject: [PATCH 095/201] perf tests: Add another metric parsing test
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit e1c92a7fbbc5668510736624df3028accd6af0ea
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e1c92a7fbbc5668510736624df3028accd6af0ea
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The test goes through all metrics compiled for arch within pmu events
|
||||
and try to parse them.
|
||||
|
||||
This test is different from 'test_parsing' in that we go through all the
|
||||
events in the current arch, not just one defined for current CPU model.
|
||||
Using 'fake_pmu' to parse events which do not have PMUs defined in the
|
||||
system.
|
||||
|
||||
Say there's bad change in ivybridge metrics file, like:
|
||||
|
||||
- a/tools/perf/pmu-events/arch/x86/ivybridge/ivb-metrics.json
|
||||
+ b/tools/perf/pmu-events/arch/x86/ivybridge/ivb-metrics.json
|
||||
@@ -8,7 +8,7 @@
|
||||
- "MetricExpr": "IDQ_UOPS_NOT_DELIVERED.CORE / (4 * ((
|
||||
+ "MetricExpr": "IDQ_UOPS_NOT_DELIVERED.CORE / / (4 *
|
||||
|
||||
the test fails with (on my kabylake laptop):
|
||||
|
||||
$ perf test 'Parsing of PMU event table metrics with fake PMUs' -v
|
||||
parsing 'idq_uops_not_delivered.core / / (4 * (( ( cpu_clk_unh...
|
||||
syntax error, line 1
|
||||
expr__parse failed
|
||||
test child finished with -1
|
||||
...
|
||||
|
||||
The test also defines its own list of metrics and tries to parse them.
|
||||
It's handy for developing.
|
||||
|
||||
Committer notes:
|
||||
|
||||
Testing it:
|
||||
|
||||
$ perf test fake
|
||||
10: PMU events :
|
||||
10.4: Parsing of PMU event table metrics with fake PMUs : FAILED!
|
||||
$ perf test -v fake |& tail
|
||||
parsing '(unc_p_freq_trans_cycles / unc_p_clockticks) * 100.'
|
||||
parsing '(unc_m_power_channel_ppd / unc_m_clockticks) * 100.'
|
||||
parsing '(unc_m_power_critical_throttle_cycles / unc_m_clockticks) * 100.'
|
||||
parsing '(unc_m_power_self_refresh / unc_m_clockticks) * 100.'
|
||||
parsing 'idq_uops_not_delivered.core / * (4 * cycles)'
|
||||
syntax error
|
||||
expr__parse failed
|
||||
test child finished with -1
|
||||
---- end ----
|
||||
PMU events subtest 4: FAILED!
|
||||
$
|
||||
|
||||
And fix this error:
|
||||
|
||||
tests/pmu-events.c:437:40: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
|
||||
struct parse_events_error error = { 0 };
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ian Rogers <irogers@google.com>
|
||||
Cc: Ingo Molnar <mingo@kernel.org>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-5-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/tests/pmu-events.c
|
||||
---
|
||||
tools/perf/tests/pmu-events.c | 115 +++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 112 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
|
||||
index 7269bdeeda2c..0a6611d8ec32 100644
|
||||
--- a/tools/perf/tests/pmu-events.c
|
||||
+++ b/tools/perf/tests/pmu-events.c
|
||||
@@ -390,7 +390,8 @@ static bool is_number(const char *str)
|
||||
return errno == 0 && end_ptr != str;
|
||||
}
|
||||
|
||||
-static int check_parse_id(const char *id, struct parse_events_error *error)
|
||||
+static int check_parse_id(const char *id, struct parse_events_error *error,
|
||||
+ struct perf_pmu *fake_pmu)
|
||||
{
|
||||
struct perf_evlist *evlist;
|
||||
int ret;
|
||||
@@ -402,7 +403,7 @@ static int check_parse_id(const char *id, struct parse_events_error *error)
|
||||
evlist = perf_evlist__new();
|
||||
if (!evlist)
|
||||
return -ENOMEM;
|
||||
- ret = parse_events(evlist, id, error);
|
||||
+ ret = __parse_events(evlist, id, error, fake_pmu);
|
||||
perf_evlist__delete(evlist);
|
||||
return ret;
|
||||
}
|
||||
@@ -411,7 +412,7 @@ static int check_parse_cpu(const char *id, bool same_cpu, struct pmu_event *pe)
|
||||
{
|
||||
struct parse_events_error error = { .idx = 0, };
|
||||
|
||||
- int ret = check_parse_id(id, &error);
|
||||
+ int ret = check_parse_id(id, &error, NULL);
|
||||
if (ret && same_cpu) {
|
||||
pr_warning("Parse event failed metric '%s' id '%s' expr '%s'\n",
|
||||
pe->metric_name, id, pe->metric_expr);
|
||||
@@ -427,6 +428,16 @@ static int check_parse_cpu(const char *id, bool same_cpu, struct pmu_event *pe)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int check_parse_fake(const char *id)
|
||||
+{
|
||||
+ struct parse_events_error error = { .idx = 0, };
|
||||
+ int ret = check_parse_id(id, &error, &perf_pmu__fake);
|
||||
+
|
||||
+ free(error.str);
|
||||
+ free(error.help);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void expr_failure(const char *msg,
|
||||
const struct pmu_events_map *map,
|
||||
const struct pmu_event *pe)
|
||||
@@ -496,6 +507,100 @@ static int test_parsing(void)
|
||||
return ret == 0 ? TEST_OK : TEST_SKIP;
|
||||
}
|
||||
|
||||
+struct test_metric {
|
||||
+ const char *str;
|
||||
+};
|
||||
+
|
||||
+static struct test_metric metrics[] = {
|
||||
+ { "(unc_p_power_state_occupancy.cores_c0 / unc_p_clockticks) * 100." },
|
||||
+ { "imx8_ddr0@read\\-cycles@ * 4 * 4", },
|
||||
+ { "imx8_ddr0@axid\\-read\\,axi_mask\\=0xffff\\,axi_id\\=0x0000@ * 4", },
|
||||
+ { "(cstate_pkg@c2\\-residency@ / msr@tsc@) * 100", },
|
||||
+ { "(imx8_ddr0@read\\-cycles@ + imx8_ddr0@write\\-cycles@)", },
|
||||
+};
|
||||
+
|
||||
+static int metric_parse_fake(const char *str)
|
||||
+{
|
||||
+ struct expr_parse_ctx ctx;
|
||||
+ struct hashmap_entry *cur;
|
||||
+ double result;
|
||||
+ int ret = -1;
|
||||
+ size_t bkt;
|
||||
+ int i;
|
||||
+
|
||||
+ pr_debug("parsing '%s'\n", str);
|
||||
+
|
||||
+ expr__ctx_init(&ctx);
|
||||
+ if (expr__find_other(str, NULL, &ctx, 0) < 0) {
|
||||
+ pr_err("expr__find_other failed\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Add all ids with a made up value. The value may
|
||||
+ * trigger divide by zero when subtracted and so try to
|
||||
+ * make them unique.
|
||||
+ */
|
||||
+ i = 1;
|
||||
+ hashmap__for_each_entry((&ctx.ids), cur, bkt)
|
||||
+ expr__add_id(&ctx, strdup(cur->key), i++);
|
||||
+
|
||||
+ hashmap__for_each_entry((&ctx.ids), cur, bkt) {
|
||||
+ if (check_parse_fake(cur->key)) {
|
||||
+ pr_err("check_parse_fake failed\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (expr__parse(&result, &ctx, str, 1))
|
||||
+ pr_err("expr__parse failed\n");
|
||||
+ else
|
||||
+ ret = 0;
|
||||
+
|
||||
+out:
|
||||
+ expr__ctx_clear(&ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Parse all the metrics for current architecture,
|
||||
+ * or all defined cpus via the 'fake_pmu'
|
||||
+ * in parse_events.
|
||||
+ */
|
||||
+static int test_parsing_fake(void)
|
||||
+{
|
||||
+ struct pmu_events_map *map;
|
||||
+ struct pmu_event *pe;
|
||||
+ unsigned int i, j;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(metrics); i++) {
|
||||
+ err = metric_parse_fake(metrics[i].str);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ i = 0;
|
||||
+ for (;;) {
|
||||
+ map = &pmu_events_map[i++];
|
||||
+ if (!map->table)
|
||||
+ break;
|
||||
+ j = 0;
|
||||
+ for (;;) {
|
||||
+ pe = &map->table[j++];
|
||||
+ if (!pe->name && !pe->metric_group && !pe->metric_name)
|
||||
+ break;
|
||||
+ if (!pe->metric_expr)
|
||||
+ continue;
|
||||
+ err = metric_parse_fake(pe->metric_expr);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct {
|
||||
int (*func)(void);
|
||||
const char *desc;
|
||||
@@ -512,6 +617,10 @@ static const struct {
|
||||
.func = test_parsing,
|
||||
.desc = "Parsing of PMU event table metrics",
|
||||
},
|
||||
+ {
|
||||
+ .func = test_parsing_fake,
|
||||
+ .desc = "Parsing of PMU event table metrics with fake PMUs",
|
||||
+ },
|
||||
};
|
||||
|
||||
const char *test__pmu_events_subtest_get_desc(int subtest)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
From f86993e23c3bc1178c82ef5e361484dfc30456ff Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Tue, 2 Jun 2020 23:47:33 +0200
|
||||
Subject: [PATCH 096/201] perf parse: Factor out parse_groups() function
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit 8b4468a2107af32b796fa818e5fb76481c39ee5a
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8b4468a2107af32b796fa818e5fb76481c39ee5a
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Factor out the parse_groups function, it will be used for new test
|
||||
interface coming in following changes.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-6-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 22 ++++++++++++++++------
|
||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 8fa4b98f6231..d2f54aa12b33 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -716,14 +716,12 @@ static void metricgroup__free_egroups(struct list_head *group_list)
|
||||
}
|
||||
}
|
||||
|
||||
-int metricgroup__parse_groups(const struct option *opt,
|
||||
- const char *str,
|
||||
- bool metric_no_group,
|
||||
- bool metric_no_merge,
|
||||
- struct rblist *metric_events)
|
||||
+static int parse_groups(struct perf_evlist *perf_evlist, const char *str,
|
||||
+ bool metric_no_group,
|
||||
+ bool metric_no_merge,
|
||||
+ struct rblist *metric_events)
|
||||
{
|
||||
struct parse_events_error parse_error;
|
||||
- struct perf_evlist *perf_evlist = *(struct perf_evlist **)opt->value;
|
||||
struct strbuf extra_events;
|
||||
LIST_HEAD(group_list);
|
||||
int ret;
|
||||
@@ -749,6 +747,18 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int metricgroup__parse_groups(const struct option *opt,
|
||||
+ const char *str,
|
||||
+ bool metric_no_group,
|
||||
+ bool metric_no_merge,
|
||||
+ struct rblist *metric_events)
|
||||
+{
|
||||
+ struct perf_evlist *perf_evlist = *(struct perf_evlist **)opt->value;
|
||||
+
|
||||
+ return parse_groups(perf_evlist, str, metric_no_group,
|
||||
+ metric_no_merge, metric_events);
|
||||
+}
|
||||
+
|
||||
bool metricgroup__has_metric(const char *metric)
|
||||
{
|
||||
struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
From 28ba4a7842588c0d3daf91b8e910d04f72f20c26 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Tue, 9 Jun 2020 12:50:42 -0300
|
||||
Subject: [PATCH 097/201] perf tools: Add fake_pmu to parse_group() function
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit 68173bda6ac9d498e450276323f1c10a1d0307ad
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=68173bda6ac9d498e450276323f1c10a1d0307ad
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Allow to pass fake_pmu in parse_groups function so it can be used in
|
||||
parse_events call.
|
||||
|
||||
It's will be passed by the upcoming metricgroup__parse_groups_test
|
||||
function.
|
||||
|
||||
Committer notes:
|
||||
|
||||
Made it a 'struct perf_pmu' pointer, in line with the changes at the
|
||||
start of this patchkit to avoid statics deep down in library code.
|
||||
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ingo Molnar <mingo@kernel.org>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-6-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index d2f54aa12b33..9fa47eb1b968 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -719,6 +719,7 @@ static void metricgroup__free_egroups(struct list_head *group_list)
|
||||
static int parse_groups(struct perf_evlist *perf_evlist, const char *str,
|
||||
bool metric_no_group,
|
||||
bool metric_no_merge,
|
||||
+ struct perf_pmu *fake_pmu,
|
||||
struct rblist *metric_events)
|
||||
{
|
||||
struct parse_events_error parse_error;
|
||||
@@ -734,7 +735,7 @@ static int parse_groups(struct perf_evlist *perf_evlist, const char *str,
|
||||
return ret;
|
||||
pr_debug("adding %s\n", extra_events.buf);
|
||||
memset(&parse_error, 0, sizeof(struct parse_events_error));
|
||||
- ret = parse_events(perf_evlist, extra_events.buf, &parse_error);
|
||||
+ ret = __parse_events(perf_evlist, extra_events.buf, &parse_error, fake_pmu);
|
||||
if (ret) {
|
||||
parse_events_print_error(&parse_error, extra_events.buf);
|
||||
goto out;
|
||||
@@ -756,7 +757,7 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
struct perf_evlist *perf_evlist = *(struct perf_evlist **)opt->value;
|
||||
|
||||
return parse_groups(perf_evlist, str, metric_no_group,
|
||||
- metric_no_merge, metric_events);
|
||||
+ metric_no_merge, NULL, metric_events);
|
||||
}
|
||||
|
||||
bool metricgroup__has_metric(const char *metric)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
116
patches/0215-perf-tools-Add-map-to-parse_groups-function.patch
Normal file
116
patches/0215-perf-tools-Add-map-to-parse_groups-function.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From 7d56affe37448a05c6dc70ea14dd25980bf90a97 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Tue, 9 Jun 2020 12:57:47 -0300
|
||||
Subject: [PATCH 098/201] perf tools: Add map to parse_groups() function
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit 1381396b0b778c918bf191b1960f92fbd563476d
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1381396b0b778c918bf191b1960f92fbd563476d
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
For testing purposes we need to pass our own map of events from
|
||||
parse_groups() through metricgroup__add_metric.
|
||||
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Ingo Molnar <mingo@kernel.org>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-8-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
tools/perf/util/metricgroup.c
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 23 +++++++++++++----------
|
||||
1 file changed, 13 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index 9fa47eb1b968..b3feb3b5cd99 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -604,17 +604,14 @@ static int __metricgroup__add_metric(struct list_head *group_list,
|
||||
|
||||
static int metricgroup__add_metric(const char *metric, bool metric_no_group,
|
||||
struct strbuf *events,
|
||||
- struct list_head *group_list)
|
||||
+ struct list_head *group_list,
|
||||
+ struct pmu_events_map *map)
|
||||
{
|
||||
- struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
struct pmu_event *pe;
|
||||
struct egroup *eg;
|
||||
int i, ret;
|
||||
bool has_match = false;
|
||||
|
||||
- if (!map)
|
||||
- return 0;
|
||||
-
|
||||
for (i = 0; ; i++) {
|
||||
pe = &map->table[i];
|
||||
|
||||
@@ -675,7 +672,8 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
|
||||
|
||||
static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
|
||||
struct strbuf *events,
|
||||
- struct list_head *group_list)
|
||||
+ struct list_head *group_list,
|
||||
+ struct pmu_events_map *map)
|
||||
{
|
||||
char *llist, *nlist, *p;
|
||||
int ret = -EINVAL;
|
||||
@@ -690,7 +688,7 @@ static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
|
||||
|
||||
while ((p = strsep(&llist, ",")) != NULL) {
|
||||
ret = metricgroup__add_metric(p, metric_no_group, events,
|
||||
- group_list);
|
||||
+ group_list, map);
|
||||
if (ret == -EINVAL) {
|
||||
fprintf(stderr, "Cannot find metric or group `%s'\n",
|
||||
p);
|
||||
@@ -720,7 +718,8 @@ static int parse_groups(struct perf_evlist *perf_evlist, const char *str,
|
||||
bool metric_no_group,
|
||||
bool metric_no_merge,
|
||||
struct perf_pmu *fake_pmu,
|
||||
- struct rblist *metric_events)
|
||||
+ struct rblist *metric_events,
|
||||
+ struct pmu_events_map *map)
|
||||
{
|
||||
struct parse_events_error parse_error;
|
||||
struct strbuf extra_events;
|
||||
@@ -730,7 +729,7 @@ static int parse_groups(struct perf_evlist *perf_evlist, const char *str,
|
||||
if (metric_events->nr_entries == 0)
|
||||
metricgroup__rblist_init(metric_events);
|
||||
ret = metricgroup__add_metric_list(str, metric_no_group,
|
||||
- &extra_events, &group_list);
|
||||
+ &extra_events, &group_list, map);
|
||||
if (ret)
|
||||
return ret;
|
||||
pr_debug("adding %s\n", extra_events.buf);
|
||||
@@ -755,9 +754,13 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
struct rblist *metric_events)
|
||||
{
|
||||
struct perf_evlist *perf_evlist = *(struct perf_evlist **)opt->value;
|
||||
+ struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
+
|
||||
+ if (!map)
|
||||
+ return 0;
|
||||
|
||||
return parse_groups(perf_evlist, str, metric_no_group,
|
||||
- metric_no_merge, NULL, metric_events);
|
||||
+ metric_no_merge, NULL, metric_events, map);
|
||||
}
|
||||
|
||||
bool metricgroup__has_metric(const char *metric)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
From dcedd111e3843d6b47fb723282481c8cf1cce769 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Olsa <jolsa@kernel.org>
|
||||
Date: Tue, 2 Jun 2020 23:47:36 +0200
|
||||
Subject: [PATCH 099/201] perf tools: Add metricgroup__parse_groups_test
|
||||
function
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.9-rc1
|
||||
commit f78ac00a8c999f4418e69e606485784fc5ff1d09
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f78ac00a8c999f4418e69e606485784fc5ff1d09
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Add the metricgroup__parse_groups_test function. It will be used as
|
||||
test's interface to metric parsing in following changes.
|
||||
|
||||
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Acked-by: Ian Rogers <irogers@google.com>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Andi Kleen <ak@linux.intel.com>
|
||||
Cc: Michael Petlan <mpetlan@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: http://lore.kernel.org/lkml/20200602214741.1218986-9-jolsa@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
tools/perf/util/metricgroup.c | 11 +++++++++++
|
||||
tools/perf/util/metricgroup.h | 9 +++++++++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
|
||||
index b3feb3b5cd99..5058db5810aa 100644
|
||||
--- a/tools/perf/util/metricgroup.c
|
||||
+++ b/tools/perf/util/metricgroup.c
|
||||
@@ -763,6 +763,17 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
metric_no_merge, NULL, metric_events, map);
|
||||
}
|
||||
|
||||
+int metricgroup__parse_groups_test(struct perf_evlist *evlist,
|
||||
+ struct pmu_events_map *map,
|
||||
+ const char *str,
|
||||
+ bool metric_no_group,
|
||||
+ bool metric_no_merge,
|
||||
+ struct rblist *metric_events)
|
||||
+{
|
||||
+ return parse_groups(evlist, str, metric_no_group,
|
||||
+ metric_no_merge, &perf_pmu__fake, metric_events, map);
|
||||
+}
|
||||
+
|
||||
bool metricgroup__has_metric(const char *metric)
|
||||
{
|
||||
struct pmu_events_map *map = perf_pmu__find_map(NULL);
|
||||
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
|
||||
index b6dfd7d09b9c..11811764edde 100644
|
||||
--- a/tools/perf/util/metricgroup.h
|
||||
+++ b/tools/perf/util/metricgroup.h
|
||||
@@ -7,8 +7,10 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
struct perf_evsel;
|
||||
+struct perf_evlist;
|
||||
struct option;
|
||||
struct rblist;
|
||||
+struct pmu_events_map;
|
||||
|
||||
struct metric_event {
|
||||
struct rb_node nd;
|
||||
@@ -34,6 +36,13 @@ int metricgroup__parse_groups(const struct option *opt,
|
||||
bool metric_no_merge,
|
||||
struct rblist *metric_events);
|
||||
|
||||
+int metricgroup__parse_groups_test(struct perf_evlist *evlist,
|
||||
+ struct pmu_events_map *map,
|
||||
+ const char *str,
|
||||
+ bool metric_no_group,
|
||||
+ bool metric_no_merge,
|
||||
+ struct rblist *metric_events);
|
||||
+
|
||||
void metricgroup__print(bool metrics, bool groups, char *filter,
|
||||
bool raw, bool details);
|
||||
bool metricgroup__has_metric(const char *metric);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user