Skip to content

Commit dd9168a

Browse files
committed
Merge branch 'for-next/perf' into for-next/core
* for-next/perf: (30 commits) arm: perf: Fix ARCH=arm build with GCC MAINTAINERS: add maintainers for DesignWare PCIe PMU driver drivers/perf: add DesignWare PCIe PMU driver PCI: Move pci_clear_and_set_dword() helper to PCI header PCI: Add Alibaba Vendor ID to linux/pci_ids.h docs: perf: Add description for Synopsys DesignWare PCIe PMU driver Revert "perf/arm_dmc620: Remove duplicate format attribute #defines" Documentation: arm64: Document the PMU event counting threshold feature arm64: perf: Add support for event counting threshold arm: pmu: Move error message and -EOPNOTSUPP to individual PMUs KVM: selftests: aarch64: Update tools copy of arm_pmuv3.h perf/arm_dmc620: Remove duplicate format attribute #defines arm: pmu: Share user ABI format mechanism with SPE arm64: perf: Include threshold control fields in PMEVTYPER mask arm: perf: Convert remaining fields to use GENMASK arm: perf: Use GENMASK for PMMIR fields arm: perf/kvm: Use GENMASK for ARMV8_PMU_PMCR_N arm: perf: Remove inlines from arm_pmuv3.c drivers/perf: arm_dsu_pmu: Remove kerneldoc-style comment syntax drivers/perf: Remove usage of the deprecated ida_simple_xx() API ...
2 parents 3b47bd8 + bb339db commit dd9168a

File tree

32 files changed

+1375
-319
lines changed

32 files changed

+1375
-319
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
======================================================================
2+
Synopsys DesignWare Cores (DWC) PCIe Performance Monitoring Unit (PMU)
3+
======================================================================
4+
5+
DesignWare Cores (DWC) PCIe PMU
6+
===============================
7+
8+
The PMU is a PCIe configuration space register block provided by each PCIe Root
9+
Port in a Vendor-Specific Extended Capability named RAS D.E.S (Debug, Error
10+
injection, and Statistics).
11+
12+
As the name indicates, the RAS DES capability supports system level
13+
debugging, AER error injection, and collection of statistics. To facilitate
14+
collection of statistics, Synopsys DesignWare Cores PCIe controller
15+
provides the following two features:
16+
17+
- one 64-bit counter for Time Based Analysis (RX/TX data throughput and
18+
time spent in each low-power LTSSM state) and
19+
- one 32-bit counter for Event Counting (error and non-error events for
20+
a specified lane)
21+
22+
Note: There is no interrupt for counter overflow.
23+
24+
Time Based Analysis
25+
-------------------
26+
27+
Using this feature you can obtain information regarding RX/TX data
28+
throughput and time spent in each low-power LTSSM state by the controller.
29+
The PMU measures data in two categories:
30+
31+
- Group#0: Percentage of time the controller stays in LTSSM states.
32+
- Group#1: Amount of data processed (Units of 16 bytes).
33+
34+
Lane Event counters
35+
-------------------
36+
37+
Using this feature you can obtain Error and Non-Error information in
38+
specific lane by the controller. The PMU event is selected by all of:
39+
40+
- Group i
41+
- Event j within the Group i
42+
- Lane k
43+
44+
Some of the events only exist for specific configurations.
45+
46+
DesignWare Cores (DWC) PCIe PMU Driver
47+
=======================================
48+
49+
This driver adds PMU devices for each PCIe Root Port named based on the BDF of
50+
the Root Port. For example,
51+
52+
30:03.0 PCI bridge: Device 1ded:8000 (rev 01)
53+
54+
the PMU device name for this Root Port is dwc_rootport_3018.
55+
56+
The DWC PCIe PMU driver registers a perf PMU driver, which provides
57+
description of available events and configuration options in sysfs, see
58+
/sys/bus/event_source/devices/dwc_rootport_{bdf}.
59+
60+
The "format" directory describes format of the config fields of the
61+
perf_event_attr structure. The "events" directory provides configuration
62+
templates for all documented events. For example,
63+
"Rx_PCIe_TLP_Data_Payload" is an equivalent of "eventid=0x22,type=0x1".
64+
65+
The "perf list" command shall list the available events from sysfs, e.g.::
66+
67+
$# perf list | grep dwc_rootport
68+
<...>
69+
dwc_rootport_3018/Rx_PCIe_TLP_Data_Payload/ [Kernel PMU event]
70+
<...>
71+
dwc_rootport_3018/rx_memory_read,lane=?/ [Kernel PMU event]
72+
73+
Time Based Analysis Event Usage
74+
-------------------------------
75+
76+
Example usage of counting PCIe RX TLP data payload (Units of bytes)::
77+
78+
$# perf stat -a -e dwc_rootport_3018/Rx_PCIe_TLP_Data_Payload/
79+
80+
The average RX/TX bandwidth can be calculated using the following formula:
81+
82+
PCIe RX Bandwidth = Rx_PCIe_TLP_Data_Payload / Measure_Time_Window
83+
PCIe TX Bandwidth = Tx_PCIe_TLP_Data_Payload / Measure_Time_Window
84+
85+
Lane Event Usage
86+
-------------------------------
87+
88+
Each lane has the same event set and to avoid generating a list of hundreds
89+
of events, the user need to specify the lane ID explicitly, e.g.::
90+
91+
$# perf stat -a -e dwc_rootport_3018/rx_memory_read,lane=4/
92+
93+
The driver does not support sampling, therefore "perf record" will not
94+
work. Per-task (without "-a") perf sessions are not supported.

