[PATCH v3 2/2] drivers/perf: hisi: Add driver for HiSilicon PCIe PMU

2021-04-15 Thread Qi Liu
PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported
to sample bandwidth, latency, buffer occupation etc.

Each PMU RCiEP device monitors multiple Root Ports, and each RCiEP is
registered as a PMU in /sys/bus/event_source/devices, so users can
select target PMU, and use filter to do further sets.

Filtering options contains:
event- select the event.
subevent - select the subevent.
port - select target Root Ports. Information of Root Ports
   are shown under sysfs.
bdf  - select requester_id of target EP device.
trig_len - set trigger condition for starting event statistics.
trigger_mode - set trigger mode. 0 means starting to statistic when
   bigger than trigger condition, and 1 means smaller.
thr_len  - set threshold for statistics.
thr_mode - set threshold mode. 0 means count when bigger than
   threshold, and 1 means smaller.

Signed-off-by: Qi Liu 
---
 MAINTAINERS|6 +
 drivers/perf/Kconfig   |2 +
 drivers/perf/Makefile  |1 +
 drivers/perf/pci/Kconfig   |   16 +
 drivers/perf/pci/Makefile  |2 +
 drivers/perf/pci/hisilicon/Makefile|3 +
 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c | 1014 
 include/linux/cpuhotplug.h |1 +
 8 files changed, 1045 insertions(+)
 create mode 100644 drivers/perf/pci/Kconfig
 create mode 100644 drivers/perf/pci/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7fdc513..efe06cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8084,6 +8084,12 @@ W:   http://www.hisilicon.com
 F: Documentation/admin-guide/perf/hisi-pmu.rst
 F: drivers/perf/hisilicon
 
+HISILICON PCIE PMU DRIVER
+M: Qi Liu 
+S: Maintained
+F: Documentation/admin-guide/perf/hisi-pcie-pmu.rst
+F: drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
+
 HISILICON QM AND ZIP Controller DRIVER
 M: Zhou Wang 
 L: linux-cry...@vger.kernel.org
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 77522e5..ddd82fa 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -139,4 +139,6 @@ config ARM_DMC620_PMU
 
 source "drivers/perf/hisilicon/Kconfig"
 
+source "drivers/perf/pci/Kconfig"
+
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 5260b11..1208c08 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
+obj-y += pci/
diff --git a/drivers/perf/pci/Kconfig b/drivers/perf/pci/Kconfig
new file mode 100644
index 000..9f30291
--- /dev/null
+++ b/drivers/perf/pci/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# PCIe Performance Monitor Drivers
+#
+menu "PCIe Performance Monitor"
+
+config HISI_PCIE_PMU
+   tristate "HiSilicon PCIE PERF PMU"
+   depends on (ARM64 && PCI) || COMPILE_TEST
+   help
+ Provide support for HiSilicon PCIe performance monitoring unit (PMU)
+ RCiEP devices.
+ Adds the PCIe PMU into perf events system for monitoring latency,
+ bandwidth etc.
+
+endmenu
diff --git a/drivers/perf/pci/Makefile b/drivers/perf/pci/Makefile
new file mode 100644
index 000..a56b1a9
--- /dev/null
+++ b/drivers/perf/pci/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += hisilicon/
diff --git a/drivers/perf/pci/hisilicon/Makefile 
b/drivers/perf/pci/hisilicon/Makefile
new file mode 100644
index 000..65b0bd7
--- /dev/null
+++ b/drivers/perf/pci/hisilicon/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
diff --git a/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c 
b/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
new file mode 100644
index 000..415bf39
--- /dev/null
+++ b/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
@@ -0,0 +1,1014 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This driver adds support for PCIe PMU RCiEP device. Related
+ * perf events are bandwidth, bandwidth utilization, latency
+ * etc.
+ *
+ * Copyright (C) 2021 HiSilicon Limited
+ * Author: Qi Liu
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Define registers */
+#define HISI_PCIE_GLOBAL_CTRL  0x00
+#define HISI_PCIE_EVENT_CTRL   0x010
+#define HISI_PCIE_CNT  0x090
+#define HISI_PCIE_EXT_CNT  0x110
+#define HISI_PCIE_INT_STAT 0x150
+#define HISI_PCIE_INT_MASK 0x154
+#define HISI_PCIE_REG_BDF  0xf

[PATCH v3 1/2] docs: perf: Add description for HiSilicon PCIe PMU driver

2021-04-15 Thread Qi Liu
PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported on
HiSilicon HIP09 platform. Document it to provide guidance on how to
use it.

Signed-off-by: Qi Liu 
---
 Documentation/admin-guide/perf/hisi-pcie-pmu.rst | 104 +++
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst

diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst 
b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
new file mode 100644
index 000..2084b53
--- /dev/null
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
@@ -0,0 +1,104 @@
+
+HiSilicon PCIe Performance Monitoring Unit (PMU)
+
+
+HiSilicon PCIe Performance Monitoring Unit (PMU) is a PCIe Root Complex
+integrated End Point (RCiEP) device. On Hip09, each PCIe Core has a PMU RCiEP
+to monitor multi Root Ports and all Endpoints downstream these Root Ports.
+
+HiSilicon PCIe PMU is supported to collect performance data of PCIe bus, such
+as: bandwidth, latency etc.
+
+
+HiSilicon PCIe PMU driver
+=
+
+The PCIe PMU driver registers a perf PMU with the name of its sicl-id and PCIe
+Core id.::
+
+  /sys/bus/event_source/hisi_pcie_
+
+PMU driver provides description of available events and filter options in 
sysfs,
+see /sys/bus/event_source/devices/hisi_pcie_.
+
+The "format" directory describes all formats of the config (events) and config1
+(filter options) fields of the perf_event_attr structure. The "events" 
directory
+describes all documented events shown in perf list.
+
+The "identifier" sysfs file allows users to identify the version of the
+PMU hardware device.
+
+The "bus" sysfs file allows users to get the bus number of Root Ports
+monitored by PMU.
+
+Example usage of perf::
+
+  $# perf list
+  hisi_pcie0_0/bw_rx/ [kernel PMU event]
+  --
+
+  $# perf stat -e hisi_pcie0_0/bw_rx/ sleep 5
+
+The current driver does not support sampling. So "perf record" is unsupported.
+Also attach to a task is unsupported for PCIe PMU.
+
+Filter options
+--
+
+1. Target filter
+PMU could only monitor the performance of traffic downstream target Root Ports
+or downstream target Endpoint. PCIe PMU driver support "port" and "bdf"
+interfaces for users, and these two interfaces aren't supported at the same
+time.
+
+-port
+"port" filter can be used in all PCIe PMU events, target Root Port can be
+selected by configuring the 16-bits-bitmap "port". Multi ports can be selected
+for AP-layer-events, and only one port can be selected for TL/DL-layer-events.
+
+For example, if target Root Port is :00:00.0 (x8 lanes), bit0 of bitmap
+should be set, port=0x1; if target Root Port is :00:04.0 (x4 lanes),
+bit8 is set, port=0x100; if these two Root Ports are both monitored, 
port=0x101.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,port=0x1/ sleep 5
+
+-bdf
+
+"bdf" filter can only be used in bandwidth events, target Endpoint is selected
+by configuring BDF to "bdf". Counter only counts the bandwidth of message
+requested by target Endpoint.
+
+For example, "bdf=0x3900" means BDF of target Endpoint is :39:00.0.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,bdf=0x3900/ sleep 5
+
+2. Trigger filter
+Event statistics start when the first time TLP length is greater/smaller
+than trigger condition. You can set the trigger condition by writing 
"trig_len",
+and set the trigger mode by writing "trig_mode". This filter can only be used
+in bandwidth events.
+
+For example, "trig_len=4" means trigger condition is 2^4 DW, "trig_mode=0"
+means statistics start when TLP length > trigger condition, "trig_mode=1"
+means start when TLP length < condition.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,trig_len=0x4,trig_mode=1/ sleep 5
+
+3. Threshold filter
+Counter counts when TLP length within the specified range. You can set the
+threshold by writing "thr_len", and set the threshold mode by writing
+"thr_mode". This filter can only be used in bandwidth events.
+
+For example, "thr_len=4" means threshold is 2^4 DW, "thr_mode=0" means
+counter counts when TLP length >= threshold, and "thr_mode=1" means counts
+when TLP length < threshold.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,thr_len=0x4,thr_mode=1/ sleep 5
-- 
2.7.4



[PATCH v3 0/2] drivers/perf: hisi: Add support for PCIe PMU

2021-04-15 Thread Qi Liu
This patchset adds support for HiSilicon PCIe Performance Monitoring
Unit(PMU). It is a PCIe Root Complex integrated End Point(RCiEP) device
added on Hip09. Each PCIe Core has a PMU RCiEP to monitor multi root
ports and all Endpoints downstream these root ports.

HiSilicon PCIe PMU is supported to collect performance data of PCIe bus,
such as: bandwidth, latency etc.

This patchset is based on 5.12-rc6. 

Changes since v2:
- Address the comments from John.
- Link: 
https://lore.kernel.org/linux-arm-kernel/1617959157-22956-1-git-send-email-liuqi...@huawei.com/

Changes since v1:
- Drop the internal Reviewed-by tag.
- Fix some build warnings when W=1.
- Link: 
https://lore.kernel.org/linux-arm-kernel/1617788943-52722-1-git-send-email-liuqi...@huawei.com/

Qi Liu (2):
  docs: perf: Add description for HiSilicon PCIe PMU driver
  drivers/perf: hisi: Add driver for HiSilicon PCIe PMU

 Documentation/admin-guide/perf/hisi-pcie-pmu.rst |  104 +++
 MAINTAINERS  |6 +
 drivers/perf/Kconfig |2 +
 drivers/perf/Makefile|1 +
 drivers/perf/pci/Kconfig |   16 +
 drivers/perf/pci/Makefile|2 +
 drivers/perf/pci/hisilicon/Makefile  |3 +
 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c   | 1014 ++
 include/linux/cpuhotplug.h   |1 +
 9 files changed, 1149 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst
 create mode 100644 drivers/perf/pci/Kconfig
 create mode 100644 drivers/perf/pci/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c

-- 
2.7.4



[PATCH v2 1/2] drivers/perf: hisi: Add driver for HiSilicon PCIe PMU

2021-04-09 Thread Qi Liu
PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported
to sample bandwidth, latency, buffer occupation etc.

Each PMU RCiEP device monitors multiple Root Ports, and each RCiEP is
registered as a PMU in /sys/bus/event_source/devices, so users can
select target PMU, and use filter to do further sets.

Filtering options contains:
event- select the event.
subevent - select the subevent.
port - select target Root Ports. Information of Root Ports
   are shown under sysfs.
bdf  - select requester_id of target EP device.
trig_len - set trigger condition for starting event statistics.
trigger_mode - set trigger mode. 0 means starting to statistic when
   bigger than trigger condition, and 1 means smaller.
thr_len  - set threshold for statistics.
thr_mode - set threshold mode. 0 means count when bigger than
   threshold, and 1 means smaller.

Signed-off-by: Qi Liu 
---
 MAINTAINERS|6 +
 drivers/perf/Kconfig   |2 +
 drivers/perf/Makefile  |1 +
 drivers/perf/pci/Kconfig   |   16 +
 drivers/perf/pci/Makefile  |2 +
 drivers/perf/pci/hisilicon/Makefile|5 +
 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c | 1011 
 include/linux/cpuhotplug.h |1 +
 8 files changed, 1044 insertions(+)
 create mode 100644 drivers/perf/pci/Kconfig
 create mode 100644 drivers/perf/pci/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3353de0..46c7861 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8023,6 +8023,12 @@ W:   http://www.hisilicon.com
 F: Documentation/admin-guide/perf/hisi-pmu.rst
 F: drivers/perf/hisilicon
 
+HISILICON PCIE PMU DRIVER
+M: Qi Liu 
+S: Maintained
+F: Documentation/admin-guide/perf/hisi-pcie-pmu.rst
+F: drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
+
 HISILICON QM AND ZIP Controller DRIVER
 M: Zhou Wang 
 L: linux-cry...@vger.kernel.org
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 3075cf1..99d4760 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -139,4 +139,6 @@ config ARM_DMC620_PMU
 
 source "drivers/perf/hisilicon/Kconfig"
 
+source "drivers/perf/pci/Kconfig"
+
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 5260b11..1208c08 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
+obj-y += pci/
diff --git a/drivers/perf/pci/Kconfig b/drivers/perf/pci/Kconfig
new file mode 100644
index 000..a119486
--- /dev/null
+++ b/drivers/perf/pci/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# PCIe Performance Monitor Drivers
+#
+menu "PCIe Performance Monitor"
+
+config HISI_PCIE_PMU
+   tristate "HiSilicon PCIE PERF PMU"
+   depends on ARM64 && PCI && HISI_PMU
+   help
+ Provide support for HiSilicon PCIe performance monitoring unit (PMU)
+ RCiEP devices.
+ Adds the PCIe PMU into perf events system for monitoring latency,
+ bandwidth etc.
+
+endmenu
diff --git a/drivers/perf/pci/Makefile b/drivers/perf/pci/Makefile
new file mode 100644
index 000..a56b1a9
--- /dev/null
+++ b/drivers/perf/pci/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += hisilicon/
diff --git a/drivers/perf/pci/hisilicon/Makefile 
b/drivers/perf/pci/hisilicon/Makefile
new file mode 100644
index 000..6f99f52
--- /dev/null
+++ b/drivers/perf/pci/hisilicon/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+ccflags-y :=  -I $(srctree)/drivers/perf/hisilicon
+
+obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
diff --git a/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c 
b/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
new file mode 100644
index 000..ac0e444
--- /dev/null
+++ b/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
@@ -0,0 +1,1011 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This driver adds support for PCIe PMU RCiEP device. Related
+ * perf events are bandwidth, bandwidth utilization, latency
+ * etc.
+ *
+ * Copyright (C) 2021 HiSilicon Limited
+ * Author: Qi Liu
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hisi_uncore_pmu.h"
+
+/* Define registers */
+#define HISI_PCIE_GLOBAL_CTRL  0x00
+#define HISI_PCIE_EVENT_CTRL   0x010
+#define HISI_PCIE_CNT  0x090
+#define HISI_PCIE_EXT_CNT  0x110
+#define HISI_PCIE_INT_STAT   

[PATCH v2 2/2] docs: perf: Add description for HiSilicon PCIe PMU driver

2021-04-09 Thread Qi Liu
PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported on
HiSilicon HIP09 platform. Document it to provide guidance on how to
use it.

Signed-off-by: Qi Liu 
---

 Documentation/admin-guide/perf/hisi-pcie-pmu.rst | 104 +++
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst

diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst 
b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
new file mode 100644
index 000..2084b53
--- /dev/null
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
@@ -0,0 +1,104 @@
+
+HiSilicon PCIe Performance Monitoring Unit (PMU)
+
+
+HiSilicon PCIe Performance Monitoring Unit (PMU) is a PCIe Root Complex
+integrated End Point (RCiEP) device. On Hip09, each PCIe Core has a PMU RCiEP
+to monitor multi Root Ports and all Endpoints downstream these Root Ports.
+
+HiSilicon PCIe PMU is supported to collect performance data of PCIe bus, such
+as: bandwidth, latency etc.
+
+
+HiSilicon PCIe PMU driver
+=
+
+The PCIe PMU driver registers a perf PMU with the name of its sicl-id and PCIe
+Core id.::
+
+  /sys/bus/event_source/hisi_pcie_
+
+PMU driver provides description of available events and filter options in 
sysfs,
+see /sys/bus/event_source/devices/hisi_pcie_.
+
+The "format" directory describes all formats of the config (events) and config1
+(filter options) fields of the perf_event_attr structure. The "events" 
directory
+describes all documented events shown in perf list.
+
+The "identifier" sysfs file allows users to identify the version of the
+PMU hardware device.
+
+The "bus" sysfs file allows users to get the bus number of Root Ports
+monitored by PMU.
+
+Example usage of perf::
+
+  $# perf list
+  hisi_pcie0_0/bw_rx/ [kernel PMU event]
+  --
+
+  $# perf stat -e hisi_pcie0_0/bw_rx/ sleep 5
+
+The current driver does not support sampling. So "perf record" is unsupported.
+Also attach to a task is unsupported for PCIe PMU.
+
+Filter options
+--
+
+1. Target filter
+PMU could only monitor the performance of traffic downstream target Root Ports
+or downstream target Endpoint. PCIe PMU driver support "port" and "bdf"
+interfaces for users, and these two interfaces aren't supported at the same
+time.
+
+-port
+"port" filter can be used in all PCIe PMU events, target Root Port can be
+selected by configuring the 16-bits-bitmap "port". Multi ports can be selected
+for AP-layer-events, and only one port can be selected for TL/DL-layer-events.
+
+For example, if target Root Port is :00:00.0 (x8 lanes), bit0 of bitmap
+should be set, port=0x1; if target Root Port is :00:04.0 (x4 lanes),
+bit8 is set, port=0x100; if these two Root Ports are both monitored, 
port=0x101.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,port=0x1/ sleep 5
+
+-bdf
+
+"bdf" filter can only be used in bandwidth events, target Endpoint is selected
+by configuring BDF to "bdf". Counter only counts the bandwidth of message
+requested by target Endpoint.
+
+For example, "bdf=0x3900" means BDF of target Endpoint is :39:00.0.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,bdf=0x3900/ sleep 5
+
+2. Trigger filter
+Event statistics start when the first time TLP length is greater/smaller
+than trigger condition. You can set the trigger condition by writing 
"trig_len",
+and set the trigger mode by writing "trig_mode". This filter can only be used
+in bandwidth events.
+
+For example, "trig_len=4" means trigger condition is 2^4 DW, "trig_mode=0"
+means statistics start when TLP length > trigger condition, "trig_mode=1"
+means start when TLP length < condition.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,trig_len=0x4,trig_mode=1/ sleep 5
+
+3. Threshold filter
+Counter counts when TLP length within the specified range. You can set the
+threshold by writing "thr_len", and set the threshold mode by writing
+"thr_mode". This filter can only be used in bandwidth events.
+
+For example, "thr_len=4" means threshold is 2^4 DW, "thr_mode=0" means
+counter counts when TLP length >= threshold, and "thr_mode=1" means counts
+when TLP length < threshold.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,thr_len=0x4,thr_mode=1/ sleep 5
-- 
2.8.1



[PATCH v2 0/2] drivers/perf: hisi: Add support for PCIe PMU

2021-04-09 Thread Qi Liu
This patchset adds support for HiSilicon PCIe Performance Monitoring
Unit(PMU). It is a PCIe Root Complex integrated End Point(RCiEP) device
added on Hip09. Each PCIe Core has a PMU RCiEP to monitor multi root
ports and all Endpoints downstream these root ports.

HiSilicon PCIe PMU is supported to collect performance data of PCIe bus,
such as: bandwidth, latency etc.

Changes since v1:
- Drop the internal Reviewed-by tag.
- Fix some build warnings when W=1.

Qi Liu (2):
  drivers/perf: hisi: Add driver for HiSilicon PCIe PMU
  docs: perf: Add description for HiSilicon PCIe PMU driver

 Documentation/admin-guide/perf/hisi-pcie-pmu.rst |  104 +++
 MAINTAINERS  |6 +
 drivers/perf/Kconfig |2 +
 drivers/perf/Makefile|1 +
 drivers/perf/pci/Kconfig |   16 +
 drivers/perf/pci/Makefile|2 +
 drivers/perf/pci/hisilicon/Makefile  |5 +
 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c   | 1011 ++
 include/linux/cpuhotplug.h   |1 +
 9 files changed, 1148 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst
 create mode 100644 drivers/perf/pci/Kconfig
 create mode 100644 drivers/perf/pci/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c

-- 
2.8.1



[PATCH 0/2] drivers/perf: hisi: Add support for PCIe PMU

2021-04-07 Thread Qi Liu
This patchset adds support for HiSilicon PCIe Performance Monitoring
Unit(PMU). It is a PCIe Root Complex integrated End Point(RCiEP) device
added on Hip09. Each PCIe Core has a PMU RCiEP to monitor multi root
ports and all Endpoints downstream these root ports.

HiSilicon PCIe PMU is supported to collect performance data of PCIe bus,
such as: bandwidth, latency etc.

Qi Liu (2):
  drivers/perf: hisi: Add driver for HiSilicon PCIe PMU
  docs: perf: Add description for HiSilicon PCIe PMU driver

 Documentation/admin-guide/perf/hisi-pcie-pmu.rst |  103 +++
 MAINTAINERS  |6 +
 drivers/perf/Kconfig |2 +
 drivers/perf/Makefile|1 +
 drivers/perf/pci/Kconfig |   16 +
 drivers/perf/pci/Makefile|2 +
 drivers/perf/pci/hisilicon/Makefile  |5 +
 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c   | 1012 ++
 include/linux/cpuhotplug.h   |1 +
 9 files changed, 1148 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst
 create mode 100644 drivers/perf/pci/Kconfig
 create mode 100644 drivers/perf/pci/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c

-- 
2.8.1



[PATCH 1/2] drivers/perf: hisi: Add driver for HiSilicon PCIe PMU

2021-04-07 Thread Qi Liu
PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported
to sample bandwidth, latency, buffer occupation etc.

