mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: Will Deacon <will@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Rob Herring <robh@kernel.org>,
	 Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	 Florian Fainelli <florian.fainelli@broadcom.com>
Cc: "Ray Jui" <rjui@broadcom.com>,
	"Scott Branden" <sbranden@broadcom.com>,
	bcm-kernel-feedback-list@broadcom.com,
	"Kernel Maintenance" <kernel-list@raspberrypi.com>,
	"Uwe Kleine-König" <ukleinek@kernel.org>,
	"Peter Robinson" <pbrobinson@gmail.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, devicetree@vger.kernel.org,
	linux-rpi-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, "Ian Rogers" <irogers@google.com>
Subject: [PATCH v14 0/3] perf: Add Raspberry Pi AXI PMU driver
Date: Fri,  2 Oct 2026 10:57:33 -0700	[thread overview]
Message-ID: <20261002175738.3242646-1-irogers@google.com> (raw)

Motivation & Background
==============================
Currently, Linux lacks a standard perf-API compatible driver for the
Broadcom AXI performance counter blocks on Raspberry Pi platforms. Prior
out-of-tree vendor solutions relied on custom debugfs nodes and ad-hoc
kthreads, preventing integration with standard Linux perf tooling (`perf stat`,
`perf list`, etc.).

This driver implements standard `struct pmu` hardware uncore callbacks
under `drivers/perf/`, exposing human-readable sysfs event aliases for all
11 hardware metrics per bus (`atwait`, `atrans`, `amax`, `wwait`, `wtrans`,
`wmax`, `rwait`, `rtrans`, `rmax`, `rpend`, `ratrans`) and 6-bit AXI master
ID filtering (`filter=0..50`) directly to user space.

Key Architectural Improvements & Features
==============================
1. Standard Linux Perf Integration:
   - Exposes uncore AXI interconnect events via
     `/sys/bus/event_source/devices/rpi_axi_pmu/`.
   - Supports up to 3 concurrently monitored buses per monitor
     (`NUM_BUS_WATCHER_RESULTS = 3`), with bus-watcher reference counting
     so all 11 counter metrics on the same `(monitor, bus, filter)` tuple
     share a single hardware watcher without multiplexing.
   - Enforces atomic group validation (`rpi_axi_pmu__validate_group`) to
     reject event groups requiring more than 3 watchers per monitor at
     `perf_event_open()` time, while supporting time-multiplexing across
     more than 3 ungrouped buses.
   - Supports hardware counter accumulation (`local64_add`) using full
     32-bit unsigned counter reads (`u32`) and periodic hrtimer polling
     (`POLL_INTERVAL_MS = 100`) to prevent counter saturation.

2. CPU Hotplug Support (`cpuhp`):
   - Registers dynamic CPU hotplug callbacks (`CPUHP_AP_ONLINE_DYN` via
     `cpuhp_state_add_instance()`).
   - Automatically migrates PMU context (`perf_pmu_migrate_context`) to an
     online CPU core when the designated CPU goes offline.

3. Hybrid Memory-Mapped & Mailbox Work Queue Architecture:
   - System Monitor (MMIO): Performs fast atomic-safe memory reads directly
     mapped over ARM physical memory space (`MON__SYSTEM`).
   - VPU Monitor (Mailbox IPC): For Broadcom BCM2835-BCM2711 platforms
     (RPi 1-4) when configured via `system-only`, VideoCore VPU monitor
     (`MON__VPU`) mailbox IPC calls are offloaded to process context via
     `schedule_work(&pmu->mailbox_work)` and serialized with an atomic
     snapshot cache (`cached_values`), avoiding sleeping in atomic/hrtimer
     context. The firmware node is discovered via
     `of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware")`
     and untranslated VideoCore bus addresses are read from the `reg`
     property via `of_property_read_u32_index()`.