Documentation/admin-guide/perf/imx-ddr.rst

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ is one register for each counter. Counter 0 is special in that it always counts
1313
interrupt is raised. If any other counter overflows, it continues counting, and
1414
no interrupt is raised.
1515

16-
The "format" directory describes format of the config (event ID) and config1
17-
(AXI filtering) fields of the perf_event_attr structure, see /sys/bus/event_source/
16+
The "format" directory describes format of the config (event ID) and config1/2
17+
(AXI filter setting) fields of the perf_event_attr structure, see /sys/bus/event_source/
1818
devices/imx8_ddr0/format/. The "events" directory describes the events types
1919
hardware supported that can be used with perf tool, see /sys/bus/event_source/
2020
devices/imx8_ddr0/events/. The "caps" directory describes filter features implemented
@@ -28,12 +28,11 @@ in DDR PMU, see /sys/bus/events_source/devices/imx8_ddr0/caps/.
2828
AXI filtering is only used by CSV modes 0x41 (axid-read) and 0x42 (axid-write)
2929
to count reading or writing matches filter setting. Filter setting is various
3030
from different DRAM controller implementations, which is distinguished by quirks
31-
in the driver. You also can dump info from userspace, filter in "caps" directory
32-
indicates whether PMU supports AXI ID filter or not; enhanced_filter indicates
33-
whether PMU supports enhanced AXI ID filter or not. Value 0 for un-supported, and
34-
value 1 for supported.
31+
in the driver. You also can dump info from userspace, "caps" directory show the
32+
type of AXI filter (filter, enhanced_filter and super_filter). Value 0 for
33+
un-supported, and value 1 for supported.
3534

36-
* With DDR_CAP_AXI_ID_FILTER quirk(filter: 1, enhanced_filter: 0).
35+
* With DDR_CAP_AXI_ID_FILTER quirk(filter: 1, enhanced_filter: 0, super_filter: 0).
3736
Filter is defined with two configuration parts:
3837
--AXI_ID defines AxID matching value.
3938
--AXI_MASKING defines which bits of AxID are meaningful for the matching.
@@ -65,7 +64,37 @@ value 1 for supported.
6564
6665
perf stat -a -e imx8_ddr0/axid-read,axi_id=0x12/ cmd, which will monitor ARID=0x12
6766
68-
* With DDR_CAP_AXI_ID_FILTER_ENHANCED quirk(filter: 1, enhanced_filter: 1).
67+
* With DDR_CAP_AXI_ID_FILTER_ENHANCED quirk(filter: 1, enhanced_filter: 1, super_filter: 0).
6968
This is an extension to the DDR_CAP_AXI_ID_FILTER quirk which permits
7069
counting the number of bytes (as opposed to the number of bursts) from DDR
7170
read and write transactions concurrently with another set of data counters.
71+
72+
* With DDR_CAP_AXI_ID_PORT_CHANNEL_FILTER quirk(filter: 0, enhanced_filter: 0, super_filter: 1).
73+
There is a limitation in previous AXI filter, it cannot filter different IDs
74+
at the same time as the filter is shared between counters. This quirk is the
75+
extension of AXI ID filter. One improvement is that counter 1-3 has their own
76+
filter, means that it supports concurrently filter various IDs. Another
77+
improvement is that counter 1-3 supports AXI PORT and CHANNEL selection. Support
78+
selecting address channel or data channel.
79+
80+
Filter is defined with 2 configuration registers per counter 1-3.
81+
--Counter N MASK COMP register - including AXI_ID and AXI_MASKING.
82+
--Counter N MUX CNTL register - including AXI CHANNEL and AXI PORT.
83+
84+
- 0: address channel
85+
- 1: data channel
86+
87+
PMU in DDR subsystem, only one single port0 exists, so axi_port is reserved
88+
which should be 0.
89+
90+
.. code-block:: bash
91+
92+
perf stat -a -e imx8_ddr0/axid-read,axi_mask=0xMMMM,axi_id=0xDDDD,axi_channel=0xH/ cmd
93+
perf stat -a -e imx8_ddr0/axid-write,axi_mask=0xMMMM,axi_id=0xDDDD,axi_channel=0xH/ cmd
94+
95+
.. note::
96+
97+
axi_channel is inverted in userspace, and it will be reverted in driver
98+
automatically. So that users do not need specify axi_channel if want to
99+
monitor data channel from DDR transactions, since data channel is more
100+
meaningful.