Each PMU RCiEP device monitors multiple root ports, and each RCiEP is
registered as a pmu in /sys/bus/event_source/devices, so users can
select target PMU, and use filter to do further sets.

Filtering options contains:
event- select the event.
subevent - select the subevent.
port - select target root ports. Information of root ports
   are shown under sysfs.
bdf   - select requester_id of target EP device.
trig_len - set trigger condition for starting event statistics.
trigger_mode - set trigger mode. 0 means starting to statistic when
   bigger than trigger condition, and 1 means smaller.
thr_len  - set threshold for statistics.
thr_mode - set threshold mode. 0 means count when bigger than
   threshold, and 1 means smaller.

Reviewed-by: Jonathan Cameron 
Signed-off-by: Qi Liu 
---
 MAINTAINERS|6 +
 drivers/perf/Kconfig   |2 +
 drivers/perf/Makefile  |1 +
 drivers/perf/pci/Kconfig   |   16 +
 drivers/perf/pci/Makefile  |2 +
 drivers/perf/pci/hisilicon/Makefile|5 +
 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c | 1012 
 include/linux/cpuhotplug.h |1 +
 8 files changed, 1045 insertions(+)
 create mode 100644 drivers/perf/pci/Kconfig
 create mode 100644 drivers/perf/pci/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/Makefile
 create mode 100644 drivers/perf/pci/hisilicon/hisi_pcie_pmu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3353de0..46c7861 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8023,6 +8023,12 @@ W:   http://www.hisilicon.com
 F: Documentation/admin-guide/perf/hisi-pmu.rst
 F: drivers/perf/hisilicon
 
+HISILICON PCIE PMU DRIVER
+M: Qi Liu 
+S: Maintained
+F: Documentation/admin-guide/perf/hisi-pcie-pmu.rst
+F: drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
+
 HISILICON QM AND ZIP Controller DRIVER
 M: Zhou Wang 
 L: linux-cry...@vger.kernel.org
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 3075cf1..99d4760 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -139,4 +139,6 @@ config ARM_DMC620_PMU
 
 source "drivers/perf/hisilicon/Kconfig"
 
+source "drivers/perf/pci/Kconfig"
+
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 5260b11..1208c08 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
+obj-y += pci/
diff --git a/drivers/perf/pci/Kconfig b/drivers/perf/pci/Kconfig
new file mode 100644
index 000..a119486
--- /dev/null
+++ b/drivers/perf/pci/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# PCIe Performance Monitor Drivers
+#
+menu "PCIe Performance Monitor"
+
+config HISI_PCIE_PMU
+   tristate "HiSilicon PCIE PERF PMU"
+   depends on ARM64 && PCI && HISI_PMU
+   help
+ Provide support for HiSilicon PCIe performance monitoring unit (PMU)
+ RCiEP devices.
+ Adds the PCIe PMU into perf events system for monitoring latency,
+ bandwidth etc.
+
+endmenu
diff --git a/drivers/perf/pci/Makefile b/drivers/perf/pci/Makefile
new file mode 100644
index 000..a56b1a9
--- /dev/null
+++ b/drivers/perf/pci/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += hisilicon/
diff --git a/drivers/perf/pci/hisilicon/Makefile 
b/drivers/perf/pci/hisilicon/Makefile
new file mode 100644
index 000..6f99f52
--- /dev/null
+++ b/drivers/perf/pci/hisilicon/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+ccflags-y :=  -I $(srctree)/drivers/perf/hisilicon
+
+obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
diff --git a/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c 
b/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
new file mode 100644
index 000..9f9bd9d
--- /dev/null
+++ b/drivers/perf/pci/hisilicon/hisi_pcie_pmu.c
@@ -0,0 +1,1012 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This driver adds support for PCIe PMU RCiEP device. Related
+ * perf events are bandwidth, bandwidth utilization, latency
+ * etc.
+ *
+ * Copyright (C) 2021 HiSilicon Limited
+ * Author: Qi Liu
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hisi_uncore_pmu.h"
+
+/* define registers */
+#define HISI_PCIE_GLOBAL_CTRL  0x00
+#define HISI_PCIE_EVENT_CTRL   0x010
+#define HISI_PCIE_CNT  0x090
+#define HISI_PCIE_EXT_CNT

[PATCH 2/2] docs: perf: Add description for HiSilicon PCIe PMU driver

2021-04-07 Thread Qi Liu
PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported on
HiSilicon HIP09 platform, and document it to provide guidance on how to
use it.

Reviewed-by: John Garry 
Signed-off-by: Qi Liu 
---
 Documentation/admin-guide/perf/hisi-pcie-pmu.rst | 103 +++
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst

diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst 
b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
new file mode 100644
index 000..8942498
--- /dev/null
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
@@ -0,0 +1,103 @@
+
+HiSilicon PCIe Performance Monitoring Unit (PMU)
+
+
+HiSilicon PCIe Performance Monitoring Unit (PMU) is a PCIe Root Complex
+integrated End Point(RCiEP) device. On Hip09, each PCIe Core has a PMU RCiEP
+to monitor multi root ports and all Endpoints downstream these root ports.
+
+HiSilicon PCIe PMU is supported to collect performance data of PCIe bus, such
+as: bandwidth, latency etc.
+
+
+HiSilicon PCIe PMU driver
+=
+
+The PCIe PMU driver registers a perf PMU with the name of its sicl-id and PCIe
+core id.::
+
+  /sys/bus/event_source/hisi_pcie_
+
+PMU driver provides description of available events and filter options in 
sysfs,
+see /sys/bus/event_source/devices/hisi_pcie_.
+
+The "format" directory describes all formats of the config (events) and config1
+(filter options) fields of the perf_event_attr structure. The "events" 
directory
+describes all documented events shown in perf list.
+
+The "identifier" sysfs file allows users to identify the version of the
+PMU hardware device.
+
+The "bus" sysfs file allows users to get the bus number of root ports
+monitored by PMU.
+
+Example usage of perf::
+
+  $# perf list
+  hisi_pcie0_0/bw_rx/ [kernel PMU event]
+  --
+
+  $# perf stat -e hisi_pcie0_0/bw_rx/ sleep 5
+
+The current driver does not support sampling. So "perf record" is unsupported.
+Also attach to a task is unsupported for PCIe PMU.
+
+Filter options
+--
+
+1. Target filter
+PMU could only monitor the performance of traffic downstream target root ports
+or traffic of target Endpoint. PCIe PMU driver support "port" and "bdf"
+interfaces for users, and this two interfaces isn't supported at the same time.
+
+-port
+"port" filter can be used in all PCIe PMU events, target root port can be
+selected by configure the bitmap "port". Multi ports can be selected for
+AP-layer-events, and only one port can be selected for TL/DL-layer-events.
+
+For example, if target root port is :00:00.0(x8 lanes), bit0 should be
+selected, port=0x1; if target root port is :00:04.0(x4 lanes), bit8 is set,
+port=0x100; if these two root port are both monitored, port=0x101.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,port=0x1/ sleep 5
+
+-bdf
+
+"bdf" filter can only be used in bandwidth events, target Endpoint is selected
+by configure BDF to "bdf". Counter only counts the bandwidth of message
+requested by target Endpoint.
+
+For example, "bdf=0x3900" means BDF of target Endpoint is :39:00.0.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,bdf=0x3900/ sleep 5
+
+2. Trigger filter
+event statistics start when the first time TLP length is greater/smaller
+than trigger condition. You can set the trigger condition by write
+"trig_len", and set the trigger mode by write "trig_mode". This filter can only
+be used in bandwidth events.
+
+For example, "trig_len=4" means trigger condition is 2^4 DW, "trig_mode=0"
+means statistics start when TLP length > trigger condition, "trig_mode=1"
+means start When TLP length < condition.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,trig_len=0x4,trig_mode=1/ sleep 5
+
+3. Threshold filter
+counter counts when TLP length within the specified range. You can set the
+threshold by write "thr_len", and set the threshold mode by write "thr_mode".
+This filter can only be used in bandwidth events.
+
+For example, "thr_len=4" means threshold is 2^4 DW, "thr_mode=0" means
+statistics when TLP length >= threshold, and "thr_mode=1" means statistics
+when TLP length < threshold.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_0/bw_rx,thr_len=0x4,thr_mode=1/ sleep 5
-- 
2.8.1



[PATCH] iommu: Remove duplicate check of pasids

2021-04-01 Thread Qi Liu
Remove duplicate check of pasids in amd_iommu_domain_enable_v2(), as it
has been guaranteed in amd_iommu_init_device().

Signed-off-by: Qi Liu 
---
 drivers/iommu/amd/iommu.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 107316e..7ca9f2f 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2310,9 +2310,6 @@ int amd_iommu_domain_enable_v2(struct iommu_domain *dom, 
int pasids)
unsigned long flags;
int levels, ret;
 
-   if (pasids <= 0 || pasids > (PASID_MASK + 1))
-   return -EINVAL;
-
/* Number of GCR3 table levels required */
for (levels = 0; (pasids - 1) & ~0x1ff; pasids >>= 9)
levels += 1;
-- 
2.8.1



[PATCH] arm64: perf: Remove redundant initialization in perf_event.c

2021-04-01 Thread Qi Liu
The initialization of value in function armv8pmu_read_hw_counter()
and armv8pmu_read_counter() seem redundant, as they are soon updated.
So, We can remove them.

