[RFC V1 00/11] arm64/perf: Enable branch stack sampling

Anshuman Khandual posted 11 patches 4 years, 5 months ago
There is a newer version of this series
arch/arm64/include/asm/sysreg.h          | 216 ++++++++++++
arch/arm64/kernel/perf_event.c           |  48 +++
arch/x86/events/intel/lbr.c              |   4 +-
drivers/perf/Kconfig                     |  11 +
drivers/perf/Makefile                    |   1 +
drivers/perf/arm_pmu.c                   |  65 +++-
drivers/perf/arm_pmu_brbe.c              | 432 +++++++++++++++++++++++
drivers/perf/arm_pmu_brbe.h              | 259 ++++++++++++++
drivers/perf/arm_pmu_platform.c          |  34 ++
include/linux/perf/arm_pmu.h             |  49 +++
include/linux/perf_event.h               |  24 ++
include/uapi/linux/perf_event.h          |  26 +-
kernel/events/core.c                     |   9 +-
tools/include/uapi/linux/perf_event.h    |  26 +-
tools/perf/Documentation/perf-record.txt |   1 +
tools/perf/util/branch.c                 |  13 +-
tools/perf/util/parse-branch-options.c   |   1 +
17 files changed, 1202 insertions(+), 17 deletions(-)
create mode 100644 drivers/perf/arm_pmu_brbe.c
create mode 100644 drivers/perf/arm_pmu_brbe.h
[RFC V1 00/11] arm64/perf: Enable branch stack sampling
Posted by Anshuman Khandual 4 years, 5 months ago
This series enables perf branch stack sampling support on arm64 platform
via a new arch feature called Branch Record Buffer Extension (BRBE). All
relevant register definitions could be accessed here.

https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers

The last two patches extend the perf ABI to accommodate additional branch
information that can be captured in BRBE. This series applies on v5.17-rc1.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-perf-users@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

Anshuman Khandual (11):
  perf: Consolidate branch sample filter helpers
  arm64/perf: Add register definitions for BRBE
  arm64/perf: Update struct arm_pmu for BRBE
  arm64/perf: Update struct pmu_hw_events for BRBE
  arm64/perf: Detect support for BRBE
  arm64/perf: Drive BRBE from perf event states
  arm64/perf: Add BRBE driver
  arm64/perf: Enable branch stack sampling
  perf: Add more generic branch types
  perf: Expand perf_branch_entry.type
  perf: Capture branch privilege information

 arch/arm64/include/asm/sysreg.h          | 216 ++++++++++++
 arch/arm64/kernel/perf_event.c           |  48 +++
 arch/x86/events/intel/lbr.c              |   4 +-
 drivers/perf/Kconfig                     |  11 +
 drivers/perf/Makefile                    |   1 +
 drivers/perf/arm_pmu.c                   |  65 +++-
 drivers/perf/arm_pmu_brbe.c              | 432 +++++++++++++++++++++++
 drivers/perf/arm_pmu_brbe.h              | 259 ++++++++++++++
 drivers/perf/arm_pmu_platform.c          |  34 ++
 include/linux/perf/arm_pmu.h             |  49 +++
 include/linux/perf_event.h               |  24 ++
 include/uapi/linux/perf_event.h          |  26 +-
 kernel/events/core.c                     |   9 +-
 tools/include/uapi/linux/perf_event.h    |  26 +-
 tools/perf/Documentation/perf-record.txt |   1 +
 tools/perf/util/branch.c                 |  13 +-
 tools/perf/util/parse-branch-options.c   |   1 +
 17 files changed, 1202 insertions(+), 17 deletions(-)
 create mode 100644 drivers/perf/arm_pmu_brbe.c
 create mode 100644 drivers/perf/arm_pmu_brbe.h

-- 
2.25.1

[PATCH 0/1] perf test: Add branch stack sampling tests for ARM64
Posted by German Gomez 4 years, 5 months ago
Adds testing of branch stack sampling on ARM64. Branch stack sampling is
supported by the Branch Record Buffer Extension (BRBE). In order to run
the tests, the Kernel must have BRBE support enabled.

At the time of writing, BRBE support in the Kernel is provided by the
patches in RFC [1]. If BRBE support is not detected, the tests will be
skipped.

Information about BRBE can be found in [2].

[1]: https://lore.kernel.org/all/1642998653-21377-1-git-send-email-anshuman.khandual@arm.com/
[2]: https://developer.arm.com/documentation/ddi0608/latest

German Gomez (1):
  perf test: Add branch stack sampling tests for ARM64

 .../perf/tests/shell/test_arm_brbe_kernel.sh  | 42 ++++++++++
 .../tests/shell/test_arm_brbe_userspace.sh    | 80 +++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100755 tools/perf/tests/shell/test_arm_brbe_kernel.sh
 create mode 100755 tools/perf/tests/shell/test_arm_brbe_userspace.sh

-- 
2.25.1

[PATCH 1/1] perf test: Add branch stack sampling tests for ARM64
Posted by German Gomez 4 years, 5 months ago
Adds two shell script tests in order to test branch stack sampling on
ARM64 plarforms. This functionality is enabled by the Branch Record
Buffer Extension (BRBE) on Arm.