4. Per-SoC Generation Support:
   - Patch 1 documents the Device Tree bindings (`brcm,bcm2835-axiperf`,
     `brcm,bcm2711-axiperf`, `brcm,bcm2712-axiperf`).
   - Patch 2 adds core driver support for Broadcom BCM2835 and BCM2711 with
     distinct per-SoC bus and AXI master ID filter tables matching the
     hardware topology of each generation.
   - Patch 3 expands support for Broadcom BCM2712 (Raspberry Pi 5), adding
     the BCM2712 System monitor pipelines (`DISPLAY_TOP`, `ARGON_TOP`,
     `BSTM_TOP`, `PCIE_01`, `XPT`, `ARM`, `SYSTEM_L2`, etc.) and 6-bit AXI
     master ID filter tables (51 filter IDs, `GENMASK(13, 8)`).

Hardware Validation
==============================
The driver has been validated on Raspberry Pi 400 (BCM2711) and Raspberry
Pi 5 (BCM2712). Example on Raspberry Pi 5 monitoring 17 events across 3
buses (`bstm_top`, `arm`, `system_l2`) simultaneously without multiplexing:

  $ sudo perf stat -a \
      -e rpi_axi_pmu/bstm_top_atwait/,rpi_axi_pmu/bstm_top_atrans/,rpi_axi_pmu/bstm_top_amax/ \
      -e rpi_axi_pmu/bstm_top_wwait/,rpi_axi_pmu/bstm_top_wtrans/,rpi_axi_pmu/bstm_top_wmax/ \
      -e rpi_axi_pmu/bstm_top_rwait/,rpi_axi_pmu/bstm_top_rtrans/,rpi_axi_pmu/bstm_top_rmax/ \
      -e rpi_axi_pmu/bstm_top_rpend/,rpi_axi_pmu/bstm_top_ratrans/ \
      -e rpi_axi_pmu/arm_rtrans/,rpi_axi_pmu/arm_wtrans/,rpi_axi_pmu/arm_rmax/,rpi_axi_pmu/arm_wmax/ \
      -e rpi_axi_pmu/system_l2_rtrans/,rpi_axi_pmu/system_l2_wtrans/ \
      -- python3 -c 'a = bytearray(256 * 1024 * 1024); b = bytearray(a)'

   Performance counter stats for 'system wide':

                   0      rpi_axi_pmu/bstm_top_atwait/
                  64      rpi_axi_pmu/bstm_top_atrans/
                   0      rpi_axi_pmu/bstm_top_amax/
                   0      rpi_axi_pmu/bstm_top_wwait/
                   0      rpi_axi_pmu/bstm_top_wtrans/
                   0      rpi_axi_pmu/bstm_top_wmax/
                   0      rpi_axi_pmu/bstm_top_rwait/
                 256      rpi_axi_pmu/bstm_top_rtrans/
                   0      rpi_axi_pmu/bstm_top_rmax/
                 190      rpi_axi_pmu/bstm_top_rpend/
                  64      rpi_axi_pmu/bstm_top_ratrans/
          10,987,780      rpi_axi_pmu/arm_rtrans/
          17,265,030      rpi_axi_pmu/arm_wtrans/
               2,519      rpi_axi_pmu/arm_rmax/
               1,093      rpi_axi_pmu/arm_wmax/
                   0      rpi_axi_pmu/system_l2_rtrans/
                   0      rpi_axi_pmu/system_l2_wtrans/

         0.165352897 seconds time elapsed

Additionally verified on Raspberry Pi 5:
- 6-bit AXI master ID filtering (`filter=0..50` accepted, with active
  traffic on `filter=16..23` and `filter=32..43` confirming bit 5 is
  decoded in BCM2712 hardware, and `filter=51` rejected with `-EINVAL`).
- Time-multiplexing across all 13 BCM2712 buses and atomic group rejection
  (`-EINVAL`) when grouping 4 distinct buses.
- Live CPU hotplug context migration when offlining `CPU0`.

Changes since v13
==============================
Addresses feedback from the upstream v13 review as well as downstream
review on https://github.com/raspberrypi/linux/pull/7571 (with the
corresponding updates tracked in
https://github.com/raspberrypi/linux/pull/7671):