Signed-off-by: Qi Liu 
---
 arch/arm64/kernel/perf_event.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 4658fcf..f594957 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -470,9 +470,8 @@ static inline u64 armv8pmu_read_evcntr(int idx)
 static inline u64 armv8pmu_read_hw_counter(struct perf_event *event)
 {
int idx = event->hw.idx;
-   u64 val = 0;
+   u64 val = armv8pmu_read_evcntr(idx);
 
-   val = armv8pmu_read_evcntr(idx);
if (armv8pmu_event_is_chained(event))
val = (val << 32) | armv8pmu_read_evcntr(idx - 1);
return val;
@@ -520,7 +519,7 @@ static u64 armv8pmu_read_counter(struct perf_event *event)
 {
struct hw_perf_event *hwc = >hw;
int idx = hwc->idx;
-   u64 value = 0;
+   u64 value;
 
if (idx == ARMV8_IDX_CYCLE_COUNTER)
value = read_sysreg(pmccntr_el0);
-- 
2.8.1



[PATCH] docs: perf: Address some html build warnings

2021-03-29 Thread Qi Liu
Fix following html build warnings:
Documentation/admin-guide/perf/hisi-pmu.rst:61: WARNING: Unexpected indentation.
Documentation/admin-guide/perf/hisi-pmu.rst:62: WARNING: Block quote ends 
without a blank line; unexpected unindent.
Documentation/admin-guide/perf/hisi-pmu.rst:69: WARNING: Unexpected indentation.
Documentation/admin-guide/perf/hisi-pmu.rst:70: WARNING: Block quote ends 
without a blank line; unexpected unindent.
Documentation/admin-guide/perf/hisi-pmu.rst:83: WARNING: Unexpected indentation.

Fixes: 9b86b1b41e0f ("docs: perf: Add new description on HiSilicon uncore PMU 
v2")
Reported-by: Stephen Rothwell 
Signed-off-by: Qi Liu 
---
 Documentation/admin-guide/perf/hisi-pmu.rst | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst 
b/Documentation/admin-guide/perf/hisi-pmu.rst
index 3b3120e..5469793 100644
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
@@ -57,16 +57,20 @@ For HiSilicon uncore PMU v2 whose identifier is 0x30, the 
topology is the same
 as PMU v1, but some new functions are added to the hardware.
 
 (a) L3C PMU supports filtering by core/thread within the cluster which can be
-specified as a bitmap.
+specified as a bitmap::
+
   $# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_core=0x3/ sleep 5
+
 This will only count the operations from core/thread 0 and 1 in this cluster.
 
 (b) Tracetag allow the user to chose to count only read, write or atomic
 operations via the tt_req parameeter in perf. The default value counts all
 operations. tt_req is 3bits, 3'b100 represents read operations, 3'b101
 represents write operations, 3'b110 represents atomic store operations and
-3'b111 represents atomic non-store operations, other values are reserved.
+3'b111 represents atomic non-store operations, other values are reserved::
+
   $# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_req=0x4/ sleep 5
+
 This will only count the read operations in this cluster.
 
 (c) Datasrc allows the user to check where the data comes from. It is 5 bits.
@@ -79,7 +83,8 @@ Some important codes are as follows:
 5'b1: comes from cross-socket DDR;
 etc, it is mainly helpful to find that the data source is nearest from the CPU
 cores. If datasrc_cfg is used in the multi-chips, the datasrc_skt shall be
-configured in perf command.
+configured in perf command::
+
   $# perf stat -a -e hisi_sccl3_l3c0/config=0xb9,datasrc_cfg=0xE/,
   hisi_sccl3_l3c0/config=0xb9,datasrc_cfg=0xF/ sleep 5
 
-- 
2.8.1



[PATCH v2] coresight: core: Fix typo in coresight-core.c

2021-03-23 Thread Qi Liu
Fix the following checkpatch warning:
WARNING: 'compoment' may be misspelled - perhaps 'component'?

Fixes: 8e264c52e1da  ("coresight: core: Allow the coresight core driver to be 
built as a module")
Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c 
b/drivers/hwtracing/coresight/coresight-core.c
index 0062c89..b57bea1 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -86,7 +86,7 @@ static int coresight_id_match(struct device *dev, void *data)
i_csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
return 0;
 
-   /* Get the source ID for both compoment */
+   /* Get the source ID for both components */
trace_id = source_ops(csdev)->trace_id(csdev);
i_trace_id = source_ops(i_csdev)->trace_id(i_csdev);
 
-- 
2.8.1



[PATCH] coresight: core: Fix typo in coresight-core.c

2021-03-22 Thread Qi Liu
Fix up one typo: compoment->component.

Fixes: 8e264c52e1da  ("coresight: core: Allow the coresight core driver to be 
built as a module")
Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c 
b/drivers/hwtracing/coresight/coresight-core.c
index 0062c89..bc397a7 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -86,7 +86,7 @@ static int coresight_id_match(struct device *dev, void *data)
i_csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
return 0;

-   /* Get the source ID for both compoment */
+   /* Get the source ID for both component */
trace_id = source_ops(csdev)->trace_id(csdev);
i_trace_id = source_ops(i_csdev)->trace_id(i_csdev);

--
2.8.1



[PATCH v2 1/3] drivers/perf: convert sysfs snprintf family to sysfs_emit

2021-03-19 Thread Qi Liu
From: Zihao Tang 

Fix the following coccicheck warning:

./drivers/perf/hisilicon/hisi_uncore_pmu.c:128:8-16: WARNING: use scnprintf or 
sprintf.
./drivers/perf/fsl_imx8_ddr_perf.c:173:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_spe_pmu.c:129:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_smmu_pmu.c:563:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_dsu_pmu.c:149:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_dsu_pmu.c:139:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cmn.c:563:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cmn.c:351:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-ccn.c:224:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:708:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:699:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:528:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:309:8-16: WARNING: use scnprintf or sprintf.

Signed-off-by: Zihao Tang 
Signed-off-by: Qi Liu 
---
 drivers/perf/arm-cci.c   | 12 ++--
 drivers/perf/arm-ccn.c   |  4 ++--
 drivers/perf/arm-cmn.c   | 22 +++---
 drivers/perf/arm_dsu_pmu.c   |  5 ++---
 drivers/perf/arm_smmuv3_pmu.c|  2 +-
 drivers/perf/arm_spe_pmu.c   |  3 +--
 drivers/perf/fsl_imx8_ddr_perf.c |  3 +--
 drivers/perf/hisilicon/hisi_uncore_pmu.c |  2 +-
 8 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index f81e2ec..666d8a9 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -306,7 +306,7 @@ static ssize_t cci400_pmu_cycle_event_show(struct device 
*dev,
 {
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
-   return snprintf(buf, PAGE_SIZE, "config=0x%lx\n", (unsigned 
long)eattr->var);
+   return sysfs_emit(buf, "config=0x%lx\n", (unsigned long)eattr->var);
 }
 
 static int cci400_get_event_idx(struct cci_pmu *cci_pmu,
@@ -525,8 +525,8 @@ static ssize_t cci5xx_pmu_global_event_show(struct device 
*dev,
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
/* Global events have single fixed source code */
-   return snprintf(buf, PAGE_SIZE, "event=0x%lx,source=0x%x\n",
-   (unsigned long)eattr->var, CCI5xx_PORT_GLOBAL);
+   return sysfs_emit(buf, "event=0x%lx,source=0x%x\n",
+ (unsigned long)eattr->var, CCI5xx_PORT_GLOBAL);
 }
 
 /*
@@ -696,7 +696,7 @@ static ssize_t cci_pmu_format_show(struct device *dev,
 {
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
-   return snprintf(buf, PAGE_SIZE, "%s\n", (char *)eattr->var);
+   return sysfs_emit(buf, "%s\n", (char *)eattr->var);
 }
 
 static ssize_t cci_pmu_event_show(struct device *dev,
@@ -705,8 +705,8 @@ static ssize_t cci_pmu_event_show(struct device *dev,
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
/* source parameter is mandatory for normal PMU events */
-   return snprintf(buf, PAGE_SIZE, "source=?,event=0x%lx\n",
-(unsigned long)eattr->var);
+   return sysfs_emit(buf, "source=?,event=0x%lx\n",
+ (unsigned long)eattr->var);
 }
 
 static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index a0a71c1..3a2ddc0 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -221,7 +221,7 @@ static ssize_t arm_ccn_pmu_format_show(struct device *dev,
struct dev_ext_attribute *ea = container_of(attr,
struct dev_ext_attribute, attr);
 
-   return snprintf(buf, PAGE_SIZE, "%s\n", (char *)ea->var);
+   return sysfs_emit(buf, "%s\n", (char *)ea->var);
 }
 
 #define CCN_FORMAT_ATTR(_name, _config) \
@@ -476,7 +476,7 @@ static ssize_t arm_ccn_pmu_cmp_mask_show(struct device *dev,
struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
u64 *mask = arm_ccn_pmu_get_cmp_mask(ccn, attr->attr.name);
 
-   return mask ? snprintf(buf, PAGE_SIZE, "0x%016llx\n", *mask) : -EINVAL;
+   return mask ? sysfs_emit(buf, "0x%016llx\n", *mask) : -EINVAL;
 }
 
 static ssize_t arm_ccn_pmu_cmp_mask_store(struct device *dev,
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 1328159f..56a5c35 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -348,19 +348,19 @@ static ssize_t arm_cmn_e

[PATCH v2 0/3] drivers/perf: convert sysfs sprintf/snprintf/scnprintf to sysfs_emit

2021-03-19 Thread Qi Liu
Use the generic sysfs_emit() and sysfs_emit_at() function to take
place of sprintf/snprintf/scnprintf, to avoid buffer overrun.

Qi Liu (2):
  drivers/perf: convert sysfs scnprintf family to sysfs_emit_at() and 
sysfs_emit()
  drivers/perf: convert sysfs sprintf family to sysfs_emit

Zihao Tang (1):
  drivers/perf: convert sysfs snprintf family to sysfs_emit

 drivers/perf/arm-cci.c   | 12 ++--
 drivers/perf/arm-ccn.c   | 31 +--
 drivers/perf/arm-cmn.c   | 22 +++---
 drivers/perf/arm_dmc620_pmu.c|  2 +-
 drivers/perf/arm_dsu_pmu.c   |  5 ++---
 drivers/perf/arm_smmuv3_pmu.c|  4 ++--
 drivers/perf/arm_spe_pmu.c   |  3 +--
 drivers/perf/fsl_imx8_ddr_perf.c |  7 +++
 drivers/perf/hisilicon/hisi_uncore_pmu.c |  8 
 drivers/perf/qcom_l2_pmu.c   |  2 +-
 drivers/perf/qcom_l3_pmu.c   |  4 ++--
 drivers/perf/thunderx2_pmu.c |  4 ++--
 drivers/perf/xgene_pmu.c |  4 ++--
 13 files changed, 50 insertions(+), 58 deletions(-)

-- 
2.8.1



[PATCH v2 2/3] drivers/perf: convert sysfs scnprintf family to sysfs_emit_at() and sysfs_emit()

2021-03-19 Thread Qi Liu
Use the generic sysfs_emit_at() and sysfs_emit() function to take place
of scnprintf()

Signed-off-by: Qi Liu 
---
 drivers/perf/arm-ccn.c | 27 +++
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 3a2ddc0..96d47cb 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -326,43 +326,38 @@ static ssize_t arm_ccn_pmu_event_show(struct device *dev,
struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
struct arm_ccn_pmu_event *event = container_of(attr,
struct arm_ccn_pmu_event, attr);
-   ssize_t res;
+   int res;
 
-   res = scnprintf(buf, PAGE_SIZE, "type=0x%x", event->type);
+   res = sysfs_emit(buf, "type=0x%x", event->type);
if (event->event)
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",event=0x%x",
-   event->event);
+   res += sysfs_emit_at(buf, res, ",event=0x%x", event->event);
if (event->def)
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",%s",
-   event->def);
+   res += sysfs_emit_at(buf, res, ",%s", event->def);
if (event->mask)
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",mask=0x%x",
-   event->mask);
+   res += sysfs_emit_at(buf, res, ",mask=0x%x", event->mask);
 
/* Arguments required by an event */
switch (event->type) {
case CCN_TYPE_CYCLES:
break;
case CCN_TYPE_XP:
-   res += scnprintf(buf + res, PAGE_SIZE - res,
-   ",xp=?,vc=?");
+   res += sysfs_emit_at(buf, res, ",xp=?,vc=?");
if (event->event == CCN_EVENT_WATCHPOINT)
-   res += scnprintf(buf + res, PAGE_SIZE - res,
+   res += sysfs_emit_at(buf, res,
",port=?,dir=?,cmp_l=?,cmp_h=?,mask=?");
else
-   res += scnprintf(buf + res, PAGE_SIZE - res,
-   ",bus=?");
+   res += sysfs_emit_at(buf, res, ",bus=?");
 
break;
case CCN_TYPE_MN:
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",node=%d", 
ccn->mn_id);
+   res += sysfs_emit_at(buf, res, ",node=%d", ccn->mn_id);
break;
default:
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",node=?");
+   res += sysfs_emit_at(buf, res, ",node=?");
break;
}
 
-   res += scnprintf(buf + res, PAGE_SIZE - res, "\n");
+   res += sysfs_emit_at(buf, res, "\n");
 
return res;
 }
-- 
2.8.1



[PATCH v2 3/3] drivers/perf: convert sysfs sprintf family to sysfs_emit

2021-03-19 Thread Qi Liu
sprintf does not know the PAGE_SIZE maximum of the temporary buffer
used for sysfs content and it's possible to overrun the buffer length.

Use sysfs_emit() function to ensures that no overrun is done.

Signed-off-by: Qi Liu 
---
 drivers/perf/arm_dmc620_pmu.c| 2 +-
 drivers/perf/arm_smmuv3_pmu.c| 2 +-
 drivers/perf/fsl_imx8_ddr_perf.c | 4 ++--
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 6 +++---
 drivers/perf/qcom_l2_pmu.c   | 2 +-
 drivers/perf/qcom_l3_pmu.c   | 4 ++--
 drivers/perf/thunderx2_pmu.c | 4 ++--
 drivers/perf/xgene_pmu.c | 4 ++--
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
index 66ad5b3..8e9002a 100644
--- a/drivers/perf/arm_dmc620_pmu.c
+++ b/drivers/perf/arm_dmc620_pmu.c
@@ -113,7 +113,7 @@ dmc620_pmu_event_show(struct device *dev,
 
eattr = container_of(attr, typeof(*eattr), attr);
 
-   return sprintf(page, "event=0x%x,clkdiv2=0x%x\n", eattr->eventid, 
eattr->clkdiv2);
+   return sysfs_emit(page, "event=0x%x,clkdiv2=0x%x\n", eattr->eventid, 
eattr->clkdiv2);
 }
 
 #define DMC620_PMU_EVENT_ATTR(_name, _eventid, _clkdiv2)   \
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index fa9dfbc..45a399f 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -506,7 +506,7 @@ static ssize_t smmu_pmu_event_show(struct device *dev,
 
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
 
-   return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+   return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
 }
 
 #define SMMU_EVENT_ATTR(name, config) \
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index c126fd8..2bbb931 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -110,7 +110,7 @@ static ssize_t ddr_perf_identifier_show(struct device *dev,
 {
struct ddr_pmu *pmu = dev_get_drvdata(dev);
 
-   return sprintf(page, "%s\n", pmu->devtype_data->identifier);
+   return sysfs_emit(page, "%s\n", pmu->devtype_data->identifier);
 }
 
 static umode_t ddr_perf_identifier_attr_visible(struct kobject *kobj,
@@ -219,7 +219,7 @@ ddr_pmu_event_show(struct device *dev, struct 
device_attribute *attr,
struct perf_pmu_events_attr *pmu_attr;
 
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
-   return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+   return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
 }
 
 #define IMX8_DDR_PMU_EVENT_ATTR(_name, _id)\
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 64ccf5e..5e2b5e1 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -33,7 +33,7 @@ ssize_t hisi_format_sysfs_show(struct device *dev,
 
eattr = container_of(attr, struct dev_ext_attribute, attr);
 
-   return sprintf(buf, "%s\n", (char *)eattr->var);
+   return sysfs_emit(buf, "%s\n", (char *)eattr->var);
 }
 EXPORT_SYMBOL_GPL(hisi_format_sysfs_show);
 
@@ -47,7 +47,7 @@ ssize_t hisi_event_sysfs_show(struct device *dev,
 
eattr = container_of(attr, struct dev_ext_attribute, attr);
 
-   return sprintf(page, "config=0x%lx\n", (unsigned long)eattr->var);
+   return sysfs_emit(page, "config=0x%lx\n", (unsigned long)eattr->var);
 }
 EXPORT_SYMBOL_GPL(hisi_event_sysfs_show);
 
@@ -59,7 +59,7 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
 {
struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
 
-   return sprintf(buf, "%d\n", hisi_pmu->on_cpu);
+   return sysfs_emit(buf, "%d\n", hisi_pmu->on_cpu);
 }
 EXPORT_SYMBOL_GPL(hisi_cpumask_sysfs_show);
 
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 8883af9..fc54a80 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -676,7 +676,7 @@ static ssize_t l2cache_pmu_event_show(struct device *dev,
struct perf_pmu_events_attr *pmu_attr;
 
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
-   return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+   return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
 }
 
 #define L2CACHE_EVENT_ATTR(_name, _id)  \
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
index fb34b87..bba0780 100644
--- a/drivers/perf/qcom_l3_pmu.c
+++ b/drivers/perf/qcom_l3_pmu.c
@@ -615,7 +615,7 @@ static ssize_t l3cache_pmu_format_show(struct device *dev,
struct dev_ext_

[PATCH 3/3] drivers/perf: convert sysfs sprintf family to sysfs_emit

2021-03-17 Thread Qi Liu
sprintf does not know the PAGE_SIZE maximum of the temporary buffer
used for sysfs content and it's possible to overrun the buffer length.

Use sysfs_emit() function to ensures that no overrun is done.

Signed-off-by: Qi Liu 
---
 drivers/perf/arm_dmc620_pmu.c| 2 +-
 drivers/perf/arm_smmuv3_pmu.c| 2 +-
 drivers/perf/fsl_imx8_ddr_perf.c | 4 ++--
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 6 +++---
 drivers/perf/qcom_l2_pmu.c   | 2 +-
 drivers/perf/qcom_l3_pmu.c   | 4 ++--
 drivers/perf/thunderx2_pmu.c | 4 ++--
 drivers/perf/xgene_pmu.c | 4 ++--
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
index 66ad5b3..8e9002a 100644
--- a/drivers/perf/arm_dmc620_pmu.c
+++ b/drivers/perf/arm_dmc620_pmu.c
@@ -113,7 +113,7 @@ dmc620_pmu_event_show(struct device *dev,
 
eattr = container_of(attr, typeof(*eattr), attr);
 
-   return sprintf(page, "event=0x%x,clkdiv2=0x%x\n", eattr->eventid, 
eattr->clkdiv2);
+   return sysfs_emit(page, "event=0x%x,clkdiv2=0x%x\n", eattr->eventid, 
eattr->clkdiv2);
 }
 
 #define DMC620_PMU_EVENT_ATTR(_name, _eventid, _clkdiv2)   \
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index fa9dfbc..45a399f 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -506,7 +506,7 @@ static ssize_t smmu_pmu_event_show(struct device *dev,
 
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
 
-   return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+   return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
 }
 
 #define SMMU_EVENT_ATTR(name, config) \
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index c126fd8..2bbb931 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -110,7 +110,7 @@ static ssize_t ddr_perf_identifier_show(struct device *dev,
 {
struct ddr_pmu *pmu = dev_get_drvdata(dev);
 
-   return sprintf(page, "%s\n", pmu->devtype_data->identifier);
+   return sysfs_emit(page, "%s\n", pmu->devtype_data->identifier);
 }
 
 static umode_t ddr_perf_identifier_attr_visible(struct kobject *kobj,
@@ -219,7 +219,7 @@ ddr_pmu_event_show(struct device *dev, struct 
device_attribute *attr,
struct perf_pmu_events_attr *pmu_attr;
 
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
-   return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+   return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
 }
 
 #define IMX8_DDR_PMU_EVENT_ATTR(_name, _id)\
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 64ccf5e..5e2b5e1 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -33,7 +33,7 @@ ssize_t hisi_format_sysfs_show(struct device *dev,
 
eattr = container_of(attr, struct dev_ext_attribute, attr);
 
-   return sprintf(buf, "%s\n", (char *)eattr->var);
+   return sysfs_emit(buf, "%s\n", (char *)eattr->var);
 }
 EXPORT_SYMBOL_GPL(hisi_format_sysfs_show);
 
@@ -47,7 +47,7 @@ ssize_t hisi_event_sysfs_show(struct device *dev,
 
eattr = container_of(attr, struct dev_ext_attribute, attr);
 
-   return sprintf(page, "config=0x%lx\n", (unsigned long)eattr->var);
+   return sysfs_emit(page, "config=0x%lx\n", (unsigned long)eattr->var);
 }
 EXPORT_SYMBOL_GPL(hisi_event_sysfs_show);
 
@@ -59,7 +59,7 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
 {
struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
 
-   return sprintf(buf, "%d\n", hisi_pmu->on_cpu);
+   return sysfs_emit(buf, "%d\n", hisi_pmu->on_cpu);
 }
 EXPORT_SYMBOL_GPL(hisi_cpumask_sysfs_show);
 
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 8883af9..fc54a80 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -676,7 +676,7 @@ static ssize_t l2cache_pmu_event_show(struct device *dev,
struct perf_pmu_events_attr *pmu_attr;
 
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
-   return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+   return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
 }
 
 #define L2CACHE_EVENT_ATTR(_name, _id)  \
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
index fb34b87..bba0780 100644
--- a/drivers/perf/qcom_l3_pmu.c
+++ b/drivers/perf/qcom_l3_pmu.c
@@ -615,7 +615,7 @@ static ssize_t l3cache_pmu_format_show(struct device *dev,
struct dev_ext_

[PATCH 1/3] drivers/perf: convert sysfs snprintf family to sysfs_emit

2021-03-17 Thread Qi Liu
From: Zihao Tang 

Fix the following coccicheck warning:

./drivers/perf/hisilicon/hisi_uncore_pmu.c:128:8-16: WARNING: use scnprintf or 
sprintf.
./drivers/perf/fsl_imx8_ddr_perf.c:173:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_spe_pmu.c:129:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_smmu_pmu.c:563:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_dsu_pmu.c:149:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm_dsu_pmu.c:139:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cmn.c:563:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cmn.c:351:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-ccn.c:224:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:708:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:699:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:528:8-16: WARNING: use scnprintf or sprintf.
./drivers/perf/arm-cci.c:309:8-16: WARNING: use scnprintf or sprintf.

Signed-off-by: Zihao Tang 
Signed-off-by: Qi Liu 
---
 drivers/perf/arm-cci.c   | 12 ++--
 drivers/perf/arm-ccn.c   |  4 ++--
 drivers/perf/arm-cmn.c   | 22 +++---
 drivers/perf/arm_dsu_pmu.c   |  5 ++---
 drivers/perf/arm_smmuv3_pmu.c|  2 +-
 drivers/perf/arm_spe_pmu.c   |  3 +--
 drivers/perf/fsl_imx8_ddr_perf.c |  3 +--
 drivers/perf/hisilicon/hisi_uncore_pmu.c |  2 +-
 8 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index f81e2ec..666d8a9 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -306,7 +306,7 @@ static ssize_t cci400_pmu_cycle_event_show(struct device 
*dev,
 {
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
-   return snprintf(buf, PAGE_SIZE, "config=0x%lx\n", (unsigned 
long)eattr->var);
+   return sysfs_emit(buf, "config=0x%lx\n", (unsigned long)eattr->var);
 }
 
 static int cci400_get_event_idx(struct cci_pmu *cci_pmu,
@@ -525,8 +525,8 @@ static ssize_t cci5xx_pmu_global_event_show(struct device 
*dev,
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
/* Global events have single fixed source code */
-   return snprintf(buf, PAGE_SIZE, "event=0x%lx,source=0x%x\n",
-   (unsigned long)eattr->var, CCI5xx_PORT_GLOBAL);
+   return sysfs_emit(buf, "event=0x%lx,source=0x%x\n",
+ (unsigned long)eattr->var, CCI5xx_PORT_GLOBAL);
 }
 
 /*
@@ -696,7 +696,7 @@ static ssize_t cci_pmu_format_show(struct device *dev,
 {
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
-   return snprintf(buf, PAGE_SIZE, "%s\n", (char *)eattr->var);
+   return sysfs_emit(buf, "%s\n", (char *)eattr->var);
 }
 
 static ssize_t cci_pmu_event_show(struct device *dev,
@@ -705,8 +705,8 @@ static ssize_t cci_pmu_event_show(struct device *dev,
struct dev_ext_attribute *eattr = container_of(attr,
struct dev_ext_attribute, attr);
/* source parameter is mandatory for normal PMU events */
-   return snprintf(buf, PAGE_SIZE, "source=?,event=0x%lx\n",
-(unsigned long)eattr->var);
+   return sysfs_emit(buf, "source=?,event=0x%lx\n",
+ (unsigned long)eattr->var);
 }
 
 static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index a0a71c1..3a2ddc0 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -221,7 +221,7 @@ static ssize_t arm_ccn_pmu_format_show(struct device *dev,
struct dev_ext_attribute *ea = container_of(attr,
struct dev_ext_attribute, attr);
 
-   return snprintf(buf, PAGE_SIZE, "%s\n", (char *)ea->var);
+   return sysfs_emit(buf, "%s\n", (char *)ea->var);
 }
 
 #define CCN_FORMAT_ATTR(_name, _config) \
@@ -476,7 +476,7 @@ static ssize_t arm_ccn_pmu_cmp_mask_show(struct device *dev,
struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
u64 *mask = arm_ccn_pmu_get_cmp_mask(ccn, attr->attr.name);
 
-   return mask ? snprintf(buf, PAGE_SIZE, "0x%016llx\n", *mask) : -EINVAL;
+   return mask ? sysfs_emit(buf, "0x%016llx\n", *mask) : -EINVAL;
 }
 
 static ssize_t arm_ccn_pmu_cmp_mask_store(struct device *dev,
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 1328159f..56a5c35 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -348,19 +348,19 @@ static ssize_t arm_cmn_e

[PATCH 0/3] drivers/perf: convert sysfs sprintf/snprintf/scnprintf to sysfs_emit

2021-03-17 Thread Qi Liu
Use the generic sysfs_emit() and sysfs_emit_at() function to take
place of sprintf/snprintf/scnprintf, to avoid buffer overrun.

Zihao Tang (1)
  drivers/perf: convert sysfs snprintf family to sysfs_emit

Qi Liu (2):
  drivers/perf: convert sysfs scnprintf family to sysfs_emit_at
  drivers/perf: convert sysfs sprintf family to sysfs_emit

 drivers/perf/arm-cci.c   | 12 ++--
 drivers/perf/arm-ccn.c   | 28 
 drivers/perf/arm-cmn.c   | 22 +++---
 drivers/perf/arm_dmc620_pmu.c|  2 +-
 drivers/perf/arm_dsu_pmu.c   |  5 ++---
 drivers/perf/arm_smmuv3_pmu.c|  4 ++--
 drivers/perf/arm_spe_pmu.c   |  3 +--
 drivers/perf/fsl_imx8_ddr_perf.c |  7 +++
 drivers/perf/hisilicon/hisi_uncore_pmu.c |  8 
 drivers/perf/qcom_l2_pmu.c   |  2 +-
 drivers/perf/qcom_l3_pmu.c   |  4 ++--
 drivers/perf/thunderx2_pmu.c |  4 ++--
 drivers/perf/xgene_pmu.c |  4 ++--
 13 files changed, 49 insertions(+), 56 deletions(-)

-- 
2.8.1



[PATCH 2/3] drivers/perf: convert sysfs scnprintf family to sysfs_emit_at

2021-03-17 Thread Qi Liu
Use the generic sysfs_emit_at() function take place of scnprintf()

Signed-off-by: Qi Liu 
---
 drivers/perf/arm-ccn.c | 24 ++--
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 3a2ddc0..0588f29 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -328,41 +328,37 @@ static ssize_t arm_ccn_pmu_event_show(struct device *dev,
struct arm_ccn_pmu_event, attr);
ssize_t res;
 
-   res = scnprintf(buf, PAGE_SIZE, "type=0x%x", event->type);
+   res = sysfs_emit(buf, "type=0x%x", event->type);
if (event->event)
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",event=0x%x",
+   res += sysfs_emit_at(buf + res, res, ",event=0x%x",
event->event);
if (event->def)
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",%s",
-   event->def);
+   res += sysfs_emit_at(buf + res, res, ",%s", event->def);
if (event->mask)
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",mask=0x%x",
-   event->mask);
+   res += sysfs_emit_at(buf + res, res, ",mask=0x%x", event->mask);
 
/* Arguments required by an event */
switch (event->type) {
case CCN_TYPE_CYCLES:
break;
case CCN_TYPE_XP:
-   res += scnprintf(buf + res, PAGE_SIZE - res,
-   ",xp=?,vc=?");
+   res += sysfs_emit(buf + res, res, ",xp=?,vc=?");
if (event->event == CCN_EVENT_WATCHPOINT)
-   res += scnprintf(buf + res, PAGE_SIZE - res,
+   res += sysfs_emit_at(buf + res, res,
",port=?,dir=?,cmp_l=?,cmp_h=?,mask=?");
else
-   res += scnprintf(buf + res, PAGE_SIZE - res,
-   ",bus=?");
+   res += sysfs_emit_at(buf + res, res, ",bus=?");
 
break;
case CCN_TYPE_MN:
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",node=%d", 
ccn->mn_id);
+   res += sysfs_emit_at(buf + res, res, ",node=%d", ccn->mn_id);
break;
default:
-   res += scnprintf(buf + res, PAGE_SIZE - res, ",node=?");
+   res += sysfs_emit_at(buf + res, res, ",node=?");
break;
}
 
-   res += scnprintf(buf + res, PAGE_SIZE - res, "\n");
+   res += sysfs_emit_at(buf + res, res, "\n");
 
return res;
 }
-- 
2.8.1



[PATCH] drivers/perf: Replace spin_lock_irqsave to spin_lock

2021-02-09 Thread Qi Liu
There is no need to do spin_lock_irqsave in context of hard IRQ, so
replace them with spin_lock.

Signed-off-by: Qi Liu 
---
 drivers/perf/arm-cci.c   | 5 ++---
 drivers/perf/xgene_pmu.c | 5 ++---
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index a75cf77..f81e2ec 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1026,12 +1026,11 @@ static void pmu_event_set_period(struct perf_event 
*event)

 static irqreturn_t pmu_handle_irq(int irq_num, void *dev)
 {
-   unsigned long flags;
struct cci_pmu *cci_pmu = dev;
struct cci_pmu_hw_events *events = _pmu->hw_events;
int idx, handled = IRQ_NONE;

-   raw_spin_lock_irqsave(>pmu_lock, flags);
+   raw_spin_lock(>pmu_lock);

/* Disable the PMU while we walk through the counters */
__cci_pmu_disable(cci_pmu);
@@ -1061,7 +1060,7 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev)

/* Enable the PMU and sync possibly overflowed counters */
__cci_pmu_enable_sync(cci_pmu);
-   raw_spin_unlock_irqrestore(>pmu_lock, flags);
+   raw_spin_unlock(>pmu_lock);

return IRQ_RETVAL(handled);
 }
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index 633cf07..44faa51 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -1234,10 +1234,9 @@ static irqreturn_t xgene_pmu_isr(int irq, void *dev_id)
u32 intr_mcu, intr_mcb, intr_l3c, intr_iob;
struct xgene_pmu_dev_ctx *ctx;
struct xgene_pmu *xgene_pmu = dev_id;
-   unsigned long flags;
u32 val;

-   raw_spin_lock_irqsave(_pmu->lock, flags);
+   raw_spin_lock(_pmu->lock);

/* Get Interrupt PMU source */
val = readl(xgene_pmu->pcppmu_csr + PCPPMU_INTSTATUS_REG);
@@ -1273,7 +1272,7 @@ static irqreturn_t xgene_pmu_isr(int irq, void *dev_id)
}
}

-   raw_spin_unlock_irqrestore(_pmu->lock, flags);
+   raw_spin_unlock(_pmu->lock);

return IRQ_HANDLED;
 }
--
2.8.1



[PATCH] drivers/perf: Simplify the SMMUv3 PMU event attributes

2021-02-08 Thread Qi Liu
For each PMU event, there is a SMMU_EVENT_ATTR(xx, XX) and
_event_attr_xx.attr.attr. Let's redefine the SMMU_EVENT_ATTR
to simplify the smmu_pmu_events.

Signed-off-by: Qi Liu 
---
 drivers/perf/arm_smmuv3_pmu.c | 32 +---
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index 8ff7a67..4c8cb1b 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -509,27 +509,21 @@ static ssize_t smmu_pmu_event_show(struct device *dev,
return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
 }

-#define SMMU_EVENT_ATTR(name, config) \
-   PMU_EVENT_ATTR(name, smmu_event_attr_##name, \
-  config, smmu_pmu_event_show)
-SMMU_EVENT_ATTR(cycles, 0);
-SMMU_EVENT_ATTR(transaction, 1);
-SMMU_EVENT_ATTR(tlb_miss, 2);
-SMMU_EVENT_ATTR(config_cache_miss, 3);
-SMMU_EVENT_ATTR(trans_table_walk_access, 4);
-SMMU_EVENT_ATTR(config_struct_access, 5);
-SMMU_EVENT_ATTR(pcie_ats_trans_rq, 6);
-SMMU_EVENT_ATTR(pcie_ats_trans_passed, 7);
+#define SMMU_EVENT_ATTR(name, config)  \
+   (&((struct perf_pmu_events_attr) {  \
+   .attr = __ATTR(name, 0444, smmu_pmu_event_show, NULL),  \
+   .id = config,   \
+   }).attr.attr)

 static struct attribute *smmu_pmu_events[] = {
-   _event_attr_cycles.attr.attr,
-   _event_attr_transaction.attr.attr,
-   _event_attr_tlb_miss.attr.attr,
-   _event_attr_config_cache_miss.attr.attr,
-   _event_attr_trans_table_walk_access.attr.attr,
-   _event_attr_config_struct_access.attr.attr,
-   _event_attr_pcie_ats_trans_rq.attr.attr,
-   _event_attr_pcie_ats_trans_passed.attr.attr,
+   SMMU_EVENT_ATTR(cycles, 0),
+   SMMU_EVENT_ATTR(transaction, 1),
+   SMMU_EVENT_ATTR(tlb_miss, 2),
+   SMMU_EVENT_ATTR(config_cache_miss, 3),
+   SMMU_EVENT_ATTR(trans_table_walk_access, 4),
+   SMMU_EVENT_ATTR(config_struct_access, 5),
+   SMMU_EVENT_ATTR(pcie_ats_trans_rq, 6),
+   SMMU_EVENT_ATTR(pcie_ats_trans_passed, 7),
NULL
 };

--
2.8.1



[PATCH] drivers/perf: Prevent forced unbinding of ARM_DMC620_PMU drivers

2021-02-02 Thread Qi Liu
Set "suppress_bind_attrs" to true, so that bind/unbind can be
disabled via sysfs and prevent unbinding ARM_DMC620_PMU drivers
during perf sampling.

Signed-off-by: Qi Liu 
---
 drivers/perf/arm_dmc620_pmu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
index 27f54c0..66ad5b3 100644
--- a/drivers/perf/arm_dmc620_pmu.c
+++ b/drivers/perf/arm_dmc620_pmu.c
@@ -717,6 +717,7 @@ static struct platform_driver dmc620_pmu_driver = {
.driver = {
.name   = DMC620_DRVNAME,
.acpi_match_table = dmc620_acpi_match,
+   .suppress_bind_attrs = true,
},
.probe  = dmc620_pmu_device_probe,
.remove = dmc620_pmu_device_remove,
--
2.8.1



[PATCH] coresight: Remove duplicate header files of coresight drivers

2021-02-01 Thread Qi Liu
Remove duplicate included header files, as coresight-priv.h is included in
these coresight drivers.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-catu.c | 2 --
 drivers/hwtracing/coresight/coresight-core.c | 3 ---
 drivers/hwtracing/coresight/coresight-cpu-debug.c| 3 ---
 drivers/hwtracing/coresight/coresight-cti-core.c | 3 ---
 drivers/hwtracing/coresight/coresight-cti-platform.c | 1 -
 drivers/hwtracing/coresight/coresight-cti.h  | 1 -
 drivers/hwtracing/coresight/coresight-etb10.c| 4 
 drivers/hwtracing/coresight/coresight-etm-perf.c | 1 -
 drivers/hwtracing/coresight/coresight-etm3x-sysfs.c  | 1 -
 drivers/hwtracing/coresight/coresight-etm4x-core.c   | 5 -
 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c  | 1 -
 drivers/hwtracing/coresight/coresight-funnel.c   | 3 ---
 drivers/hwtracing/coresight/coresight-platform.c | 2 --
 drivers/hwtracing/coresight/coresight-replicator.c   | 3 ---
 drivers/hwtracing/coresight/coresight-stm.c  | 3 ---
 drivers/hwtracing/coresight/coresight-tmc-core.c | 3 ---
 drivers/hwtracing/coresight/coresight-tmc-etf.c  | 1 -
 drivers/hwtracing/coresight/coresight-tmc-etr.c  | 1 -
 drivers/hwtracing/coresight/coresight-tpiu.c | 4 
 19 files changed, 45 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-catu.c 
b/drivers/hwtracing/coresight/coresight-catu.c
index a61313f..fcc0367 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -7,10 +7,8 @@
  * Author: Suzuki K Poulose 
  */

-#include 
 #include 
 #include 
-#include 
 #include 
 #include 

diff --git a/drivers/hwtracing/coresight/coresight-core.c 
b/drivers/hwtracing/coresight/coresight-core.c
index 4ba801d..5fb8b12 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -7,17 +7,14 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
-#include 

 #include "coresight-etm-perf.h"
 #include "coresight-priv.h"
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c 
b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index e1d2324..f8df512 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -4,15 +4,12 @@
  *
  * Author: Leo Yan 
  */
-#include 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c 
b/drivers/hwtracing/coresight/coresight-cti-core.c
index 61dbc1a..ed7ab82 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -4,18 +4,15 @@
  * Author: Mike Leach 
  */

-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 

diff --git a/drivers/hwtracing/coresight/coresight-cti-platform.c 
b/drivers/hwtracing/coresight/coresight-cti-platform.c
index ccef04f..60b0580 100644
--- a/drivers/hwtracing/coresight/coresight-cti-platform.c
+++ b/drivers/hwtracing/coresight/coresight-cti-platform.c
@@ -2,7 +2,6 @@
 /*
  * Copyright (c) 2019, The Linaro Limited. All rights reserved.
  */
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/hwtracing/coresight/coresight-cti.h 
b/drivers/hwtracing/coresight/coresight-cti.h
index acf7b54..0a3b313 100644
--- a/drivers/hwtracing/coresight/coresight-cti.h
+++ b/drivers/hwtracing/coresight/coresight-cti.h
@@ -7,7 +7,6 @@
 #ifndef _CORESIGHT_CORESIGHT_CTI_H
 #define _CORESIGHT_CORESIGHT_CTI_H

-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c 
b/drivers/hwtracing/coresight/coresight-etb10.c
index 0cf6f0b..8d5bc04 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -10,17 +10,13 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
-#include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c 
b/drivers/hwtracing/coresight/coresight-etm-perf.c
index bdc34ca..01aba63 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -4,7 +4,6 @@
  * Author: Mathieu Poirier 
  */

-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c 
b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index e8c7649..5cf6660 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -5,7 +5,6 @@
  */

 #include 
-#include 
 #include 
 #include "coresight-et

[PATCH v6] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-12-07 Thread Qi Liu
The ETM device can't keep up with the core pipeline when cpu core
is at full speed. This may cause overflow within core and its ETM.
This is a common phenomenon on ETM devices.

On HiSilicon Hip08 platform, a specific feature is added to set
core pipeline. So commit rate can be reduced manually to avoid ETM
overflow.

Reviewed-by: Suzuki K Poulose 
Signed-off-by: Qi Liu 
---
Change since v1:
- add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
  to keep specific feature off platforms which don't use it.
Change since v2:
- remove some unused variable.
Change since v3:
- use read/write_sysreg_s() to access register.
Change since v4:
- rename the call back function to a more generic name, and fix some
  compile warnings.
Change since v5:
- add function comments about HISI_HIP08_CORE_COMMIT_REG, and use
  explicitly masked values when update register.

 drivers/hwtracing/coresight/Kconfig|  9 ++
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 98 ++
 drivers/hwtracing/coresight/coresight-etm4x.h  |  8 ++
 3 files changed, 115 insertions(+)

diff --git a/drivers/hwtracing/coresight/Kconfig 
b/drivers/hwtracing/coresight/Kconfig
index c119824..1cc3601 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -110,6 +110,15 @@ config CORESIGHT_SOURCE_ETM4X
  To compile this driver as a module, choose M here: the
  module will be called coresight-etm4x.

+config ETM4X_IMPDEF_FEATURE
+   bool "Control overflow impdef support in CoreSight ETM 4.x driver "
+   depends on CORESIGHT_SOURCE_ETM4X
+   help
+ This control provides overflow implement define for CoreSight
+ ETM 4.x tracer module which could not reduce commit race
+ automatically, and could avoid overflow within ETM tracer module
+ and its cpu core.
+
 config CORESIGHT_STM
tristate "CoreSight System Trace Macrocell driver"
depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index abd706b..0cbc92a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
  */

+#include 
 #include 
 #include 
 #include 
@@ -28,7 +29,9 @@
 #include 
 #include 
 #include 
+
 #include 
+#include 
 #include 
 #include 

@@ -103,6 +106,97 @@ struct etm4_enable_arg {
int rc;
 };

+#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
+
+#define HISI_HIP08_AMBA_ID 0x000b6d01
+#define ETM4_AMBA_MASK 0xf
+#define HISI_HIP08_CORE_COMMIT_MASK0x3000
+#define HISI_HIP08_CORE_COMMIT_SHIFT   12
+#define HISI_HIP08_CORE_COMMIT_FULL0b00
+#define HISI_HIP08_CORE_COMMIT_LVL_1   0b01
+#define HISI_HIP08_CORE_COMMIT_REG sys_reg(3, 1, 15, 2, 5)
+
+struct etm4_arch_features {
+   void (*arch_callback)(bool enable);
+};
+
+static bool etm4_hisi_match_pid(unsigned int id)
+{
+   return (id & ETM4_AMBA_MASK) == HISI_HIP08_AMBA_ID;
+}
+
+static void etm4_hisi_config_core_commit(bool enable)
+{
+   u8 commit = enable ? HISI_HIP08_CORE_COMMIT_LVL_1 :
+   HISI_HIP08_CORE_COMMIT_FULL;
+   u64 val;
+
+   /*
+* bit 12 and 13 of HISI_HIP08_CORE_COMMIT_REG are used together
+* to set core-commit, 2'b00 means cpu is at full speed, 2'b01,
+* 2'b10, 2'b11 mean reduce pipeline speed, and 2'b01 means level-1
+* speed(minimun value). So bit 12 and 13 should be cleared together.
+*/
+   val = read_sysreg_s(HISI_HIP08_CORE_COMMIT_REG);
+   val &= ~HISI_HIP08_CORE_COMMIT_MASK;
+   val |= commit << HISI_HIP08_CORE_COMMIT_SHIFT;
+   write_sysreg_s(val, HISI_HIP08_CORE_COMMIT_REG);
+}
+
+static struct etm4_arch_features etm4_features[] = {
+   [ETM4_IMPDEF_HISI_CORE_COMMIT] = {
+   .arch_callback = etm4_hisi_config_core_commit,
+   },
+   {},
+};
+
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct etm4_arch_features *ftr;
+   int bit;
+
+   for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
+   ftr = _features[bit];
+
+   if (ftr->arch_callback)
+   ftr->arch_callback(true);
+   }
+}
+
+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct etm4_arch_features *ftr;
+   int bit;
+
+   for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
+   ftr = _features[bit];
+
+   if (ftr->arch_callback)
+   ftr->arch_callback(false);
+   }
+}
+
+static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
+   

Re: [PATCH v5] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-12-07 Thread Qi Liu



On 2020/12/7 19:27, Suzuki K Poulose wrote:
> On 12/7/20 11:21 AM, Qi Liu wrote:
>>
>> Hi Suzuki,
>> On 2020/12/7 18:38, Suzuki K Poulose wrote:
>>> On 12/7/20 2:08 AM, Qi Liu wrote:
>>>> Hi Mathieu,
>>>>
>>>> On 2020/12/5 2:55, Mathieu Poirier wrote:
>>>>> On Thu, Nov 26, 2020 at 09:34:30PM +0800, Qi Liu wrote:
>>>>>> The ETM device can't keep up with the core pipeline when cpu core
>>>>>> is at full speed. This may cause overflow within core and its ETM.
>>>>>> This is a common phenomenon on ETM devices.
>>>>>>
>>>>>> On HiSilicon Hip08 platform, a specific feature is added to set
>>>>>> core pipeline. So commit rate can be reduced manually to avoid ETM
>>>>>> overflow.
>>>>>>
>>>>>> Signed-off-by: Qi Liu 
>>>>>> ---
>>>>>> Change since v1:
>>>>>> - add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
>>>>>> to keep specific feature off platforms which don't use it.
>>>>>> Change since v2:
>>>>>> - remove some unused variable.
>>>>>> Change since v3:
>>>>>> - use read/write_sysreg_s() to access register.
>>>>>> Change since v4:
>>>>>> - rename the call back function to a more generic name, and fix some
>>>>>> compile warnings.
>>>>>>
>>>>>>drivers/hwtracing/coresight/Kconfig|  9 +++
>>>>>>drivers/hwtracing/coresight/coresight-etm4x-core.c | 88 
>>>>>> ++
>>>>>>drivers/hwtracing/coresight/coresight-etm4x.h  |  8 ++
>>>>>>3 files changed, 105 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/hwtracing/coresight/Kconfig 
>>>>>> b/drivers/hwtracing/coresight/Kconfig
>>>>>> index c119824..1cc3601 100644
>>>>>> --- a/drivers/hwtracing/coresight/Kconfig
>>>>>> +++ b/drivers/hwtracing/coresight/Kconfig
>>>>>> @@ -110,6 +110,15 @@ config CORESIGHT_SOURCE_ETM4X
>>>>>>  To compile this driver as a module, choose M here: the
>>>>>>  module will be called coresight-etm4x.
>>>>>>
>>>>>> +config ETM4X_IMPDEF_FEATURE
>>>>>> +bool "Control overflow impdef support in CoreSight ETM 4.x driver "
>>>>>> +depends on CORESIGHT_SOURCE_ETM4X
>>>>>> +help
>>>>>> +  This control provides overflow implement define for CoreSight
>>>>>> +  ETM 4.x tracer module which could not reduce commit race
>>>>>> +  automatically, and could avoid overflow within ETM tracer module
>>>>>> +  and its cpu core.
>>>>>> +
>>>>>>config CORESIGHT_STM
>>>>>>tristate "CoreSight System Trace Macrocell driver"
>>>>>>depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
>>>>>> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>>>> index abd706b..fcee27a 100644
>>>>>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>>>> @@ -3,6 +3,7 @@
>>>>>> * Copyright (c) 2014, The Linux Foundation. All rights reserved.
>>>>>> */
>>>>>>
>>>>>> +#include 
>>>>>>#include 
>>>>>>#include 
>>>>>>#include 
>>>>>> @@ -28,7 +29,9 @@
>>>>>>#include 
>>>>>>#include 
>>>>>>#include 
>>>>>> +
>>>>>>#include 
>>>>>> +#include 
>>>>>>#include 
>>>>>>#include 
>>>>>>
>>>>>> @@ -103,6 +106,87 @@ struct etm4_enable_arg {
>>>>>>int rc;
>>>>>>};
>>>>>>
>>>>>> +#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
>>>>>> +
>>>>>> +#define HISI_HIP08_AMBA_ID0x000b6d01
>>>>>> +#define ETM4_AMBA_MASK0xf
>>>>&

Re: [PATCH v5] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-12-07 Thread Qi Liu


Hi Suzuki,
On 2020/12/7 18:38, Suzuki K Poulose wrote:
> On 12/7/20 2:08 AM, Qi Liu wrote:
>> Hi Mathieu,
>>
>> On 2020/12/5 2:55, Mathieu Poirier wrote:
>>> On Thu, Nov 26, 2020 at 09:34:30PM +0800, Qi Liu wrote:
>>>> The ETM device can't keep up with the core pipeline when cpu core
>>>> is at full speed. This may cause overflow within core and its ETM.
>>>> This is a common phenomenon on ETM devices.
>>>>
>>>> On HiSilicon Hip08 platform, a specific feature is added to set
>>>> core pipeline. So commit rate can be reduced manually to avoid ETM
>>>> overflow.
>>>>
>>>> Signed-off-by: Qi Liu 
>>>> ---
>>>> Change since v1:
>>>> - add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
>>>>to keep specific feature off platforms which don't use it.
>>>> Change since v2:
>>>> - remove some unused variable.
>>>> Change since v3:
>>>> - use read/write_sysreg_s() to access register.
>>>> Change since v4:
>>>> - rename the call back function to a more generic name, and fix some
>>>>compile warnings.
>>>>
>>>>   drivers/hwtracing/coresight/Kconfig|  9 +++
>>>>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 88 
>>>> ++
>>>>   drivers/hwtracing/coresight/coresight-etm4x.h  |  8 ++
>>>>   3 files changed, 105 insertions(+)
>>>>
>>>> diff --git a/drivers/hwtracing/coresight/Kconfig 
>>>> b/drivers/hwtracing/coresight/Kconfig
>>>> index c119824..1cc3601 100644
>>>> --- a/drivers/hwtracing/coresight/Kconfig
>>>> +++ b/drivers/hwtracing/coresight/Kconfig
>>>> @@ -110,6 +110,15 @@ config CORESIGHT_SOURCE_ETM4X
>>>> To compile this driver as a module, choose M here: the
>>>> module will be called coresight-etm4x.
>>>>
>>>> +config ETM4X_IMPDEF_FEATURE
>>>> +bool "Control overflow impdef support in CoreSight ETM 4.x driver "
>>>> +depends on CORESIGHT_SOURCE_ETM4X
>>>> +help
>>>> +  This control provides overflow implement define for CoreSight
>>>> +  ETM 4.x tracer module which could not reduce commit race
>>>> +  automatically, and could avoid overflow within ETM tracer module
>>>> +  and its cpu core.
>>>> +
>>>>   config CORESIGHT_STM
>>>>   tristate "CoreSight System Trace Macrocell driver"
>>>>   depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
>>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
>>>> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>> index abd706b..fcee27a 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>> @@ -3,6 +3,7 @@
>>>>* Copyright (c) 2014, The Linux Foundation. All rights reserved.
>>>>*/
>>>>
>>>> +#include 
>>>>   #include 
>>>>   #include 
>>>>   #include 
>>>> @@ -28,7 +29,9 @@
>>>>   #include 
>>>>   #include 
>>>>   #include 
>>>> +
>>>>   #include 
>>>> +#include 
>>>>   #include 
>>>>   #include 
>>>>
>>>> @@ -103,6 +106,87 @@ struct etm4_enable_arg {
>>>>   int rc;
>>>>   };
>>>>
>>>> +#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
>>>> +
>>>> +#define HISI_HIP08_AMBA_ID0x000b6d01
>>>> +#define ETM4_AMBA_MASK0xf
>>>> +#define HISI_HIP08_CORE_COMMIT_CLEAR0x3000
>>>
>>> Here bit 12 and 13 are cleared but in etm4_hisi_config_core_commit() only 
>>> bit 12
>>> is set - is this intentional?  What is bit 13 for?
>>>
>> bit 12 and 13 are used together to set core-commit, 2'b00 means cpu is at 
>> full speed,
>> 2'b01, 2'b10, 2'b11 means reduce the speed of cpu pipeline, and 2'b01 means 
>> speed is
>> reduced to minimum value. So bit 12 and 13 should be cleared together in
>> etm4_hisi_config_core_commit().
> 
> Please could you document this in the function.
> 
of course, thanks.
>>
>> Qi
>>
>>>> +#define HISI_HIP08_CORE_COMMIT_SHIFT12
>>>> +#define HISI_HIP08_CORE_COMMIT_REGsys_reg(3, 1, 15, 2, 5)
>>>> +
>>>> +struct etm4_arch_features {
>>>> +void (*arch_callback)(bool enable);
>>>> +};
>>>> +
>>>> +static bool etm4_hisi_match_pid(unsigned int id)
>>>> +{
>>>> +return (id & ETM4_AMBA_MASK) == HISI_HIP08_AMBA_ID;
>>>> +}
>>>> +
>>>> +static void etm4_hisi_config_core_commit(bool enable)
>>>> +{
>>>> +u64 val;
>>>> +
>>>> +val = read_sysreg_s(HISI_HIP08_CORE_COMMIT_REG);
>>>> +val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
>>>> +val |= enable << HISI_HIP08_CORE_COMMIT_SHIFT;
> 
> I would use the explicitly masked values when you update
> a register.
> 
ok, how about changing these code to this:
val &= ~GENMASK(12, 13);

Thanks
Qi

> With the above:
> 
> Reviewed-by: Suzuki K Poulose 
> 
> .
> 



Re: [PATCH v5] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-12-06 Thread Qi Liu
Hi Mathieu,

On 2020/12/5 2:55, Mathieu Poirier wrote:
> On Thu, Nov 26, 2020 at 09:34:30PM +0800, Qi Liu wrote:
>> The ETM device can't keep up with the core pipeline when cpu core
>> is at full speed. This may cause overflow within core and its ETM.
>> This is a common phenomenon on ETM devices.
>>
>> On HiSilicon Hip08 platform, a specific feature is added to set
>> core pipeline. So commit rate can be reduced manually to avoid ETM
>> overflow.
>>
>> Signed-off-by: Qi Liu 
>> ---
>> Change since v1:
>> - add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
>>   to keep specific feature off platforms which don't use it.
>> Change since v2:
>> - remove some unused variable.
>> Change since v3:
>> - use read/write_sysreg_s() to access register.
>> Change since v4:
>> - rename the call back function to a more generic name, and fix some
>>   compile warnings.
>>
>>  drivers/hwtracing/coresight/Kconfig|  9 +++
>>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 88 
>> ++
>>  drivers/hwtracing/coresight/coresight-etm4x.h  |  8 ++
>>  3 files changed, 105 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/Kconfig 
>> b/drivers/hwtracing/coresight/Kconfig
>> index c119824..1cc3601 100644
>> --- a/drivers/hwtracing/coresight/Kconfig
>> +++ b/drivers/hwtracing/coresight/Kconfig
>> @@ -110,6 +110,15 @@ config CORESIGHT_SOURCE_ETM4X
>>To compile this driver as a module, choose M here: the
>>module will be called coresight-etm4x.
>>
>> +config ETM4X_IMPDEF_FEATURE
>> +bool "Control overflow impdef support in CoreSight ETM 4.x driver "
>> +depends on CORESIGHT_SOURCE_ETM4X
>> +help
>> +  This control provides overflow implement define for CoreSight
>> +  ETM 4.x tracer module which could not reduce commit race
>> +  automatically, and could avoid overflow within ETM tracer module
>> +  and its cpu core.
>> +
>>  config CORESIGHT_STM
>>  tristate "CoreSight System Trace Macrocell driver"
>>  depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
>> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index abd706b..fcee27a 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -3,6 +3,7 @@
>>   * Copyright (c) 2014, The Linux Foundation. All rights reserved.
>>   */
>>
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -28,7 +29,9 @@
>>  #include 
>>  #include 
>>  #include 
>> +
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>
>> @@ -103,6 +106,87 @@ struct etm4_enable_arg {
>>  int rc;
>>  };
>>
>> +#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
>> +
>> +#define HISI_HIP08_AMBA_ID  0x000b6d01
>> +#define ETM4_AMBA_MASK  0xf
>> +#define HISI_HIP08_CORE_COMMIT_CLEAR0x3000
> 
> Here bit 12 and 13 are cleared but in etm4_hisi_config_core_commit() only bit 
> 12
> is set - is this intentional?  What is bit 13 for? 
> 
bit 12 and 13 are used together to set core-commit, 2'b00 means cpu is at full 
speed,
2'b01, 2'b10, 2'b11 means reduce the speed of cpu pipeline, and 2'b01 means 
speed is
reduced to minimum value. So bit 12 and 13 should be cleared together in
etm4_hisi_config_core_commit().

Qi

>> +#define HISI_HIP08_CORE_COMMIT_SHIFT12
>> +#define HISI_HIP08_CORE_COMMIT_REG  sys_reg(3, 1, 15, 2, 5)
>> +
>> +struct etm4_arch_features {
>> +void (*arch_callback)(bool enable);
>> +};
>> +
>> +static bool etm4_hisi_match_pid(unsigned int id)
>> +{
>> +return (id & ETM4_AMBA_MASK) == HISI_HIP08_AMBA_ID;
>> +}
>> +
>> +static void etm4_hisi_config_core_commit(bool enable)
>> +{
>> +u64 val;
>> +
>> +val = read_sysreg_s(HISI_HIP08_CORE_COMMIT_REG);
>> +val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
>> +val |= enable << HISI_HIP08_CORE_COMMIT_SHIFT;
>> +write_sysreg_s(val, HISI_HIP08_CORE_COMMIT_REG);
>> +}
>> +
>> +static struct etm4_arch_features etm4_features[] = {
>> +[ETM4_IMPDEF_HISI_CORE_COMMIT] = {
>> +.arch_callback = etm4_hisi_config_core_commit,
>> +},
>> +{},
>> +};
>> +
>> +static void etm4_enable_arch_specific(struct 

Re: [PATCH] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-11-26 Thread Qi Liu



On 2020/11/23 22:12, Suzuki K Poulose wrote:
> Hi Qi
> 
> Thanks for the changes. Mostly looks good to me, except for the
> name of the call back.
> 
> 
Hi Suzuki,
ok, I'll send a new patch to change the name of call back.

Thanks
Qi
> On 11/23/20 1:29 PM, Qi Liu wrote:
>> The ETM device can't keep up with the core pipeline when cpu core
>> is at full speed. This may cause overflow within core and its ETM.
>> This is a common phenomenon on ETM devices.
>>
>> On HiSilicon Hip08 platform, a specific feature is added to set
>> core pipeline. So commit rate can be reduced manually to avoid ETM
>> overflow.
>>
>> Signed-off-by: Qi Liu 
> 
> 
>> ---
>> Change since v1:
>> - add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
>>to keep specific feature off platforms which don't use it.
>> Change since v2:
>> - remove some unused variable.
>> Change since v3:
>> - use read/write_sysreg_s() to access register.
>>
>>   drivers/hwtracing/coresight/Kconfig|  9 +++
>>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 84 
>> ++
>>   drivers/hwtracing/coresight/coresight-etm4x.h  | 12 
>>   3 files changed, 105 insertions(+)
>>
> 
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h 
>> b/drivers/hwtracing/coresight/coresight-etm4x.h
>> index eefc737..1784975 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
>> @@ -8,6 +8,7 @@
>>
>>   #include 
>>   #include 
>> +#include 
>>   #include "coresight-priv.h"
>>
>>   /*
>> @@ -203,6 +204,11 @@
>>   /* Interpretation of resource numbers change at ETM v4.3 architecture */
>>   #define ETM4X_ARCH_4V30x43
>>
>> +enum etm_impdef_type {
>> +ETM4_IMPDEF_HISI_CORE_COMMIT,
>> +ETM4_IMPDEF_FEATURE_MAX,
>> +};
>> +
>>   /**
>>* struct etmv4_config - configuration information related to an ETMv4
>>* @mode:Controls various modes supported by this ETM.
>> @@ -415,6 +421,7 @@ struct etmv4_save_state {
>>* @state_needs_restore: True when there is context to restore after PM 
>> exit
>>* @skip_power_up: Indicates if an implementation can skip powering up
>>*   the trace unit.
>> + * @arch_features: Bitmap of arch features of etmv4 devices.
>>*/
>>   struct etmv4_drvdata {
>>   void __iomem*base;
>> @@ -463,6 +470,11 @@ struct etmv4_drvdata {
>>   struct etmv4_save_state*save_state;
>>   boolstate_needs_restore;
>>   boolskip_power_up;
>> +DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX);
>> +};
>> +
>> +struct etm4_arch_features {
>> +void (*set_commit)(bool enable);
> 
> The set_commit is too hisilicon specific :-). Could we please rename
> this to soemthing more generic. The callback for hisilicon etms, could still
> be xx_commit". May be simply call it
> 
> callback() ?
> 
> or may be even
> arch_callback() ?
> 
> 
>>   };
> 
> nit: This need not be part of the header file, as it is not used
> outside the etm4x-core.c
> 
> Suzuki
> 
> .
> 



[PATCH v5] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-11-26 Thread Qi Liu
The ETM device can't keep up with the core pipeline when cpu core
is at full speed. This may cause overflow within core and its ETM.
This is a common phenomenon on ETM devices.

On HiSilicon Hip08 platform, a specific feature is added to set
core pipeline. So commit rate can be reduced manually to avoid ETM
overflow.

Signed-off-by: Qi Liu 
---
Change since v1:
- add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
  to keep specific feature off platforms which don't use it.
Change since v2:
- remove some unused variable.
Change since v3:
- use read/write_sysreg_s() to access register.
Change since v4:
- rename the call back function to a more generic name, and fix some
  compile warnings.

 drivers/hwtracing/coresight/Kconfig|  9 +++
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 88 ++
 drivers/hwtracing/coresight/coresight-etm4x.h  |  8 ++
 3 files changed, 105 insertions(+)

diff --git a/drivers/hwtracing/coresight/Kconfig 
b/drivers/hwtracing/coresight/Kconfig
index c119824..1cc3601 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -110,6 +110,15 @@ config CORESIGHT_SOURCE_ETM4X
  To compile this driver as a module, choose M here: the
  module will be called coresight-etm4x.

+config ETM4X_IMPDEF_FEATURE
+   bool "Control overflow impdef support in CoreSight ETM 4.x driver "
+   depends on CORESIGHT_SOURCE_ETM4X
+   help
+ This control provides overflow implement define for CoreSight
+ ETM 4.x tracer module which could not reduce commit race
+ automatically, and could avoid overflow within ETM tracer module
+ and its cpu core.
+
 config CORESIGHT_STM
tristate "CoreSight System Trace Macrocell driver"
depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index abd706b..fcee27a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
  */

+#include 
 #include 
 #include 
 #include 
@@ -28,7 +29,9 @@
 #include 
 #include 
 #include 
+
 #include 
+#include 
 #include 
 #include 

@@ -103,6 +106,87 @@ struct etm4_enable_arg {
int rc;
 };

+#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
+
+#define HISI_HIP08_AMBA_ID 0x000b6d01
+#define ETM4_AMBA_MASK 0xf
+#define HISI_HIP08_CORE_COMMIT_CLEAR   0x3000
+#define HISI_HIP08_CORE_COMMIT_SHIFT   12
+#define HISI_HIP08_CORE_COMMIT_REG sys_reg(3, 1, 15, 2, 5)
+
+struct etm4_arch_features {
+   void (*arch_callback)(bool enable);
+};
+
+static bool etm4_hisi_match_pid(unsigned int id)
+{
+   return (id & ETM4_AMBA_MASK) == HISI_HIP08_AMBA_ID;
+}
+
+static void etm4_hisi_config_core_commit(bool enable)
+{
+   u64 val;
+
+   val = read_sysreg_s(HISI_HIP08_CORE_COMMIT_REG);
+   val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
+   val |= enable << HISI_HIP08_CORE_COMMIT_SHIFT;
+   write_sysreg_s(val, HISI_HIP08_CORE_COMMIT_REG);
+}
+
+static struct etm4_arch_features etm4_features[] = {
+   [ETM4_IMPDEF_HISI_CORE_COMMIT] = {
+   .arch_callback = etm4_hisi_config_core_commit,
+   },
+   {},
+};
+
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct etm4_arch_features *ftr;
+   int bit;
+
+   for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
+   ftr = _features[bit];
+
+   if (ftr->arch_callback)
+   ftr->arch_callback(true);
+   }
+}
+
+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct etm4_arch_features *ftr;
+   int bit;
+
+   for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
+   ftr = _features[bit];
+
+   if (ftr->arch_callback)
+   ftr->arch_callback(false);
+   }
+}
+
+static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
+ unsigned int id)
+{
+   if (etm4_hisi_match_pid(id))
+   set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
+}
+#else
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+}
+
+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+}
+
+static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
+unsigned int id)
+{
+}
+#endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
+
 static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 {
int i, rc;
@@ -110,6 +194,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
struct device *etm_dev = >csdev->dev;

  

[PATCH] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-11-23 Thread Qi Liu
The ETM device can't keep up with the core pipeline when cpu core
is at full speed. This may cause overflow within core and its ETM.
This is a common phenomenon on ETM devices.

On HiSilicon Hip08 platform, a specific feature is added to set
core pipeline. So commit rate can be reduced manually to avoid ETM
overflow.

Signed-off-by: Qi Liu 
---
Change since v1:
- add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
  to keep specific feature off platforms which don't use it.
Change since v2:
- remove some unused variable.
Change since v3:
- use read/write_sysreg_s() to access register.

 drivers/hwtracing/coresight/Kconfig|  9 +++
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 84 ++
 drivers/hwtracing/coresight/coresight-etm4x.h  | 12 
 3 files changed, 105 insertions(+)

diff --git a/drivers/hwtracing/coresight/Kconfig 
b/drivers/hwtracing/coresight/Kconfig
index c119824..1cc3601 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -110,6 +110,15 @@ config CORESIGHT_SOURCE_ETM4X
  To compile this driver as a module, choose M here: the
  module will be called coresight-etm4x.

+config ETM4X_IMPDEF_FEATURE
+   bool "Control overflow impdef support in CoreSight ETM 4.x driver "
+   depends on CORESIGHT_SOURCE_ETM4X
+   help
+ This control provides overflow implement define for CoreSight
+ ETM 4.x tracer module which could not reduce commit race
+ automatically, and could avoid overflow within ETM tracer module
+ and its cpu core.
+
 config CORESIGHT_STM
tristate "CoreSight System Trace Macrocell driver"
depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index abd706b..a1cf215 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
  */

+#include 
 #include 
 #include 
 #include 
@@ -28,7 +29,9 @@
 #include 
 #include 
 #include 
+
 #include 
+#include 
 #include 
 #include 

@@ -103,6 +106,83 @@ struct etm4_enable_arg {
int rc;
 };

+#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
+
+#define HISI_HIP08_AMBA_ID 0x000b6d01
+#define ETM4_AMBA_MASK 0xf
+#define HISI_HIP08_CORE_COMMIT_CLEAR   0x3000
+#define HISI_HIP08_CORE_COMMIT_SHIFT   12
+#define HISI_HIP08_CORE_COMMIT_REG sys_reg(3, 1, 15, 2, 5)
+
+bool etm4_hisi_match_pid(unsigned int id)
+{
+   return (id & ETM4_AMBA_MASK) == HISI_HIP08_AMBA_ID;
+}
+
+static void etm4_hisi_config_core_commit(bool enable)
+{
+   u64 val;
+
+   val = read_sysreg_s(HISI_HIP08_CORE_COMMIT_REG);
+   val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
+   val |= enable << HISI_HIP08_CORE_COMMIT_SHIFT;
+   write_sysreg_s(val, HISI_HIP08_CORE_COMMIT_REG);
+}
+
+static struct etm4_arch_features etm4_features[] = {
+   [ETM4_IMPDEF_HISI_CORE_COMMIT] = {
+   .set_commit = etm4_hisi_config_core_commit,
+   },
+   {},
+};
+
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct etm4_arch_features *ftr;
+   int bit;
+
+   for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
+   ftr = _features[bit];
+
+   if (ftr->set_commit)
+   ftr->set_commit(true);
+   }
+}
+
+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct etm4_arch_features *ftr;
+   int bit;
+
+   for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
+   ftr = _features[bit];
+
+   if (ftr->set_commit)
+   ftr->set_commit(false);
+   }
+}
+
+static void etm4x_check_arch_features(struct etmv4_drvdata *drvdata,
+ unsigned int id)
+{
+   if (etm4_hisi_match_pid(id))
+   set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
+}
+#else
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+}
+
+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+}
+
+static void etm4_check_arch_features(struct etmv4_drvdata drvdata,
+unsigned int id)
+{
+}
+#endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
+
 static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 {
int i, rc;
@@ -110,6 +190,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
struct device *etm_dev = >csdev->dev;

CS_UNLOCK(drvdata->base);
+   etm4_enable_arch_specific(drvdata);

etm4_os_unlock(drvdata);

@@ -476,6 +557,7 @@ static void etm4_disable_hw(void *info)
int i;


Re: [RFC PATCH v2] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-11-13 Thread Qi Liu



On 2020/11/12 22:03, Suzuki K Poulose wrote:
> On 11/12/20 1:09 PM, Qi Liu wrote:
>>
>>
>> On 2020/11/12 1:03, Mathieu Poirier wrote:
>>> On Wed, Nov 11, 2020 at 04:58:23PM +0800, Qi Liu wrote:
>>>> Hi Mathieu,
>>>>
>>>> On 2020/9/10 0:26, Mathieu Poirier wrote:
>>>>> On Wed, Sep 09, 2020 at 12:30:02PM +0100, Mike Leach wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On Wed, 2 Sep 2020 at 11:36, Suzuki K Poulose  
>>>>>> wrote:
>>>>>>> On 08/27/2020 09:44 PM, Mathieu Poirier wrote:
>>>>>>>> Hi Liu,
>>>>>>>>
>>>>>>>> On Wed, Aug 19, 2020 at 04:06:37PM +0800, Qi Liu wrote:
>>>>>>>>> When too much trace information is generated on-chip, the ETM will
>>>>>>>>> overflow, and cause data loss. This is a common phenomenon on ETM
>>>>>>>>> devices.
>>>>>>>>>
>>>>>>>>> But sometimes we do not want to lose performance trace data, so we
>>>>>>>>> suppress the speed of instructions sent from CPU core to ETM to
>>>>>>>>> avoid the overflow of ETM.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Qi Liu 
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>> Changes since v1:
>>>>>>>>> - ETM on HiSilicon Hip09 platform supports backpressure, so does
>>>>>>>>> not need to modify core commit.
>>>>>>>>>
>>>>>>>>>drivers/hwtracing/coresight/coresight-etm4x.c | 43 
>>>>>>>>> +++
>>>>>>>>>1 file changed, 43 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
>>>>>>>>> b/drivers/hwtracing/coresight/coresight-etm4x.c
>>>>>>>>> index 7797a57..7641f89 100644
>>>>>>>>> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
>>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
>>>>>>>>> @@ -43,6 +43,10 @@ MODULE_PARM_DESC(boot_enable, "Enable tracing on 
>>>>>>>>> boot");
>>>>>>>>>#define PARAM_PM_SAVE_NEVER  1 /* never save any state */
>>>>>>>>>#define PARAM_PM_SAVE_SELF_HOSTED 2 /* save self-hosted state only 
>>>>>>>>> */
>>>>>>>>>
>>>>>>>>> +#define CORE_COMMIT_CLEAR   0x3000
>>>>>>>>> +#define CORE_COMMIT_SHIFT   12
>>>>>>>>> +#define HISI_ETM_AMBA_ID_V1 0x000b6d01
>>>>>>>>> +
>>>>>>>>>static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
>>>>>>>>>module_param(pm_save_enable, int, 0444);
>>>>>>>>>MODULE_PARM_DESC(pm_save_enable,
>>>>>>>>> @@ -104,11 +108,40 @@ struct etm4_enable_arg {
>>>>>>>>>   int rc;
>>>>>>>>>};
>>>>>>>>>
>>>>>>>>> +static void etm4_cpu_actlr1_cfg(void *info)
>>>>>>>>> +{
>>>>>>>>> +struct etm4_enable_arg *arg = (struct etm4_enable_arg *)info;
>>>>>>>>> +u64 val;
>>>>>>>>> +
>>>>>>>>> +asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
>>>>>>>
>>>>>>> The ID register (S3_1_C15_c2_5) falls into implementation defined space.
>>>>>>> See Arm ARM DDI 0487F.a, section "D12.3.2  Reserved encodings for
>>>>>>> IMPLEMENTATION DEFINED registers".
>>>>>>>
>>>>>>> So, please stop calling this "etm4_cpu_actlr1_cfg". Since,
>>>>>>> 1) actlr1 is not an architected name for the said encoding
>>>>>>> 2) The id register could mean something else on another CPU.
>>>>>>>
>>>>>>> Rather this should indicate platform/CPU specific. e.g,
>>>>>>>
>>>>>>> etm4_cpu_hisilicon_config_core_commit()
>>>>>>>
>>>>>>>
>>>>&

Re: [RFC PATCH v2] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-11-12 Thread Qi Liu



On 2020/11/12 1:03, Mathieu Poirier wrote:
> On Wed, Nov 11, 2020 at 04:58:23PM +0800, Qi Liu wrote:
>> Hi Mathieu,
>>
>> On 2020/9/10 0:26, Mathieu Poirier wrote:
>>> On Wed, Sep 09, 2020 at 12:30:02PM +0100, Mike Leach wrote:
>>>> Hi,
>>>>
>>>> On Wed, 2 Sep 2020 at 11:36, Suzuki K Poulose  
>>>> wrote:
>>>>> On 08/27/2020 09:44 PM, Mathieu Poirier wrote:
>>>>>> Hi Liu,
>>>>>>
>>>>>> On Wed, Aug 19, 2020 at 04:06:37PM +0800, Qi Liu wrote:
>>>>>>> When too much trace information is generated on-chip, the ETM will
>>>>>>> overflow, and cause data loss. This is a common phenomenon on ETM
>>>>>>> devices.
>>>>>>>
>>>>>>> But sometimes we do not want to lose performance trace data, so we
>>>>>>> suppress the speed of instructions sent from CPU core to ETM to
>>>>>>> avoid the overflow of ETM.
>>>>>>>
>>>>>>> Signed-off-by: Qi Liu 
>>>>>>> ---
>>>>>>>
>>>>>>> Changes since v1:
>>>>>>> - ETM on HiSilicon Hip09 platform supports backpressure, so does
>>>>>>> not need to modify core commit.
>>>>>>>
>>>>>>>   drivers/hwtracing/coresight/coresight-etm4x.c | 43 
>>>>>>> +++
>>>>>>>   1 file changed, 43 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
>>>>>>> b/drivers/hwtracing/coresight/coresight-etm4x.c
>>>>>>> index 7797a57..7641f89 100644
>>>>>>> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
>>>>>>> @@ -43,6 +43,10 @@ MODULE_PARM_DESC(boot_enable, "Enable tracing on 
>>>>>>> boot");
>>>>>>>   #define PARAM_PM_SAVE_NEVER  1 /* never save any state */
>>>>>>>   #define PARAM_PM_SAVE_SELF_HOSTED 2 /* save self-hosted state only */
>>>>>>>
>>>>>>> +#define CORE_COMMIT_CLEAR   0x3000
>>>>>>> +#define CORE_COMMIT_SHIFT   12
>>>>>>> +#define HISI_ETM_AMBA_ID_V1 0x000b6d01
>>>>>>> +
>>>>>>>   static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
>>>>>>>   module_param(pm_save_enable, int, 0444);
>>>>>>>   MODULE_PARM_DESC(pm_save_enable,
>>>>>>> @@ -104,11 +108,40 @@ struct etm4_enable_arg {
>>>>>>>  int rc;
>>>>>>>   };
>>>>>>>
>>>>>>> +static void etm4_cpu_actlr1_cfg(void *info)
>>>>>>> +{
>>>>>>> +struct etm4_enable_arg *arg = (struct etm4_enable_arg *)info;
>>>>>>> +u64 val;
>>>>>>> +
>>>>>>> +asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
>>>>>
>>>>> The ID register (S3_1_C15_c2_5) falls into implementation defined space.
>>>>> See Arm ARM DDI 0487F.a, section "D12.3.2  Reserved encodings for
>>>>> IMPLEMENTATION DEFINED registers".
>>>>>
>>>>> So, please stop calling this "etm4_cpu_actlr1_cfg". Since,
>>>>> 1) actlr1 is not an architected name for the said encoding
>>>>> 2) The id register could mean something else on another CPU.
>>>>>
>>>>> Rather this should indicate platform/CPU specific. e.g,
>>>>>
>>>>> etm4_cpu_hisilicon_config_core_commit()
>>>>>
>>>>>
>>>>>>> +val &= ~CORE_COMMIT_CLEAR;
>>>>>>> +val |= arg->rc << CORE_COMMIT_SHIFT;
>>>>>>> +asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
>>>>>>> +}
>>>>>>> +
>>>>>>> +static void etm4_config_core_commit(int cpu, int val)
>>>>>>> +{
>>>>>>> +struct etm4_enable_arg arg = {0};
>>>>>>> +
>>>>>>> +arg.rc = val;
>>>>>>> +smp_call_function_single(cpu, etm4_cpu_actlr1_cfg, , 1);
>>>>>> Function etm4_enable/disable_hw() are already running on the CPU the

[PATCH] coresight: Remove unnecessary THIS_MODULE of funnel and replicator driver

2020-11-03 Thread Qi Liu
As THIS_MODULE has been set in platform_driver_register(), so remove it
from static funnel driver and static replicator driver to avoid set it
twice.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-funnel.c | 2 +-
 drivers/hwtracing/coresight/coresight-replicator.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-funnel.c 
b/drivers/hwtracing/coresight/coresight-funnel.c
index af40814..39be46b 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -356,7 +356,7 @@ static struct platform_driver static_funnel_driver = {
.remove  = static_funnel_remove,
.driver = {
.name   = "coresight-static-funnel",
-   .owner  = THIS_MODULE,
+   /* THIS_MODULE is taken care of by platform_driver_register() */
.of_match_table = static_funnel_match,
.acpi_match_table = ACPI_PTR(static_funnel_ids),
.pm = _dev_pm_ops,
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c 
b/drivers/hwtracing/coresight/coresight-replicator.c
index 62afdde..6772f23 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -374,7 +374,7 @@ static struct platform_driver static_replicator_driver = {
.remove = static_replicator_remove,
.driver = {
.name   = "coresight-static-replicator",
-   .owner  = THIS_MODULE,
+   /* THIS_MODULE is taken care of by platform_driver_register() */
.of_match_table = of_match_ptr(static_replicator_match),
.acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
.pm = _dev_pm_ops,
--
2.8.1



Re: [PATCH] coresight: funnel: Remove unnecessary .owner of static funnel driver

2020-11-02 Thread Qi Liu
Hi Mathieu,


On 2020/11/3 1:23, Mathieu Poirier wrote:
> Hi Liu,
>
> On Sat, Oct 31, 2020 at 06:12:30PM +0800, Qi Liu wrote:
>> As driver.owner has been set in platform_driver_register(), it is
>> unnecessary to set it in static funnel driver, so remove it from
>> struct static_funnel_driver.
>>
>> Signed-off-by: Qi Liu 
>> ---
>>  drivers/hwtracing/coresight/coresight-funnel.c | 1 -
>>  1 file changed, 1 deletion(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c 
>> b/drivers/hwtracing/coresight/coresight-funnel.c
>> index af40814..07bc203 100644
>> --- a/drivers/hwtracing/coresight/coresight-funnel.c
>> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
>> @@ -356,7 +356,6 @@ static struct platform_driver static_funnel_driver = {
>>  .remove  = static_funnel_remove,
>>  .driver = {
>>  .name   = "coresight-static-funnel",
>> -.owner  = THIS_MODULE,
> I received two identical patches (with a different title) from you.  Since 
> there
> was no explanation I will discard the first one and work with this one.
>
> You are correct, platform_driver_register() does take care of THIS_MODULE.
> Please send another revision where you will do three things:
>
> 1) CC the coresight mailing list, as instructed by get_maintainer.pl
> 1) Also fix the replicator driver.
> 2) Add a comment that clearly mentions THIS_MODULE doesn't need to be set:
>
> .name   = "coresight-static-funnel",
> /* THIS_MODULE is taken care of by platform_driver_register() 
> */
> .of_match_table = static_funnel_match,
> .acpi_match_table = ACPI_PTR(static_funnel_ids),
> .pm   = _dev_pm_ops,
>
> Thanks,
> Mathieu
Thanks for your review , I'll send a new patch latter.

Liu
>> --
>> 2.8.1
>>
> .
>




[PATCH] coresight: funnel: Remove unnecessary .owner of static funnel driver

2020-10-31 Thread Qi Liu
As driver.owner has been set in platform_driver_register(), it is
unnecessary to set it in static funnel driver, so remove it from
struct static_funnel_driver.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-funnel.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-funnel.c 
b/drivers/hwtracing/coresight/coresight-funnel.c
index af40814..07bc203 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -356,7 +356,6 @@ static struct platform_driver static_funnel_driver = {
.remove  = static_funnel_remove,
.driver = {
.name   = "coresight-static-funnel",
-   .owner  = THIS_MODULE,
.of_match_table = static_funnel_match,
.acpi_match_table = ACPI_PTR(static_funnel_ids),
.pm = _dev_pm_ops,
--
2.8.1



[PATCH] Description: coresight: funnel: Remove unnecessary .owner of static funnel driver

2020-10-31 Thread Qi Liu
As driver.owner has been set in platform_driver_register(), it is
unnecessary to set it in static funnel driver, so remove it from
struct static_funnel_driver.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-funnel.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-funnel.c 
b/drivers/hwtracing/coresight/coresight-funnel.c
index af40814..07bc203 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -356,7 +356,6 @@ static struct platform_driver static_funnel_driver = {
.remove  = static_funnel_remove,
.driver = {
.name   = "coresight-static-funnel",
-   .owner  = THIS_MODULE,
.of_match_table = static_funnel_match,
.acpi_match_table = ACPI_PTR(static_funnel_ids),
.pm = _dev_pm_ops,
--
2.8.1



Re: [PATCH v3] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-10-31 Thread Qi Liu
Hi Suzuki,

On 2020/10/23 18:40, Suzuki Poulose wrote:
> On 10/23/20 11:23 AM, Qi Liu wrote:
>> The ETM device can't keep up with the core pipeline when cpu core
>> is at full speed. This may cause overflow within core and its ETM.
>> This is a common phenomenon on ETM devices.
>>
>> On HiSilicon Hip08 platform, a specific feature is added to set
>> core pipeline. So commit rate can be reduced manually to avoid ETM
>> overflow.
>>
>> Signed-off-by: Qi Liu 
>> ---
>> Change since v1:
>> - add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
>>to keep specific feature off platforms which don't use it.
>> Change since v2:
>> - remove some unused variable.
>>
>>   drivers/hwtracing/coresight/Kconfig| 18 
>>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 50 
>> ++
>>   2 files changed, 68 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/Kconfig 
>> b/drivers/hwtracing/coresight/Kconfig
>> index c119824..9665d70 100644
>> --- a/drivers/hwtracing/coresight/Kconfig
>> +++ b/drivers/hwtracing/coresight/Kconfig
>> @@ -110,6 +110,24 @@ config CORESIGHT_SOURCE_ETM4X
>> To compile this driver as a module, choose M here: the
>> module will be called coresight-etm4x.
>>
>> +config ETM4X_IMPDEF_FEATURE
>> +bool "Control overflow impdef support in CoreSight ETM 4.x driver "
>> +depends on CORESIGHT_SOURCE_ETM4X
>> +help
>> +  This control provides overflow implement define for CoreSight
>> +  ETM 4.x tracer module which could not reduce commit race
>> +  automatically, and could avoid overflow within ETM tracer module
>> +  and its cpu core.
>> +
>> +config ETM4X_IMPDEF_HISILICON
>> +bool "Control overflow impdef support in HiSilicon ETM 4.x driver "
>> +depends on ETM4X_IMPDEF_FEATURE
>> +help
>> +  This control provides overflow implement define for HiSilicon
>> +  ETM 4.x tracer module of Hip08 platform. Overflow within ETM
>> +  tracer module and its cpu core can be avoided by reducing core
>> +  commit manually.
>> +
>>   config CORESIGHT_STM
>>   tristate "CoreSight System Trace Macrocell driver"
>>   depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
>> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index abd706b..35f4333 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -103,12 +103,61 @@ struct etm4_enable_arg {
>>   int rc;
>>   };
>>
>> +#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
>> +
>> +#ifdef CONFIG_ETM4X_IMPDEF_HISILICON
>> +
>> +#define HISI_HIP08_CORE_COMMIT_CLEAR0x3000
>> +#define HISI_HIP08_CORE_COMMIT_SHIFT12
>> +static void etm4_hisi_config_core_commit(int flag)
>
> nit: s/int flag/bool enable ?
thanks, bool is better to use here, will fix this.
>
>> +{
>> +u64 val;
>> +
>> +asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
>> +val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
>> +val |= flag << HISI_HIP08_CORE_COMMIT_SHIFT;
>> +asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
>
> Sorry for missing this out. We don't encourage the above encodings
> as it will break on legacy toolchain. So, please could you follow what
> we do normally, by using sys_reg() macros to define the encoding and use
> read/write_sysreg_s() instead. See arch/arm64/include/asm/sysreg.h
>

ok, I'll use sys_reg() macro here, and send a new version latter, thanks : )
>
>> +}
>> +#else
>> +static void etm4_hisi_config_core_commit(int flag)
>> +{
>> +}
>> +#endif /* CONFIG_ETM4X_IMPDEF_HISILICON */
>> +
>> +static void etm4_enable_arch_specific(void)
>> +{
>> +/*
>> + * If ETM device is HiSilicon ETM device, reduce the
>> + * core-commit to avoid ETM overflow.
>> + */
>> +etm4_hisi_config_core_commit(1);
>> +}
>> +
>> +static void etm4_disable_arch_specific(void)
>> +{
>> +/*
>> + * If ETM device is HiSilicon ETM device, resume the
>> + * core-commit after ETM trace is complete.
>> + */
>> +etm4_hisi_config_core_commit(0);
>> +}
>> +#else
>> +static void etm4_enable_arch_specific(void)
>> +{
>> +}
>> +
>> +static void

[PATCH v3] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-10-23 Thread Qi Liu
The ETM device can't keep up with the core pipeline when cpu core
is at full speed. This may cause overflow within core and its ETM.
This is a common phenomenon on ETM devices.

On HiSilicon Hip08 platform, a specific feature is added to set
core pipeline. So commit rate can be reduced manually to avoid ETM
overflow.

Signed-off-by: Qi Liu 
---
Change since v1:
- add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
  to keep specific feature off platforms which don't use it.
Change since v2:
- remove some unused variable.

 drivers/hwtracing/coresight/Kconfig| 18 
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 50 ++
 2 files changed, 68 insertions(+)

diff --git a/drivers/hwtracing/coresight/Kconfig 
b/drivers/hwtracing/coresight/Kconfig
index c119824..9665d70 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -110,6 +110,24 @@ config CORESIGHT_SOURCE_ETM4X
  To compile this driver as a module, choose M here: the
  module will be called coresight-etm4x.

+config ETM4X_IMPDEF_FEATURE
+   bool "Control overflow impdef support in CoreSight ETM 4.x driver "
+   depends on CORESIGHT_SOURCE_ETM4X
+   help
+ This control provides overflow implement define for CoreSight
+ ETM 4.x tracer module which could not reduce commit race
+ automatically, and could avoid overflow within ETM tracer module
+ and its cpu core.
+
+config ETM4X_IMPDEF_HISILICON
+   bool "Control overflow impdef support in HiSilicon ETM 4.x driver "
+   depends on ETM4X_IMPDEF_FEATURE
+   help
+ This control provides overflow implement define for HiSilicon
+ ETM 4.x tracer module of Hip08 platform. Overflow within ETM
+ tracer module and its cpu core can be avoided by reducing core
+ commit manually.
+
 config CORESIGHT_STM
tristate "CoreSight System Trace Macrocell driver"
depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c 
b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index abd706b..35f4333 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -103,12 +103,61 @@ struct etm4_enable_arg {
int rc;
 };

+#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
+
+#ifdef CONFIG_ETM4X_IMPDEF_HISILICON
+
+#define HISI_HIP08_CORE_COMMIT_CLEAR   0x3000
+#define HISI_HIP08_CORE_COMMIT_SHIFT   12
+static void etm4_hisi_config_core_commit(int flag)
+{
+   u64 val;
+
+   asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
+   val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
+   val |= flag << HISI_HIP08_CORE_COMMIT_SHIFT;
+   asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
+}
+#else
+static void etm4_hisi_config_core_commit(int flag)
+{
+}
+#endif /* CONFIG_ETM4X_IMPDEF_HISILICON */
+
+static void etm4_enable_arch_specific(void)
+{
+   /*
+* If ETM device is HiSilicon ETM device, reduce the
+* core-commit to avoid ETM overflow.
+*/
+   etm4_hisi_config_core_commit(1);
+}
+
+static void etm4_disable_arch_specific(void)
+{
+   /*
+* If ETM device is HiSilicon ETM device, resume the
+* core-commit after ETM trace is complete.
+*/
+   etm4_hisi_config_core_commit(0);
+}
+#else
+static void etm4_enable_arch_specific(void)
+{
+}
+
+static void etm4_disable_arch_specific(void)
+{
+}
+#endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
+
 static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 {
int i, rc;
struct etmv4_config *config = >config;
struct device *etm_dev = >csdev->dev;

+   etm4_enable_arch_specific();
CS_UNLOCK(drvdata->base);

etm4_os_unlock(drvdata);
@@ -475,6 +524,7 @@ static void etm4_disable_hw(void *info)
struct device *etm_dev = >csdev->dev;
int i;

+   etm4_disable_arch_specific();
CS_UNLOCK(drvdata->base);

if (!drvdata->skip_power_up) {
--
2.8.1



[PATCH] drivers/perf: hisi: Fix typo in HiSilicon DDRC driver

2020-09-23 Thread Qi Liu
Fix up typo in function hisi_ddrc_pmu_write_evtype(), and the whitespace
in function hisi_ddrc_pmu_module_exit()

Signed-off-by: Qi Liu 
---
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 5e3645c..e6fe4b8 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -93,7 +93,7 @@ static void hisi_ddrc_pmu_write_counter(struct hisi_pmu 
*ddrc_pmu,
  * For DDRC PMU, event has been mapped to fixed-purpose counter by hardware,
  * so there is no need to write event type.
  */
-static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
+static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *ddrc_pmu, int idx,
   u32 type)
 {
 }
@@ -450,7 +450,6 @@ static void __exit hisi_ddrc_pmu_module_exit(void)
 {
platform_driver_unregister(_ddrc_pmu_driver);
cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE);
-
 }
 module_exit(hisi_ddrc_pmu_module_exit);

--
2.8.1



[PATCH v2] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-09-21 Thread Qi Liu
The ETM device can't keep up with the core pipeline when cpu core
is at full speed. This may cause overflow within core and its ETM.
This is a common phenomenon on ETM devices.

On HiSilicon Hip08 platform, a specific feature is added to set
core pipeline. So commit rate can be reduced manually to avoid ETM
overflow.

Signed-off-by: Qi Liu 
---
Change since v1:
- add CONFIG_ETM4X_IMPDEF_FEATURE and CONFIG_ETM4X_IMPDEF_HISILICON
  to keep specific feature off platforms which don't use it.

 drivers/hwtracing/coresight/Kconfig   | 13 ++
 drivers/hwtracing/coresight/coresight-etm4x.c | 60 +++
 2 files changed, 73 insertions(+)

diff --git a/drivers/hwtracing/coresight/Kconfig 
b/drivers/hwtracing/coresight/Kconfig
index 02dbb5c..362dadf 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -85,6 +85,19 @@ config CORESIGHT_SOURCE_ETM4X
  for instruction level tracing. Depending on the implemented version
  data tracing may also be available.

+config ETM4X_IMPDEF_FEATURE
+   bool "Control overflow impdef support in CoreSight ETM 4.x driver "
+   depends on CORESIGHT_SOURCE_ETM4X
+   help
+ This control provides overflow impdef for CoreSight ETM 4.x driver
+ which can not reduce commit race automatically.
+
+config ETM4X_IMPDEF_HISILICON
+   bool "Control overflow impdef support in HiSilicon ETM 4.x driver "
+   depends on ETM4X_IMPDEF_FEATURE
+   help
+ This control provides overflow impdef for HiSilicon ETM 4.x driver.
+
 config CORESIGHT_STM
bool "CoreSight System Trace Macrocell driver"
depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index f5ab13a..1a7a6c9 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -103,12 +103,71 @@ struct etm4_enable_arg {
int rc;
 };

+#ifdef CONFIG_ETM4X_IMPDEF_FEATURE
+
+#ifdef CONFIG_ETM4X_IMPDEF_HISILICON
+
+#define HISI_HIP08_CORE_COMMIT_CLEAR   0x3000
+#define HISI_HIP08_CORE_COMMIT_SHIFT   12
+static void etm4_hisi_config_core_commit(int flag)
+{
+   u64 val;
+
+   asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
+   val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
+   val |= flag << HISI_HIP08_CORE_COMMIT_SHIFT;
+   asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
+}
+#else
+static void etm4_hisi_config_core_commit(int flag)
+{
+}
+#endif /* CONFIG_ETM4X_IMPDEF_HISILICON */
+
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct device *dev = drvdata->csdev->dev.parent;
+   struct amba_device *adev;
+
+   adev = container_of(dev, struct amba_device, dev);
+
+   /*
+* If ETM device is HiSilicon ETM device, reduce the
+* core-commit to avoid ETM overflow.
+*/
+   etm4_hisi_config_core_commit(1);
+}
+
+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct device *dev = drvdata->csdev->dev.parent;
+   struct amba_device *adev;
+
+   adev = container_of(dev, struct amba_device, dev);
+
+   /*
+* If ETM device is HiSilicon ETM device, resume the
+* core-commit after ETM trace is complete.
+*/
+   etm4_hisi_config_core_commit(0);
+}
+#else
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+}
+
+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+}
+#endif/* CONFIG_ETM4X_IMPDEF_FEATURE */
+
 static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 {
int i, rc;
struct etmv4_config *config = >config;
struct device *etm_dev = >csdev->dev;

+   etm4_enable_arch_specific(drvdata);
CS_UNLOCK(drvdata->base);

etm4_os_unlock(drvdata);
@@ -475,6 +534,7 @@ static void etm4_disable_hw(void *info)
struct device *etm_dev = >csdev->dev;
int i;

+   etm4_disable_arch_specific(drvdata);
CS_UNLOCK(drvdata->base);

if (!drvdata->skip_power_up) {
--
2.8.1



[PATCH V2 RESEND] perf stat: Fix the ratio comments of miss-events

2020-09-16 Thread Qi Liu
Perf stat displays miss ratio of L1-dcache, L1-icache, dTLB cache,
iTLB cache and LL-cache. Take L1-dcache for example, miss ratio is
caculated as "L1-dcache-load-misses/L1-dcache-loads". So
"of all L1-dcache hits" is unsuitable to describe it, and
"of all L1-dcache accesses" seems better.

The comments of L1-icache, dTLB cache, iTLB cache and LL-cache are
fixed in the same way.

Signed-off-by: Qi Liu 
Reviewed-by: Andi Kleen 
---
 tools/perf/util/stat-shadow.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index e1ba6c1..ee3c404 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -517,7 +517,7 @@ static void print_l1_dcache_misses(struct perf_stat_config 
*config,

color = get_ratio_color(GRC_CACHE_MISSES, ratio);

-   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-dcache 
hits", ratio);
+   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-dcache 
accesses", ratio);
 }

 static void print_l1_icache_misses(struct perf_stat_config *config,
@@ -538,7 +538,7 @@ static void print_l1_icache_misses(struct perf_stat_config 
*config,
ratio = avg / total * 100.0;

color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-icache 
hits", ratio);
+   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-icache 
accesses", ratio);
 }

 static void print_dtlb_cache_misses(struct perf_stat_config *config,
@@ -558,7 +558,7 @@ static void print_dtlb_cache_misses(struct perf_stat_config 
*config,
ratio = avg / total * 100.0;

color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all dTLB 
cache hits", ratio);
+   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all dTLB 
cache accesses", ratio);
 }

 static void print_itlb_cache_misses(struct perf_stat_config *config,
@@ -578,7 +578,7 @@ static void print_itlb_cache_misses(struct perf_stat_config 
*config,
ratio = avg / total * 100.0;

color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all iTLB 
cache hits", ratio);
+   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all iTLB 
cache accesses", ratio);
 }

 static void print_ll_cache_misses(struct perf_stat_config *config,
@@ -598,7 +598,7 @@ static void print_ll_cache_misses(struct perf_stat_config 
*config,
ratio = avg / total * 100.0;

color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all LL-cache 
hits", ratio);
+   out->print_metric(config, out->ctx, color, "%7.2f%%", "of all LL-cache 
accesses", ratio);
 }

 /*
@@ -918,7 +918,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config 
*config,
if (runtime_stat_n(st, STAT_L1_DCACHE, ctx, cpu) != 0)
print_l1_dcache_misses(config, cpu, evsel, avg, out, 
st);
else
-   print_metric(config, ctxp, NULL, NULL, "of all 
L1-dcache hits", 0);
+   print_metric(config, ctxp, NULL, NULL, "of all 
L1-dcache accesses", 0);
} else if (
evsel->core.attr.type == PERF_TYPE_HW_CACHE &&
evsel->core.attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
@@ -928,7 +928,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config 
*config,
if (runtime_stat_n(st, STAT_L1_ICACHE, ctx, cpu) != 0)
print_l1_icache_misses(config, cpu, evsel, avg, out, 
st);
else
-   print_metric(config, ctxp, NULL, NULL, "of all 
L1-icache hits", 0);
+   print_metric(config, ctxp, NULL, NULL, "of all 
L1-icache accesses", 0);
} else if (
evsel->core.attr.type == PERF_TYPE_HW_CACHE &&
evsel->core.attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
@@ -938,7 +938,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config 
*config,
if (runtime_stat_n(st, STAT_DTLB_CACHE, ctx, cpu) != 0)
print_dtlb_cache_misses(config, cpu, evsel, avg, out, 
st);
else
-   print_metric(config, ctxp, NULL, NULL, "of all dTLB 
cache hits", 0);
+   print_metric(config, ctxp, NULL, NULL, "of all dTLB 
cache accesses", 0);
} else 

[PATCH] mm/madvise.c: Remove the unused variable in function madvise_inject_error

2020-09-14 Thread Qi Liu
Variable zone is unused in function madvise_inject_error, let's remove it.

Signed-off-by: Qi Liu 
---
 mm/madvise.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mm/madvise.c b/mm/madvise.c
index 460e19d..94b9d17 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -879,7 +879,6 @@ static long madvise_remove(struct vm_area_struct *vma,
 static int madvise_inject_error(int behavior,
unsigned long start, unsigned long end)
 {
-   struct zone *zone;
unsigned long size;

if (!capable(CAP_SYS_ADMIN))
--
2.8.1



[PATCH] coresight: Don't allocate pdata->conns when there is no output port

2020-09-08 Thread Qi Liu
When there is no output port, coresight_alloc_conns() still do the following
copy connection information to pdata->conns, and this may cause kernel panic.
Let's fix it.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-platform.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-platform.c 
b/drivers/hwtracing/coresight/coresight-platform.c
index bfd4423..cdc8824 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -26,12 +26,13 @@
 static int coresight_alloc_conns(struct device *dev,
 struct coresight_platform_data *pdata)
 {
-   if (pdata->nr_outport) {
-   pdata->conns = devm_kcalloc(dev, pdata->nr_outport,
-   sizeof(*pdata->conns), GFP_KERNEL);
-   if (!pdata->conns)
-   return -ENOMEM;
-   }
+   if (!pdata->nr_outport)
+   return -ENOMEM;
+
+   pdata->conns = devm_kcalloc(dev, pdata->nr_outport,
+   sizeof(*pdata->conns), GFP_KERNEL);
+   if (!pdata->conns)
+   return -ENOMEM;

return 0;
 }
--
2.8.1



[PATCH] arm64: perf: Remove unnecessary event_idx check

2020-09-04 Thread Qi Liu
event_idx is obtained from armv8pmu_get_event_idx(), and this idx must be
between ARMV8_IDX_CYCLE_COUNTER and cpu_pmu->num_events. So it's unnecessary
to do this check. Let's remove it.

Signed-off-by: Qi Liu 
---
 arch/arm64/kernel/perf_event.c | 20 ++--
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 462f9a9..885a357 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -307,8 +307,6 @@ static struct attribute_group armv8_pmuv3_format_attr_group 
= {
  */
 #defineARMV8_IDX_CYCLE_COUNTER 0
 #defineARMV8_IDX_COUNTER0  1
-#defineARMV8_IDX_COUNTER_LAST(cpu_pmu) \
-   (ARMV8_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)


 /*
@@ -365,12 +363,6 @@ static inline int armv8pmu_has_overflowed(u32 pmovsr)
return pmovsr & ARMV8_PMU_OVERFLOWED_MASK;
 }

-static inline int armv8pmu_counter_valid(struct arm_pmu *cpu_pmu, int idx)
-{
-   return idx >= ARMV8_IDX_CYCLE_COUNTER &&
-   idx <= ARMV8_IDX_COUNTER_LAST(cpu_pmu);
-}
-
 static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx)
 {
return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx));
@@ -440,15 +432,11 @@ static u64 armv8pmu_unbias_long_counter(struct perf_event 
*event, u64 value)

 static u64 armv8pmu_read_counter(struct perf_event *event)
 {
-   struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
struct hw_perf_event *hwc = >hw;
int idx = hwc->idx;
u64 value = 0;

-   if (!armv8pmu_counter_valid(cpu_pmu, idx))
-   pr_err("CPU%u reading wrong counter %d\n",
-   smp_processor_id(), idx);
-   else if (idx == ARMV8_IDX_CYCLE_COUNTER)
+   if (idx == ARMV8_IDX_CYCLE_COUNTER)
value = read_sysreg(pmccntr_el0);
else
value = armv8pmu_read_hw_counter(event);
@@ -477,16 +465,12 @@ static inline void armv8pmu_write_hw_counter(struct 
perf_event *event,

 static void armv8pmu_write_counter(struct perf_event *event, u64 value)
 {
-   struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
struct hw_perf_event *hwc = >hw;
int idx = hwc->idx;

value = armv8pmu_bias_long_counter(event, value);

-   if (!armv8pmu_counter_valid(cpu_pmu, idx))
-   pr_err("CPU%u writing wrong counter %d\n",
-   smp_processor_id(), idx);
-   else if (idx == ARMV8_IDX_CYCLE_COUNTER)
+   if (idx == ARMV8_IDX_CYCLE_COUNTER)
write_sysreg(value, pmccntr_el0);
else
armv8pmu_write_hw_counter(event, value);
--
2.8.1



[PATCH] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-09-03 Thread Qi Liu
The ETM device can't keep up with the core pipeline when cpu core
is at full speed. This may cause overflow within core and its ETM.
This is a common phenomenon on ETM devices.

On HiSilicon Hip08 platform, a specific feature is added to set
core pipeline. So commit rate can be reduced manually to avoid ETM
overflow.

Signed-off-by: Qi Liu 
---
link of the RFC patch:
https://lore.kernel.org/linux-arm-kernel/1597824397-29894-1-git-send-email-liuqi...@huawei.com/

drivers/hwtracing/coresight/coresight-etm4x.c | 46 +++
 1 file changed, 46 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 7bcac88..5833be1 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -45,6 +45,10 @@ static int etm4_set_event_filters(struct etmv4_drvdata 
*drvdata,

 static enum cpuhp_state hp_online;

+#define HISI_HIP08_CORE_COMMIT_CLEAR   0x3000
+#define HISI_HIP08_CORE_COMMIT_SHIFT   12
+#define HISI_HIP08_ETM_ID  0x000b6d01
+
 static void etm4_os_unlock(struct etmv4_drvdata *drvdata)
 {
/* Writing any value to ETMOSLAR unlocks the trace registers */
@@ -84,12 +88,38 @@ struct etm4_enable_arg {
int rc;
 };

+static void etm4_hisi_config_core_commit(int flag)
+{
+   u64 val;
+
+   asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
+   val &= ~HISI_HIP08_CORE_COMMIT_CLEAR;
+   val |= flag << HISI_HIP08_CORE_COMMIT_SHIFT;
+   asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
+}
+
+static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct device *dev = drvdata->csdev->dev.parent;
+   struct amba_device *adev;
+
+   adev = container_of(dev, struct amba_device, dev);
+
+   /*
+* If ETM device is HiSilicon ETM device, reduce the
+* core-commit to avoid ETM overflow.
+*/
+   if (adev->periphid == HISI_HIP08_ETM_ID)
+   etm4_hisi_config_core_commit(1);
+}
+
 static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 {
int i, rc;
struct etmv4_config *config = >config;
struct device *etm_dev = >csdev->dev;

+   etm4_enable_arch_specific(drvdata);
CS_UNLOCK(drvdata->base);

etm4_os_unlock(drvdata);
@@ -436,11 +466,27 @@ static int etm4_enable(struct coresight_device *csdev,
return ret;
 }

+static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
+{
+   struct device *dev = drvdata->csdev->dev.parent;
+   struct amba_device *adev;
+
+   adev = container_of(dev, struct amba_device, dev);
+
+   /*
+* If ETM device is HiSilicon ETM device, resume the
+* core-commit after ETM trace is complete.
+*/
+   if (adev->periphid == HISI_HIP08_ETM_ID)
+   etm4_hisi_config_core_commit(0);
+}
+
 static void etm4_disable_hw(void *info)
 {
u32 control;
struct etmv4_drvdata *drvdata = info;

+   etm4_disable_arch_specific(drvdata);
CS_UNLOCK(drvdata->base);

/* power can be removed from the trace unit now */
--
2.8.1



Re: [RFC PATCH v2] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-08-31 Thread Qi Liu
Hi Mathieu,

Thanks for your review.

On 2020/9/1 6:13, Mathieu Poirier wrote:
> Following Al's comment I have the following recommendations...
>
> On Wed, Aug 19, 2020 at 04:06:37PM +0800, Qi Liu wrote:
>> When too much trace information is generated on-chip, the ETM will
>> overflow, and cause data loss. This is a common phenomenon on ETM
>> devices.
>>
>> But sometimes we do not want to lose performance trace data, so we
>> suppress the speed of instructions sent from CPU core to ETM to
>> avoid the overflow of ETM.
>>
>> Signed-off-by: Qi Liu 
>> ---
>>
>> Changes since v1:
>> - ETM on HiSilicon Hip09 platform supports backpressure, so does
>> not need to modify core commit.
>>
>>  drivers/hwtracing/coresight/coresight-etm4x.c | 43 
>> +++
>>  1 file changed, 43 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
>> b/drivers/hwtracing/coresight/coresight-etm4x.c
>> index 7797a57..7641f89 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
>> @@ -43,6 +43,10 @@ MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
>>  #define PARAM_PM_SAVE_NEVER   1 /* never save any state */
>>  #define PARAM_PM_SAVE_SELF_HOSTED 2 /* save self-hosted state only */
>>
>> +#define CORE_COMMIT_CLEAR   0x3000
>> +#define CORE_COMMIT_SHIFT   12
>> +#define HISI_ETM_AMBA_ID_V1 0x000b6d01
> Do you have a name for the SoC that can be added so that other HiSilicon SoC 
> can
> be added?  I suggest something like:
>
> #define HISI_NAME_CORE_COMMIT_CLEAR
> #define HISI_NAME_CORE_COMMIT_SHIFT
> #define HISI_NAME_ETM_ID
Will fix this next version.
> Moreover I don't see an entry for 0x000b6d01 in the amba id table - is your
> devices upstream?  Needless to day that is mandatory in order to move forward
> with this work.
A patch has been applied to add this ETM id and here is the link:
https://lore.kernel.org/linux-arm-kernel/2020081321.GO3393195@xps15/

>> +
>>  static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
>>  module_param(pm_save_enable, int, 0444);
>>  MODULE_PARM_DESC(pm_save_enable,
>> @@ -104,11 +108,40 @@ struct etm4_enable_arg {
>>  int rc;
>>  };
>>
>> +static void etm4_cpu_actlr1_cfg(void *info)
>> +{
>> +struct etm4_enable_arg *arg = (struct etm4_enable_arg *)info;
>> +u64 val;
>> +
>> +asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
>> +val &= ~CORE_COMMIT_CLEAR;
>> +val |= arg->rc << CORE_COMMIT_SHIFT;
>> +asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
>> +}
>> +
>> +static void etm4_config_core_commit(int cpu, int val)
>> +{
>> +struct etm4_enable_arg arg = {0};
>> +
>> +arg.rc = val;
>> +smp_call_function_single(cpu, etm4_cpu_actlr1_cfg, , 1);
>> +}
>> +
>>  static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
>>  {
>>  int i, rc;
>> +struct amba_device *adev;
>>  struct etmv4_config *config = >config;
>>  struct device *etm_dev = >csdev->dev;
>> +struct device *dev = drvdata->csdev->dev.parent;
>> +
>> +adev = container_of(dev, struct amba_device, dev);
>> +/*
>> + * If ETM device is HiSilicon ETM device, reduce the
>> + * core-commit to avoid ETM overflow.
>> + */
>> +if (adev->periphid == HISI_ETM_AMBA_ID_V1)
>> +etm4_config_core_commit(drvdata->cpu, 1);
> I susggest to add a function like etm4_enable_arch_specific() and do the above
> in there.  The same goes for the disable path.
>
> Thanks,
> Mathieu
Thanks, I'll fix this next version : )

Qi
>
>>  CS_UNLOCK(drvdata->base);
>>
>> @@ -472,10 +505,20 @@ static void etm4_disable_hw(void *info)
>>  {
>>  u32 control;
>>  struct etmv4_drvdata *drvdata = info;
>> +struct device *dev = drvdata->csdev->dev.parent;
>>  struct etmv4_config *config = >config;
>>  struct device *etm_dev = >csdev->dev;
>> +struct amba_device *adev;
>>  int i;
>>
>> +adev = container_of(dev, struct amba_device, dev);
>> +/*
>> + * If ETM device is HiSilicon ETM device, resume the
>> + * core-commit after ETM trace is complete.
>> + */
>> +if (adev->periphid == HISI_ETM_AMBA_ID_V1)
>> +etm4_config_core_commit(drvdata->cpu, 0);
>> +
>>  CS_UNLOCK(drvdata->base);
>>
>>  if (!drvdata->skip_power_up) {
>> --
>> 2.8.1
>>
> .
>




Re: [RFC PATCH v2] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-08-31 Thread Qi Liu
Hi Al,

On 2020/8/28 17:00, Al Grant wrote:
> Hi Mathieu and CS maintainers,
>
>> Hi Liu,
>>
>> On Wed, Aug 19, 2020 at 04:06:37PM +0800, Qi Liu wrote:
>>> When too much trace information is generated on-chip, the ETM will
>>> overflow, and cause data loss. This is a common phenomenon on ETM
>>> devices.
>>>
>>> But sometimes we do not want to lose performance trace data, so we
>>> suppress the speed of instructions sent from CPU core to ETM to avoid
>>> the overflow of ETM.
>>>
>>> Signed-off-by: Qi Liu 
>>> ---
>>>
>>> Changes since v1:
>>> - ETM on HiSilicon Hip09 platform supports backpressure, so does not
>>> need to modify core commit.
>>>
>>>  drivers/hwtracing/coresight/coresight-etm4x.c | 43
>>> +++
>>>  1 file changed, 43 insertions(+)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c
>>> b/drivers/hwtracing/coresight/coresight-etm4x.c
>>> index 7797a57..7641f89 100644
>>> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
>>> @@ -43,6 +43,10 @@ MODULE_PARM_DESC(boot_enable, "Enable tracing
>> on boot");
>>>  #define PARAM_PM_SAVE_NEVER  1 /* never save any state */
>>>  #define PARAM_PM_SAVE_SELF_HOSTED 2 /* save self-hosted state only */
>>>
>>> +#define CORE_COMMIT_CLEAR  0x3000
>>> +#define CORE_COMMIT_SHIFT  12
>>> +#define HISI_ETM_AMBA_ID_V10x000b6d01
>>> +
>>>  static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
>>> module_param(pm_save_enable, int, 0444);
>>> MODULE_PARM_DESC(pm_save_enable, @@ -104,11 +108,40 @@ struct
>>> etm4_enable_arg {
>>> int rc;
>>>  };
>>>
>>> +static void etm4_cpu_actlr1_cfg(void *info) {
>>> +   struct etm4_enable_arg *arg = (struct etm4_enable_arg *)info;
>>> +   u64 val;
>>> +
>>> +   asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
>>> +   val &= ~CORE_COMMIT_CLEAR;
>>> +   val |= arg->rc << CORE_COMMIT_SHIFT;
>>> +   asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val)); }
>>> +
>>> +static void etm4_config_core_commit(int cpu, int val) {
>>> +   struct etm4_enable_arg arg = {0};
>>> +
>>> +   arg.rc = val;
>>> +   smp_call_function_single(cpu, etm4_cpu_actlr1_cfg, , 1);
>> Function etm4_enable/disable_hw() are already running on the CPU they are
>> supposed to so no need to call smp_call_function_single().
>>
>>> +}
>>> +
>>>  static int etm4_enable_hw(struct etmv4_drvdata *drvdata)  {
>>> int i, rc;
>>> +   struct amba_device *adev;
>>> struct etmv4_config *config = >config;
>>> struct device *etm_dev = >csdev->dev;
>>> +   struct device *dev = drvdata->csdev->dev.parent;
>>> +
>>> +   adev = container_of(dev, struct amba_device, dev);
>>> +   /*
>>> +* If ETM device is HiSilicon ETM device, reduce the
>>> +* core-commit to avoid ETM overflow.
>>> +*/
>>> +   if (adev->periphid == HISI_ETM_AMBA_ID_V1)
>> Do you have any documentation on this back pressure feature?  I doubt this is
>> specific to Hip09 platform and as such would prefer to have a more generic
>> approach that works on any platform that supports it.
> It's not a standard Arm architecture feature, this is a model-specific 
> register.
> Some cores may be able to throttle throughput under user control,
> but this isn't standardized. It may (as in this case) be something that you
> want to enable whenever you enable ETM - and, I guess, disable whenever
> you disable ETM. It's a bit unclean to have model-specific code in the main
> ETM driver, and names like CORE_COMMIT_CLEAR really ought to be more
> specific, but I don't see that it's more ugly than the model-specific code in
> e.g. arch/arm64/kernel/perf_event.c or its equivalent on other architectures.
Thanks for the review. 
Yes, this core commit is a specific feature to reduce commit rate and let ETM 
keep up
with core pipeline. Considering this, I'll change a more specific name for the 
macro
definition and send a new version.

Qi
> Ideally, a core that has an inherent difficulty generating ETM at full speed,
> i.e. where the ETM can't keep up with the core pipeline, would reduce
> commit rate automatically, and some already do. So if this core needs it
> to be done manually via a system register, we might all

[RFC PATCH v2] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-08-19 Thread Qi Liu
When too much trace information is generated on-chip, the ETM will
overflow, and cause data loss. This is a common phenomenon on ETM
devices.

But sometimes we do not want to lose performance trace data, so we
suppress the speed of instructions sent from CPU core to ETM to
avoid the overflow of ETM.

Signed-off-by: Qi Liu 
---

Changes since v1:
- ETM on HiSilicon Hip09 platform supports backpressure, so does
not need to modify core commit.

 drivers/hwtracing/coresight/coresight-etm4x.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 7797a57..7641f89 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -43,6 +43,10 @@ MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
 #define PARAM_PM_SAVE_NEVER  1 /* never save any state */
 #define PARAM_PM_SAVE_SELF_HOSTED 2 /* save self-hosted state only */

+#define CORE_COMMIT_CLEAR  0x3000
+#define CORE_COMMIT_SHIFT  12
+#define HISI_ETM_AMBA_ID_V10x000b6d01
+
 static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
 module_param(pm_save_enable, int, 0444);
 MODULE_PARM_DESC(pm_save_enable,
@@ -104,11 +108,40 @@ struct etm4_enable_arg {
int rc;
 };

+static void etm4_cpu_actlr1_cfg(void *info)
+{
+   struct etm4_enable_arg *arg = (struct etm4_enable_arg *)info;
+   u64 val;
+
+   asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
+   val &= ~CORE_COMMIT_CLEAR;
+   val |= arg->rc << CORE_COMMIT_SHIFT;
+   asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
+}
+
+static void etm4_config_core_commit(int cpu, int val)
+{
+   struct etm4_enable_arg arg = {0};
+
+   arg.rc = val;
+   smp_call_function_single(cpu, etm4_cpu_actlr1_cfg, , 1);
+}
+
 static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 {
int i, rc;
+   struct amba_device *adev;
struct etmv4_config *config = >config;
struct device *etm_dev = >csdev->dev;
+   struct device *dev = drvdata->csdev->dev.parent;
+
+   adev = container_of(dev, struct amba_device, dev);
+   /*
+* If ETM device is HiSilicon ETM device, reduce the
+* core-commit to avoid ETM overflow.
+*/
+   if (adev->periphid == HISI_ETM_AMBA_ID_V1)
+   etm4_config_core_commit(drvdata->cpu, 1);

CS_UNLOCK(drvdata->base);

@@ -472,10 +505,20 @@ static void etm4_disable_hw(void *info)
 {
u32 control;
struct etmv4_drvdata *drvdata = info;
+   struct device *dev = drvdata->csdev->dev.parent;
struct etmv4_config *config = >config;
struct device *etm_dev = >csdev->dev;
+   struct amba_device *adev;
int i;

+   adev = container_of(dev, struct amba_device, dev);
+   /*
+* If ETM device is HiSilicon ETM device, resume the
+* core-commit after ETM trace is complete.
+*/
+   if (adev->periphid == HISI_ETM_AMBA_ID_V1)
+   etm4_config_core_commit(drvdata->cpu, 0);
+
CS_UNLOCK(drvdata->base);

if (!drvdata->skip_power_up) {
--
2.8.1



[PATCH v2] coresight: etm4x: Add Support for HiSilicon ETM device

2020-08-13 Thread Qi Liu
Add ETMv4 periperhal ID for HiSilicon Hip08 and Hip09 platform. Hip08
contains ETMv4.2 device and Hip09 contains ETMv4.5 device.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 6d7d216..7797a57 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1587,6 +1587,8 @@ static const struct amba_id etm4_ids[] = {
CS_AMBA_UCI_ID(0x000bb805, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A55 
*/
CS_AMBA_UCI_ID(0x000bb804, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A76 
*/
CS_AMBA_UCI_ID(0x000cc0af, uci_id_etm4),/* Marvell ThunderX2 */
+   CS_AMBA_UCI_ID(0x000b6d01, uci_id_etm4),/* HiSilicon-Hip08 */
+   CS_AMBA_UCI_ID(0x000b6d02, uci_id_etm4),/* HiSilicon-Hip09 */
{},
 };

--
2.8.1



Re: [PATCH] coresight: etm4x: Add Support for HiSilicon ETM device

2020-08-10 Thread Qi Liu
Hi Suzuki,
Thanks for your review.

On 2020/8/4 18:47, Suzuki K Poulose wrote:
> Hi Qi
> 
> On 08/03/2020 02:35 PM, Qi Liu wrote:
>> Add ETMv4 periperhal ID for HiSilicon Hip08 and Hip09 platform. Hip08
>> contains ETMv4.2 device and Hip09 contains ETMv4.5 device.
> 
> Does the ETMv4.5 on your system implement system instructions to access
> the ETMs ? If so, please could you give the following series on your
> board ?
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2020-July/587745.html
> 

ETMv4.5 on Hip09 platform does not support system instructions.
> 
>>
>> Signed-off-by: Qi Liu 
>> ---
>>   drivers/hwtracing/coresight/coresight-etm4x.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
>> b/drivers/hwtracing/coresight/coresight-etm4x.c
>> index 0c35cd5e..4a4f0bd 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
>> @@ -1561,6 +1561,8 @@ static struct amba_cs_uci_id uci_id_etm4[] = {
>>   };
>>
>>   static const struct amba_id etm4_ids[] = {
>> +CS_AMBA_ID(0x000b6d02),/* HiSilicon-Hip09 */
>> +CS_AMBA_ID(0x000b6d01),/* HiSilicon-Hip08 */
> 
> Please use CS_AMBA_UCI_ID() instead.
> 
> We should stop using the CS_AMBA_ID()
> 
ok, I'll fix this in next version.

Thanks,
Qi
> 
> Suzuki
> 
> .
> 



[PATCH] coresight: etm4x: Modify core-commit of cpu to avoid the overflow of HiSilicon ETM

2020-08-03 Thread Qi Liu
When too much trace information is generated on-chip, the ETM will
overflow, and may cause data loss. This is a common phenomenon on
ETM devices.

But sometimes we do not want to lose any performance trace data, so
we suppress the speed of instructions sent from CPU core to ETM to
avoid the overflow of ETM.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 46 +++
 1 file changed, 46 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 4a4f0bd..ca9fb11 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -43,6 +43,11 @@ MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
 #define PARAM_PM_SAVE_NEVER  1 /* never save any state */
 #define PARAM_PM_SAVE_SELF_HOSTED 2 /* save self-hosted state only */

+#define CORE_COMMIT_CLEAR  0x3000
+#define CORE_COMMIT_SHIFT  12
+#define HISI_ETM_AMBA_ID_V10x000b6d01
+#define HISI_ETM_AMBA_ID_V20x000b6d02
+
 static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
 module_param(pm_save_enable, int, 0444);
 MODULE_PARM_DESC(pm_save_enable,
@@ -104,11 +109,41 @@ struct etm4_enable_arg {
int rc;
 };

+static void etm4_cpu_actlr1_cfg(void *info)
+{
+   struct etm4_enable_arg *arg = (struct etm4_enable_arg *)info;
+   u64 val;
+
+   asm volatile("mrs %0,s3_1_c15_c2_5" : "=r"(val));
+   val &= ~CORE_COMMIT_CLEAR;
+   val |= arg->rc << CORE_COMMIT_SHIFT;
+   asm volatile("msr s3_1_c15_c2_5,%0" : : "r"(val));
+}
+
+static void etm4_config_core_commit(int cpu, int val)
+{
+   struct etm4_enable_arg arg = {0};
+
+   arg.rc = val;
+   smp_call_function_single(cpu, etm4_cpu_actlr1_cfg, , 1);
+}
+
 static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 {
int i, rc;
+   struct amba_device *adev;
struct etmv4_config *config = >config;
struct device *etm_dev = >csdev->dev;
+   struct device *dev = drvdata->csdev->dev.parent;
+
+   adev = container_of(dev, struct amba_device, dev);
+   /*
+* If ETM device is HiSilicon ETM device, reduce the
+* core-commit to avoid ETM overflow.
+*/
+   if (adev->periphid == HISI_ETM_AMBA_ID_V1 ||
+   adev->periphid == HISI_ETM_AMBA_ID_V2)
+   etm4_config_core_commit(drvdata->cpu, 1);

CS_UNLOCK(drvdata->base);

@@ -469,11 +504,22 @@ static int etm4_enable(struct coresight_device *csdev,
 static void etm4_disable_hw(void *info)
 {
u32 control;
+   struct amba_device *adev;
struct etmv4_drvdata *drvdata = info;
struct etmv4_config *config = >config;
struct device *etm_dev = >csdev->dev;
+   struct device *dev = drvdata->csdev->dev.parent;
int i;

+   adev = container_of(dev, struct amba_device, dev);
+   /*
+* If ETM device is HiSilicon ETM device, resume the
+* core-commit after ETM trace is complete.
+*/
+   if (adev->periphid == HISI_ETM_AMBA_ID_V1 ||
+   adev->periphid == HISI_ETM_AMBA_ID_V2)
+   etm4_config_core_commit(drvdata->cpu, 0);
+
CS_UNLOCK(drvdata->base);

/* power can be removed from the trace unit now */
--
2.8.1



[PATCH] coresight: etm4x: Add Support for HiSilicon ETM device

2020-08-03 Thread Qi Liu
Add ETMv4 periperhal ID for HiSilicon Hip08 and Hip09 platform. Hip08
contains ETMv4.2 device and Hip09 contains ETMv4.5 device.

Signed-off-by: Qi Liu 
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 0c35cd5e..4a4f0bd 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1561,6 +1561,8 @@ static struct amba_cs_uci_id uci_id_etm4[] = {
 };

 static const struct amba_id etm4_ids[] = {
+   CS_AMBA_ID(0x000b6d02), /* HiSilicon-Hip09 */
+   CS_AMBA_ID(0x000b6d01), /* HiSilicon-Hip08 */
CS_AMBA_ID(0x000bb95d), /* Cortex-A53 */
CS_AMBA_ID(0x000bb95e), /* Cortex-A57 */
CS_AMBA_ID(0x000bb95a), /* Cortex-A72 */
--
2.8.1



[PATCH] drivers/perf: Prevent forced unbinding of PMU drivers

2020-07-17 Thread Qi Liu
Forcefully unbinding PMU drivers during perf sampling will lead to
a kernel panic, because the perf upper-layer framework call a NULL
pointer in this situation.

To solve this issue, "suppress_bind_attrs" should be set to true, so
that bind/unbind can be disabled via sysfs and prevent unbinding PMU
drivers during perf sampling.

Signed-off-by: Qi Liu 
Reviewed-by: John Garry 
---
 drivers/perf/arm-cci.c| 1 +
 drivers/perf/arm-ccn.c| 1 +
 drivers/perf/arm_dsu_pmu.c| 1 +
 drivers/perf/arm_smmuv3_pmu.c | 1 +
 drivers/perf/arm_spe_pmu.c| 1 +
 drivers/perf/fsl_imx8_ddr_perf.c  | 1 +
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 +
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 1 +
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  | 1 +
 drivers/perf/qcom_l2_pmu.c| 1 +
 drivers/perf/qcom_l3_pmu.c| 1 +
 drivers/perf/thunderx2_pmu.c  | 1 +
 drivers/perf/xgene_pmu.c  | 1 +
 13 files changed, 13 insertions(+)

diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index 1b8e337..87c4be9 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1718,6 +1718,7 @@ static struct platform_driver cci_pmu_driver = {
.driver = {
   .name = DRIVER_NAME,
   .of_match_table = arm_cci_pmu_matches,
+  .suppress_bind_attrs = true,
  },
.probe = cci_pmu_probe,
.remove = cci_pmu_remove,
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index d50edef..7b7d23f 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -1545,6 +1545,7 @@ static struct platform_driver arm_ccn_driver = {
.driver = {
.name = "arm-ccn",
.of_match_table = arm_ccn_match,
+   .suppress_bind_attrs = true,
},
.probe = arm_ccn_probe,
.remove = arm_ccn_remove,
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 518d060..96ed93c 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -757,6 +757,7 @@ static struct platform_driver dsu_pmu_driver = {
.driver = {
.name   = DRVNAME,
.of_match_table = of_match_ptr(dsu_pmu_of_match),
+   .suppress_bind_attrs = true,
},
.probe = dsu_pmu_device_probe,
.remove = dsu_pmu_device_remove,
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index 90caba56..4cdb35d 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -860,6 +860,7 @@ static void smmu_pmu_shutdown(struct platform_device *pdev)
 static struct platform_driver smmu_pmu_driver = {
.driver = {
.name = "arm-smmu-v3-pmcg",
+   .suppress_bind_attrs = true,
},
.probe = smmu_pmu_probe,
.remove = smmu_pmu_remove,
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index d80f487..e51ddb6 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -1226,6 +1226,7 @@ static struct platform_driver arm_spe_pmu_driver = {
.driver = {
.name   = DRVNAME,
.of_match_table = of_match_ptr(arm_spe_pmu_of_match),
+   .suppress_bind_attrs = true,
},
.probe  = arm_spe_pmu_device_probe,
.remove = arm_spe_pmu_device_remove,
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 2aed2d9..397540a 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -707,6 +707,7 @@ static struct platform_driver imx_ddr_pmu_driver = {
.driver = {
.name   = "imx-ddr-pmu",
.of_match_table = imx_ddr_pmu_dt_ids,
+   .suppress_bind_attrs = true,
},
.probe  = ddr_perf_probe,
.remove = ddr_perf_remove,
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 71587f1..5e3645c 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -419,6 +419,7 @@ static struct platform_driver hisi_ddrc_pmu_driver = {
.driver = {
.name = "hisi_ddrc_pmu",
.acpi_match_table = ACPI_PTR(hisi_ddrc_pmu_acpi_match),
+   .suppress_bind_attrs = true,
},
.probe = hisi_ddrc_pmu_probe,
.remove = hisi_ddrc_pmu_remove,
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index c199de7..5eb8168 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -431,6 +431,7 @@ static struct platform_driver hisi_hha_pmu_dr

[PATCH] drivers/perf: Fix kernel panic when rmmod PMU modules during perf sampling

2020-07-16 Thread Qi Liu
When users try to remove PMU modules during perf sampling, kernel panic
will happen because the pmu->read() is a NULL pointer here.

INFO on HiSilicon hip08 platform as follow:
pc : hisi_uncore_pmu_event_update+0x30/0xa4 [hisi_uncore_pmu]
lr : hisi_uncore_pmu_read+0x20/0x2c [hisi_uncore_pmu]
sp : 800010103e90
x29: 800010103e90 x28: 0027db0c0e40
x27: a29a76f129d8 x26: a29a77ceb000
x25: a29a773a5000 x24: a29a77392000
x23: ddffe5943f08 x22: 002784285960
x21: 002784285800 x20: 0027d2e76c80
x19: 0027842859e0 x18: 80003498bcc8
x17: a29a76afe910 x16: a29a7583f530
x15: 16151a1512061a1e x14: 
x13: a29a76f1e238 x12: 0001
x11: 0400 x10: 09f0
x9 : 8000107b3e70 x8 : 0027db0c1890
x7 : a29a773a7000 x6 : 0007f5131013
x5 : 0007f5131013 x4 : 09f257d417c0
x3 : 0002187bd7ce x2 : a29a38f0f0d8
x1 : a29a38eae268 x0 : 0027d2e76c80
Call trace:
hisi_uncore_pmu_event_update+0x30/0xa4 [hisi_uncore_pmu]
hisi_uncore_pmu_read+0x20/0x2c [hisi_uncore_pmu]
__perf_event_read+0x1a0/0x1f8
flush_smp_call_function_queue+0xa0/0x160
generic_smp_call_function_single_interrupt+0x18/0x20
handle_IPI+0x31c/0x4dc
gic_handle_irq+0x2c8/0x310
el1_irq+0xcc/0x180
arch_cpu_idle+0x4c/0x20c
default_idle_call+0x20/0x30
do_idle+0x1b4/0x270
cpu_startup_entry+0x28/0x30
secondary_start_kernel+0x1a4/0x1fc

To solve the above issue, current module should be registered to kernel,
so that try_module_get() can be invoked when perf sampling starts. This
adds the reference counting of module and could prevent users from removing
modules during sampling.

Signed-off-by: Qi Liu 
Reported-by: Haifeng Wang 
Reviewed-by: John Garry 
---
Kernel panic will also happen when users try to unbind PMU drivers with
device. This unbind issue could be solved by another patch latter.

 drivers/perf/arm_smmuv3_pmu.c | 1 +
 drivers/perf/fsl_imx8_ddr_perf.c  | 1 +
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 +
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 1 +
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  | 1 +
 5 files changed, 5 insertions(+)

diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index 48e28ef..90caba56 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -742,6 +742,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, smmu_pmu);

smmu_pmu->pmu = (struct pmu) {
+   .module = THIS_MODULE,
.task_ctx_nr= perf_invalid_context,
.pmu_enable = smmu_pmu_enable,
.pmu_disable= smmu_pmu_disable,
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 90884d1..2aed2d9 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -512,6 +512,7 @@ static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem 
*base,
 {
*pmu = (struct ddr_pmu) {
.pmu = (struct pmu) {
+   .module   = THIS_MODULE,
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
.task_ctx_nr = perf_invalid_context,
.attr_groups = attr_groups,
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 15713fa..71587f1 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -378,6 +378,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
  ddrc_pmu->sccl_id, ddrc_pmu->index_id);
ddrc_pmu->pmu = (struct pmu) {
.name   = name,
+   .module = THIS_MODULE,
.task_ctx_nr= perf_invalid_context,
.event_init = hisi_uncore_pmu_event_init,
.pmu_enable = hisi_uncore_pmu_enable,
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index dcc5600..c199de7 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -390,6 +390,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
  hha_pmu->sccl_id, hha_pmu->index_id);
hha_pmu->pmu = (struct pmu) {
.name   = name,
+   .module = THIS_MODULE,
.task_ctx_nr= perf_invalid_context,
.event_init = hisi_uncore_pmu_event_init,
.pmu_enable = hisi_uncore_pmu_enable,
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index 7719ae4..567d7e6 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -380,6 +380,7 @@ static int h

Re: [PATCH v2] perf stat: Fix the ratio comments of miss-events

2020-05-06 Thread Qi Liu
Gentle ping ...

Hi Arnaldo,
If possible, could you give a look for this patch?

Thank you,
Qi Liu

On 2020/5/6 20:01, Qi Liu wrote:
> Perf stat displays miss ratio of L1-dcache, L1-icache, dTLB cache, iTLB cache 
> and LL-cache. Take L1-dcache for example, its miss ratio is caculated as 
> "L1-dcache-load-misses/L1-dcache-loads". So "of all L1-dcache hits" is 
> unsuitable to describe it, and "of all L1-dcache accesses" seems better. The 
> comments of L1-icache, dTLB cache, iTLB cache and LL-cache are fixed in the 
> same way.
> 
> Signed-off-by: Qi Liu 
> Reviewed-by: Andi Kleen 
> ---
> Changelog
> v2: Fix the format issue
> 
>  tools/perf/util/stat-shadow.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c 
> index 2c41d47..28f4470 100644
> --- a/tools/perf/util/stat-shadow.c
> +++ b/tools/perf/util/stat-shadow.c
> @@ -506,7 +506,7 @@ static void print_l1_dcache_misses(struct 
> perf_stat_config *config,
> 
>   color = get_ratio_color(GRC_CACHE_MISSES, ratio);
> 
> - out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-dcache 
> hits", ratio);
> + out->print_metric(config, out->ctx, color, "%7.2f%%", "of all 
> +L1-dcache accesses", ratio);
>  }
> 
>  static void print_l1_icache_misses(struct perf_stat_config *config, @@ 
> -527,7 +527,7 @@ static void print_l1_icache_misses(struct perf_stat_config 
> *config,
>   ratio = avg / total * 100.0;
> 
>   color = get_ratio_color(GRC_CACHE_MISSES, ratio);
> - out->print_metric(config, out->ctx, color, "%7.2f%%", "of all L1-icache 
> hits", ratio);
> + out->print_metric(config, out->ctx, color, "%7.2f%%", "of all 
> +L1-icache accesses", ratio);
>  }
> 
>  static void print_dtlb_cache_misses(struct perf_stat_config *config, @@ 
> -547,7 +547,7 @@ static void print_dtlb_cache_misses(struct perf_stat_config 
> *config,
>   ratio = avg / total * 100.0;
> 
>   color = get_ratio_color(GRC_CACHE_MISSES, ratio);
> - out->print_metric(config, out->ctx, color, "%7.2f%%", "of all dTLB 
> cache hits", ratio);
> + out->print_metric(config, out->ctx, color, "%7.2f%%", "of all dTLB 
> +cache accesses", ratio);
>  }
> 
>  static void print_itlb_cache_misses(struct perf_stat_config *config, @@ 
> -567,7 +567,7 @@ static void print_itlb_cache_misses(struct perf_stat_config 
> *config,
>   ratio = avg / total * 100.0;
> 
>   color = get_ratio_color(GRC_CACHE_MISSES, ratio);
> - out->print_metric(config, out->ctx, color, "%7.2f%%", "of all iTLB 
> cache hits", ratio);
> + out->print_metric(config, out->ctx, color, "%7.2f%%", "of all iTLB 
> +cache accesses", ratio);
>  }
> 
>  static void print_ll_cache_misses(struct perf_stat_config *config, @@ -587,7 
> +587,7 @@ static void print_ll_cache_misses(struct perf_stat_config *config,
>   ratio = avg / total * 100.0;
> 
>   color = get_ratio_color(GRC_CACHE_MISSES, ratio);
> - out->print_metric(config, out->ctx, color, "%7.2f%%", "of all LL-cache 
> hits", ratio);
> + out->print_metric(config, out->ctx, color, "%7.2f%%", "of all LL-cache 
> +accesses", ratio);
>  }
> 
>  /*
> @@ -872,7 +872,7 @@ void perf_stat__print_shadow_stats(struct 
> perf_stat_config *config,
>   if (runtime_stat_n(st, STAT_L1_DCACHE, ctx, cpu) != 0)
>   print_l1_dcache_misses(config, cpu, evsel, avg, out, 
> st);
>   else
> - print_metric(config, ctxp, NULL, NULL, "of all 
> L1-dcache hits", 0);
> + print_metric(config, ctxp, NULL, NULL, "of all 
> L1-dcache accesses", +0);
>   } else if (
>   evsel->core.attr.type == PERF_TYPE_HW_CACHE &&
>   evsel->core.attr.config ==  ( PERF_COUNT_HW_CACHE_L1I | @@ 
> -882,7 +882,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config 
> *config,
>   if (runtime_stat_n(st, STAT_L1_ICACHE, ctx, cpu) != 0)
>   print_l1_icache_misses(config, cpu, evsel, avg, out, 
> st);
>   else
> - print_metric(config, ctxp, NULL, NULL, "of all 
> L1-icache hits", 0);
> + print_metric(config, ctxp, NULL, NULL, "of all 
> L1-icache accesses", +0);
>   } else