Information about BRBE can be found in [1] chapter F1.

[1]: https://developer.arm.com/documentation/ddi0608/latest

Signed-off-by: German Gomez <german.gomez@arm.com>
---
 .../perf/tests/shell/test_arm_brbe_kernel.sh  | 42 ++++++++++
 .../tests/shell/test_arm_brbe_userspace.sh    | 80 +++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100755 tools/perf/tests/shell/test_arm_brbe_kernel.sh
 create mode 100755 tools/perf/tests/shell/test_arm_brbe_userspace.sh

diff --git a/tools/perf/tests/shell/test_arm_brbe_kernel.sh b/tools/perf/tests/shell/test_arm_brbe_kernel.sh
new file mode 100755
index 000000000..dc5a2238f
--- /dev/null
+++ b/tools/perf/tests/shell/test_arm_brbe_kernel.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Arm64 BRBE kernel branches
+
+# SPDX-License-Identifier: GPL-2.0
+# German Gomez <german.gomez@arm.com>, 2022
+
+PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
+
+cleanup_files() {
+	rm -f $PERF_DATA*
+}
+
+trap cleanup_files exit term int
+
+test_brbe_kernel() {
+	lscpu | grep -q "aarch64" || return $?
+	perf record -o $PERF_DATA --branch-filter any,k -- true > /dev/null 2>&1
+}
+
+test_brbe_kernel || exit 2
+
+# example perf-script output:
+#   0xffffffff9a80dd5e/0xffffffff9a87c5c0/P/-/-/1
+#   0xffff8000080ac20c/0xffff800008e99720/P/-/-/2
+#   0xffff8000080ac20c/0xffff800008e99720/P/-/-/3
+
+# kernel addresses always have the upper 16 bits set (https://lwn.net/Articles/718895/)
+KERNEL_ADDRESS_REGEX="0xffff[0-9a-f]{12}"
+
+perf record -o $PERF_DATA --branch-filter any,k -a -- sleep 1
+perf script -i $PERF_DATA --fields brstack | egrep "(0x0|$KERNEL_ADDRESS_REGEX)\/(0x0|$KERNEL_ADDRESS_REGEX)\/" > /dev/null
+err=$?
+
+echo -n "BRB kernel branches: "
+if [ $err != 0 ]; then
+	echo "FAIL"
+	exit 1
+else
+	echo "PASS"
+fi
+
+exit 0
diff --git a/tools/perf/tests/shell/test_arm_brbe_userspace.sh b/tools/perf/tests/shell/test_arm_brbe_userspace.sh
new file mode 100755
index 000000000..4f0bdc03a
--- /dev/null
+++ b/tools/perf/tests/shell/test_arm_brbe_userspace.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+# Arm64 BRBE userspace branches
+
+# SPDX-License-Identifier: GPL-2.0
+# German Gomez <german.gomez@arm.com>, 2022
+
+PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
+TEST_PROGRAM_SOURCE=$(mktemp /tmp/brbe_test_program.XXXXX.c)
+TEST_PROGRAM=$(mktemp /tmp/brbe_test_program.XXXXX)
+
+cleanup_files() {
+	rm -f $PERF_DATA*
+	rm -f $TEST_PROGRAM_SOURCE
+	rm -f $TEST_PROGRAM
+}
+
+trap cleanup_files exit term int
+
+test_brbe_user() {
+	lscpu | grep -q "aarch64" || return $?
+	perf record -o $PERF_DATA --branch-filter any,u -- true > /dev/null 2>&1
+}
+
+test_brbe_user || exit 2
+
+# Skip if there's no compiler
+# We need it to compile the test program
+if ! [ -x "$(command -v cc)" ]; then
+	echo "failed: no compiler, install gcc"
+	exit 2
+fi
+
+script_has_branch() {
+	local from="$1\+0x[0-9a-f]+"
+	local to="$2\+0x[0-9a-f]+"
+	perf script -i $PERF_DATA --fields brstacksym | egrep -qm 1 " +$from\/$to\/"
+}
+
+# compile test program
+cat << EOF > $TEST_PROGRAM_SOURCE
+void f2() {
+}
+void f1() {
+  f2();
+}
+void f0() {
+  f1();
+  f2();
+}
+int main() {
+  while(1) {
+    f0();
+    f1();
+  }
+  return 0;
+}
+EOF
+
+CFLAGS="-O0 -fno-inline -static"
+cc $CFLAGS $TEST_PROGRAM_SOURCE -o $TEST_PROGRAM || exit 1
+
+perf record -o $PERF_DATA --branch-filter any,u -- timeout 1 $TEST_PROGRAM
+
+script_has_branch "main" "f0" &&
+	script_has_branch "main" "f1" &&
+	script_has_branch "f0" "f1" &&
+	script_has_branch "f0" "f2" &&
+	script_has_branch "f1" "f2" &&
+	script_has_branch "main" "main"
+err=$?
+
+echo -n "BRB user branches: "
+if [ $err != 0 ]; then
+	echo "FAIL"
+	exit 1
+else
+	echo "PASS"
+fi
+
+exit 0
-- 
2.25.1