Documentation/admin-guide/perf/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Performance monitor support
1919
arm_dsu_pmu
2020
thunderx2-pmu
2121
alibaba_pmu
22+
dwc_pcie_pmu
2223
nvidia-pmu
2324
meson-ddr-pmu
2425
cxl

Documentation/arch/arm64/perf.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,75 @@ and should be used to mask the upper bits as needed.
164164
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/arch/arm64/tests/user-events.c
165165
.. _tools/lib/perf/tests/test-evsel.c:
166166
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/perf/tests/test-evsel.c
167+
168+
Event Counting Threshold
169+
==========================================
170+
171+
Overview
172+
--------
173+
174+
FEAT_PMUv3_TH (Armv8.8) permits a PMU counter to increment only on
175+
events whose count meets a specified threshold condition. For example if
176+
threshold_compare is set to 2 ('Greater than or equal'), and the
177+
threshold is set to 2, then the PMU counter will now only increment by
178+
when an event would have previously incremented the PMU counter by 2 or
179+
more on a single processor cycle.
180+
181+
To increment by 1 after passing the threshold condition instead of the
182+
number of events on that cycle, add the 'threshold_count' option to the
183+
commandline.
184+
185+
How-to
186+
------
187+
188+
These are the parameters for controlling the feature:
189+
190+
.. list-table::
191+
:header-rows: 1
192+
193+
* - Parameter
194+
- Description
195+
* - threshold
196+
- Value to threshold the event by. A value of 0 means that
197+
thresholding is disabled and the other parameters have no effect.
198+
* - threshold_compare
199+
- | Comparison function to use, with the following values supported:
200+
|
201+
| 0: Not-equal
202+
| 1: Equals
203+
| 2: Greater-than-or-equal
204+
| 3: Less-than
205+
* - threshold_count
206+
- If this is set, count by 1 after passing the threshold condition
207+
instead of the value of the event on this cycle.
208+
209+
The threshold, threshold_compare and threshold_count values can be
210+
provided per event, for example:
211+
212+
.. code-block:: sh
213+
214+
perf stat -e stall_slot/threshold=2,threshold_compare=2/ \
215+
-e dtlb_walk/threshold=10,threshold_compare=3,threshold_count/
216+
217+
In this example the stall_slot event will count by 2 or more on every
218+
cycle where 2 or more stalls happen. And dtlb_walk will count by 1 on
219+
every cycle where the number of dtlb walks were less than 10.
220+
221+
The maximum supported threshold value can be read from the caps of each
222+
PMU, for example:
223+
224+
.. code-block:: sh
225+
226+
cat /sys/bus/event_source/devices/armv8_pmuv3/caps/threshold_max
227+
228+
0x000000ff
229+
230+
If a value higher than this is given, then opening the event will result
231+
in an error. The highest possible maximum is 4095, as the config field
232+
for threshold is limited to 12 bits, and the Perf tool will refuse to
233+
parse higher values.
234+
235+
If the PMU doesn't support FEAT_PMUv3_TH, then threshold_max will read
236+
0, and attempting to set a threshold value will also result in an error.
237+
threshold_max will also read as 0 on aarch32 guests, even if the host
238+
is running on hardware with the feature.

Documentation/devicetree/bindings/perf/fsl-imx-ddr.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ properties:
2727
- fsl,imx8mq-ddr-pmu
2828
- fsl,imx8mp-ddr-pmu
2929
- const: fsl,imx8m-ddr-pmu
30+
- items:
31+
- const: fsl,imx8dxl-ddr-pmu
32+
- const: fsl,imx8-ddr-pmu
3033

3134
reg:
3235
maxItems: 1

MAINTAINERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21090,6 +21090,13 @@ L: [email protected]
2109021090
S: Maintained
2109121091
F: drivers/mmc/host/dw_mmc*
2109221092

