[PATCH v13 0/3] perf: Add Raspberry Pi AXI PMU driver

Ian Rogers irogers at google.com
Sat Aug 15 11:40:21 PDT 2026


On Sat, Aug 15, 2026 at 10:27 AM Ian Rogers <irogers at google.com> wrote:
>
> Motivation & Background
> ==============================
> Currently, Linux lacks a standard perf-API compatible driver for the
> Broadcom AXI performance counter blocks on Raspberry Pi platforms.

The patches now have no Sashiko reported issues except for the
deliberate backward compatibility #ifdef to support earlier than Linux
6.13 builds (I believe Raspberry Pi OS is currently using the LTS
v6.12 kernel and when they switch to v6.18 this can be removed):
https://sashiko.dev/#/patchset/20260815172712.50119-1-irogers%40google.com

If you are testing the patches the easiest way (imo) is to build them
outside the Linux tree doing something like:

# Remove the non-perf driver
$ sudo rmmod raspberrypi_axi_monitor

In a directory have rpi_axi_pmu.c (from the patches) and a Makefile with:
```
obj-m += rpi_axi_pmu.o

KDIR ?= /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

default:
        $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
        $(MAKE) -C $(KDIR) M=$(PWD) clean
```
then run make and `sudo insmod rpi_axi_pmu.ko`.

On a Raspberry Pi 4 and earlier you should be able to test counters like:
```
$ sudo perf stat -e rpi_axi_pmu/h264_rtrans/,rpi_axi_pmu/h264_wtrans/
-a -- ffmpeg -vcodec h264_v4l2m2m -i test.mp4 -f null -
ffmpeg version 5.1.9-0+deb12u1+rpt1 Copyright (c) 2000-2026 the FFmpeg
developers
  built with gcc 12 (Debian 12.2.0-14+deb12u1)
  configuration: --prefix=/usr --extra-version=0+deb12u1+rpt1
--toolchain=hardened --incdir=/usr/include/aarch64-linux-gnu
--enable-gpl --disable-stripping --disable-mmal --enable-gnutls
--enable-ladspa --enable-libaom --enable-libass --enable-libbluray
--enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2
--enable-libdav1d --enable-libflite --enable-libfontconfig
--enable-libfreetype --enable-libfribidi --enable-libglslang
--enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame
--enable-libmysofa --enable-libopenjpeg --enable-libopenmpt
--enable-libopus --enable-libpulse --enable-librabbitmq
--enable-librist --enable-librubberband --enable-libshine
--enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt
--enable-libssh --enable-libsvtav1 --enable-libtheora
--enable-libtwolame --enable-libvidstab --enable-libvorbis
--enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2
--enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi
--enable-lv2 --enable-omx --enable-openal --enable-opencl
--enable-opengl --enable-sand --enable-sdl2 --disable-sndio
--enable-libjxl --enable-neon --enable-v4l2-request --enable-libudev
--enable-epoxy --libdir=/usr/lib/aarch64-linux-gnu --arch=arm64
--enable-pocketsphinx --enable-librsvg --enable-libdc1394
--enable-libdrm --enable-vout-drm --enable-libiec61883
--enable-chromaprint --enable-frei0r --enable-libx264
--enable-libplacebo --enable-librav1e --enable-shared
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:05.00, start: 0.000000, bitrate: 204 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661),
yuv420p(tv, smpte170m, progressive), 640x480, 202 kb/s, SAR 1:1 DAR
4:3, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.37.100 h264_v4l2m2m
[h264_v4l2m2m @ 0x559bdbefb0] Using device /dev/video10
[h264_v4l2m2m @ 0x559bdbefb0] driver 'bcm2835-codec' on card
'bcm2835-codec-decode' in mplane mode
[h264_v4l2m2m @ 0x559bdbefb0] requesting formats: output=H264 capture=YU12
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (h264_v4l2m2m) -> wrapped_avframe (native))
Press [q] to stop, [?] for help
Output #0, null, to 'pipe:':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Stream #0:0(und): Video: wrapped_avframe, yuv420p(tv,
smpte170m/bt470m/bt709, progressive), 640x480 [SAR 1:1 DAR 4:3],
q=2-31, 200 kb/s, 30 fps, 30 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.37.100 wrapped_avframe
frame=  150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A
speed=12.9x
video:69kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB
muxing overhead: unknown

 Performance counter stats for 'system wide':

       429,721,472 Bytes rpi_axi_pmu/h264_rtrans/
       163,431,488 Bytes rpi_axi_pmu/h264_wtrans/

       2.152513625 seconds time elapsed
```

and on a Raspberry Pi 5 like:
```
$ sudo perf stat -e
rpi_axi_pmu/a76_dsu_l3_rtrans/,rpi_axi_pmu/a76_dsu_l3_wtrans/,rpi_axi_pmu/dma_l2_wtrans/
-a -- sh -c 'dd if=/dev/zero of=/dev/shm/test_ram bs=1M count=1000 &&
rm /dev/shm/test_ram'
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 0.255655 s, 4.1 GB/s

 Performance counter stats for 'system wide':

             2,656 Bytes rpi_axi_pmu/a76_dsu_l3_rtrans/
             1,152 Bytes rpi_axi_pmu/a76_dsu_l3_wtrans/
               576 Bytes rpi_axi_pmu/dma_l2_wtrans/

       0.279860667 seconds time elapsed
```

Thanks,
Ian



More information about the linux-rpi-kernel mailing list