- Device Tree Bindings (Patch 1):
  - Removed the `firmware` phandle property and `allOf` conditional from
    `brcm,bcm2835-axiperf.yaml` per Krzysztof Kozlowski's review; the
    driver now locates `raspberrypi,bcm2835-firmware` via
    `of_find_compatible_node()`.
  - Set `reg` `minItems: 2` (`MON_SYSTEM` and `MON_VPU`) and updated the
    example to use the BCM2712 address map (`0x7c012800` / `0x7e000000`).
- Core Driver & SoC Support (Patches 2 & 3):
  - Removed all `LINUX_VERSION_CODE` conditional checks per Uwe
    Kleine-König and Florian Fainelli.
  - Separated BCM2835, BCM2711, and BCM2712 bus and AXI master ID filter
    tables (`CHIP_BCM2835`, `CHIP_BCM2711`, `CHIP_BCM2712`) to match the
    hardware definitions per https://github.com/raspberrypi/linux/pull/7571.
  - Fixed VPU mailbox base address lookup to read untranslated 32-bit
    VideoCore peripheral addresses via `of_property_read_u32_index()`
    instead of CPU-translated `platform_get_resource()` addresses, and
    skipped mapping `MON_VPU` on BCM2712 (`CHIP_BCM2712`).
  - Widened the AXI master ID filter field from 5 bits to 6 bits
    (`GENMASK(13, 8)` in hardware, `config:10-15` in perf attr) to support
    all 51 BCM2712 filter IDs without truncation.
  - Replaced 31-bit counter masking (`& 0x7FFFFFFF`) with full 32-bit
    unsigned reads (`u32`) and removed speculative `scale="32"` /
    `unit="Bytes"` sysfs attributes so raw transaction, cycle, and latency
    counts are reported accurately.
  - Added bus-watcher reference counting and
    `rpi_axi_pmu__validate_group()` so multiple metrics on the same
    `(monitor, bus, filter)` share a single hardware watcher and
    unschedulable event groups fail at `perf_event_open()` with `-EINVAL`.
  - Switched CPU hotplug registration to exported
    `cpuhp_state_add_instance()` with an online callback
    (`rpi_axi_pmu_online_cpu`) and updated `cpumask_show()` to use
    `sysfs_emit()`.
  - Fixed `Kconfig` dependencies (`ARCH_BCM2835`, `RASPBERRYPI_FIRMWARE`,
    and `!RPI_AXIPERF`).

Ian Rogers (3):
  dt-bindings: perf: Add Broadcom Raspberry Pi AXI PMU definition
  perf: Add Raspberry Pi BCM2835 AXI PMU driver
  perf: Add Raspberry Pi 5 (BCM2712) AXI PMU support

 .../bindings/perf/brcm,bcm2835-axiperf.yaml   |   71 +
 drivers/perf/Kconfig                          |   13 +
 drivers/perf/Makefile                         |    1 +
 drivers/perf/rpi_axi_pmu.c                    | 3397 +++++++++++++++++
 4 files changed, 3482 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/brcm,bcm2835-axiperf.yaml
 create mode 100644 drivers/perf/rpi_axi_pmu.c

-- 
2.56.0.rc1.315.gc6ed9934b7-goog


             reply	other threads:[~2026-10-02 17:57 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-02 17:57 Ian Rogers [this message]
2026-10-02 17:57 ` [PATCH v14 1/3] dt-bindings: perf: Add Broadcom Raspberry Pi AXI PMU definition Ian Rogers
2026-10-02 17:57 ` [PATCH v14 2/3] perf: Add Raspberry Pi BCM2835 AXI PMU driver Ian Rogers
2026-10-02 17:57 ` [PATCH v14 3/3] perf: Add Raspberry Pi 5 (BCM2712) AXI PMU support Ian Rogers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261002175738.3242646-1-irogers@google.com \
    --to=irogers@google.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=florian.fainelli@broadcom.com \
    --cc=kernel-list@raspberrypi.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=pbrobinson@gmail.com \
    --cc=rjui@broadcom.com \
    --cc=robh@kernel.org \
    --cc=sbranden@broadcom.com \
    --cc=ukleinek@kernel.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®