21093+
SYNOPSYS DESIGNWARE PCIE PMU DRIVER
21094+
M: Shuai Xue <[email protected]>
21095+
M: Jing Zhang <[email protected]>
21096+
S: Supported
21097+
F: Documentation/admin-guide/perf/dwc_pcie_pmu.rst
21098+
F: drivers/perf/dwc_pcie_pmu.c
21099+
2109321100
SYNOPSYS HSDK RESET CONTROLLER DRIVER
2109421101
M: Eugeniy Paltsev <[email protected]>
2109521102
S: Supported

arch/arm/kernel/perf_event_v6.c

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,8 @@ static inline void armv6pmu_write_counter(struct perf_event *event, u64 value)
268268

269269
static void armv6pmu_enable_event(struct perf_event *event)
270270
{
271-
unsigned long val, mask, evt, flags;
272-
struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
271+
unsigned long val, mask, evt;
273272
struct hw_perf_event *hwc = &event->hw;
274-
struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
275273
int idx = hwc->idx;
276274

277275
if (ARMV6_CYCLE_COUNTER == idx) {
@@ -294,12 +292,10 @@ static void armv6pmu_enable_event(struct perf_event *event)
294292
* Mask out the current event and set the counter to count the event
295293
* that we're interested in.
296294
*/
297-
raw_spin_lock_irqsave(&events->pmu_lock, flags);
298295
val = armv6_pmcr_read();
299296
val &= ~mask;
300297
val |= evt;
301298
armv6_pmcr_write(val);
302-
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
303299
}
304300

305301
static irqreturn_t
@@ -362,26 +358,20 @@ armv6pmu_handle_irq(struct arm_pmu *cpu_pmu)
362358

363359
static void armv6pmu_start(struct arm_pmu *cpu_pmu)
364360
{
365-
unsigned long flags, val;
366-
struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
361+
unsigned long val;
367362

368-
raw_spin_lock_irqsave(&events->pmu_lock, flags);
369363
val = armv6_pmcr_read();
370364
val |= ARMV6_PMCR_ENABLE;
371365
armv6_pmcr_write(val);
372-
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
373366
}
374367

375368
static void armv6pmu_stop(struct arm_pmu *cpu_pmu)
376369
{
377-
unsigned long flags, val;
378-
struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
370+
unsigned long val;
379371

380-
raw_spin_lock_irqsave(&events->pmu_lock, flags);
381372
val = armv6_pmcr_read();
382373
val &= ~ARMV6_PMCR_ENABLE;
383374
armv6_pmcr_write(val);
384-
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
385375
}
386376

387377
static int
@@ -419,10 +409,8 @@ static void armv6pmu_clear_event_idx(struct pmu_hw_events *cpuc,
419409

420410
static void armv6pmu_disable_event(struct perf_event *event)
421411
{
422-
unsigned long val, mask, evt, flags;
423-
struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
412+
unsigned long val, mask, evt;
424413
struct hw_perf_event *hwc = &event->hw;
425-
struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
426414
int idx = hwc->idx;
427415

428416
if (ARMV6_CYCLE_COUNTER == idx) {
@@ -444,20 +432,16 @@ static void armv6pmu_disable_event(struct perf_event *event)
444432
* of ETM bus signal assertion cycles. The external reporting should
445433
* be disabled and so this should never increment.
446434
*/
447-
raw_spin_lock_irqsave(&events->pmu_lock, flags);
448435
val = armv6_pmcr_read();
449436
val &= ~mask;
450437
val |= evt;
451438
armv6_pmcr_write(val);
452-
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
453439
}
454440

455441
static void armv6mpcore_pmu_disable_event(struct perf_event *event)
456442
{
457-
unsigned long val, mask, flags, evt = 0;
458-
struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
443+
unsigned long val, mask, evt = 0;
459444
struct hw_perf_event *hwc = &event->hw;
460-
struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
461445
int idx = hwc->idx;
462446

463447
if (ARMV6_CYCLE_COUNTER == idx) {
@@ -475,12 +459,10 @@ static void armv6mpcore_pmu_disable_event(struct perf_event *event)
475459
* Unlike UP ARMv6, we don't have a way of stopping the counters. We
476460
* simply disable the interrupt reporting.
477461
*/
478-
raw_spin_lock_irqsave(&events->pmu_lock, flags);
479462
val = armv6_pmcr_read();
480463
val &= ~mask;
481464
val |= evt;
482465
armv6_pmcr_write(val);
483-
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
484466
}
485467

486468
static int armv6_map_event(struct perf_event *event)

0 commit comments

Comments
 (0)