# Perf for Linux on Arm (LinuxPerf)

## About this Install Guide

| Reading time:      | 15 min            |
|-------------------|------------------|
| Last updated:     | 13 Oct 2026      |
| Ecosystem dashboard: | [View](https://developer.arm.com/ecosystem-dashboard/linux?package=perf) |
| Author:           | Jason Andrews, Arm [GitHub](https://github.com/jasonrandrews) [LinkedIn](https://linkedin.com/in/jason-andrews-7b05a8) |
| Official docs:    | [View](https://perf.wiki.kernel.org/index.php/Main_Page) |

This guide shows you how to install and use the tool with the most common configuration. For advanced options and complete reference information, see the official documentation. Some install guides also include optional next steps to help you explore related workflows or integrations.

Linux Perf is a command line performance analysis tool. The source code is part of the Linux kernel and Perf is connected to the `perf_events` kernel interface. Perf is used to count events from hardware and software and to identify hot spots.

Perf can be used on a wide variety of Arm Linux systems including laptops, desktops, cloud virtual machines, Windows on Arm with WSL (Windows Subsystem for Linux), and ChromeOS with Linux enabled.

Perf is best installed using a Linux package manager, but if a suitable package is not available you can build it from source code. Both situations are covered below.

## What should I do before installing Perf?

Follow the instructions below to install Perf on an Arm Linux system.

Confirm you are using an Arm machine by running:

```
uname -m
```

The output should be:

```
__output__ aarch64
```

If you see a different result, you are not using an Arm computer running 64-bit Linux.

Perf is dependent on the version of the Linux kernel.

To find your version run:

```
uname -r
```

The output will be a string with the first two numbers providing the major and minor kernel version numbers.

For example:

```
__output__ 5.15.0-79-generic
```

This indicates kernel version 5.15.

## How do I install Perf?

The Perf source code is part of the Linux kernel source tree.

There are two ways to install Perf on Arm Linux machines:

- Use a [Linux package manager](https://learn.arm.com/install-guides/perf/#packman)
- Build the [source code](https://learn.arm.com/install-guides/perf/#source)

### How do I install Perf using a Linux package manager?

If a package exists for your specific kernel version you can install Perf using the package manager.

Use the tabs below and copy the commands for your Linux package manager:

```
sudo apt update && sudo apt install linux-tools-generic linux-tools-$(uname -r) -y
```

```
sudo apt install linux-perf -y
```

```
sudo dnf install perf -y
```

If the package manager completes successfully you can skip the next section and proceed to [test Perf](https://learn.arm.com/install-guides/perf/#test).

If the package manager does not complete successfully, it usually means there was no package available for your specific kernel version as shown by `uname -r`.

There are hundreds of packages, and the package name must match the output of `uname -r` exactly. This is most common on Arm single board computers (SBCs) where the Linux kernel has been customized.

If there is no match, you can install Perf using the source code as described in the next [section](https://learn.arm.com/install-guides/perf/#source).

### How do I build Perf from source code?

If there is no package available for your kernel version you can build Perf from source code.

Building Perf from source requires `gcc`, `flex`, `bison`, `git`, and `make`. Install these on your system.

For Ubuntu run:

```
sudo apt update
sudo apt install git make gcc flex bison pkg-config linux-tools-generic linux-tools-$(uname -r) \
libzstd1 libdwarf-dev libdw-dev binutils-dev libcap-dev libelf-dev libnuma-dev python3 python3-dev python3-setuptools \
libssl-dev libunwind-dev zlib1g-dev liblzma-dev libaio-dev libtraceevent-dev debuginfod \
libpfm4-dev libslang2-dev systemtap-sdt-dev libperl-dev libbabeltrace-dev libiberty-dev libzstd-dev -y
```

For Debian and Raspberry Pi OS run:

```
sudo apt update
sudo apt install git make gcc flex bison pkg-config \
libzstd1 libdwarf-dev libdw-dev binutils-dev libcap-dev libelf-dev libnuma-dev python3 python3-dev python3-setuptools \
libssl-dev libunwind-dev zlib1g-dev liblzma-dev libaio-dev libtraceevent-dev debuginfod \
libpfm4-dev libslang2-dev systemtap-sdt-dev libperl-dev libbabeltrace-dev libiberty-dev libzstd-dev -y
```

The `linux-tools-*` packages exist only on Ubuntu, so they are not part of the Debian and Raspberry Pi OS command.

Use `git` to get the source code. Use `--branch` to specify the Linux kernel source tree closest to your kernel version.

For example, if your kernel version is 6.8, use:

```
git clone --depth=1 --branch v6.8 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
```

Change to the `linux` directory and build:

```
cd linux
make -C tools/perf
```

If the build succeeds, a ready to use `perf` executable is available at `tools/perf/perf`.

You can copy it to a location in your search path or run it from the current location.

To copy it use:

```
sudo cp tools/perf/perf /usr/local/bin
```

## How do I test Perf?

Regardless of how you installed Perf, run the `version` command:

```
perf version
```

The output will be similar to:

```
__output__ perf version 5.15.116
```

You can also try the `list` command to confirm `perf` is working as expected:

```
perf list
```

Perf is installed correctly if you see a list of events similar to the output below:

```
__output__ List of pre-defined events (to be used in -e or -M):
__output__
__output__   cpu-cycles OR cycles                               [Hardware event]
__output__
__output__   alignment-faults                                   [Software event]
__output__   bpf-output                                         [Software event]
__output__   cgroup-switches                                    [Software event]
__output__   context-switches OR cs                             [Software event]
__output__   cpu-clock                                          [Software event]
__output__   cpu-migrations OR migrations                       [Software event]
__output__   dummy                                              [Software event]
__output__   emulation-faults                                   [Software event]
__output__   major-faults                                       [Software event]
__output__   minor-faults                                       [Software event]
__output__   page-faults OR faults                              [Software event]
__output__   task-clock                                         [Software event]
__output__
__output__   duration_time                                      [Tool event]
__output__   user_time                                          [Tool event]
__output__   system_time                                        [Tool event]
__output__
__output__
__output__ branch:
__output__   br_mis_pred                                        [Mispredicted or not predicted branch speculatively executed]
__output__   br_pred                                            [Predictable branch speculatively executed]
```

Perf is not working correctly if you see output similar to the messages below. To fix the errors you need to [build Perf from source](https://learn.arm.com/install-guides/perf/#source).

Error #1:

```
__output__ WARNING: perf not found for kernel 5.15.90.1-microsoft
__output__
__output__ You may need to install the following packages for this specific kernel:
__output__   linux-tools-5.15.90.1-microsoft-standard-WSL2
__output__   linux-cloud-tools-5.15.90.1-microsoft-standard-WSL2
__output__
__output__ You may also want to install one of the following packages to keep up to date:
__output__   linux-tools-standard-WSL2
__output__   linux-cloud-tools-standard-WSL2
```

Error #2:

```
__output__ /usr/bin/perf: line 13: exec: perf_5.15: not found
__output__ E: linux-perf-5.15 is not installed.
```

### How do I generate a test Perf report?

Generate a simple Perf report. For example:

```
perf stat -a pwd
```

The `pwd` command output will be shown as well as the report:

```
__output__ Performance counter stats for 'system wide':
__output__
__output__           2.72 msec cpu-clock                 #    2.205 CPUs utilized
__output__             14      context-switches          #    5.147 K/sec
__output__              2      cpu-migrations            #  735.277 /sec
__output__             76      page-faults               #   27.941 K/sec
__output__        2380757      cycles                    #    0.875 GHz
__output__        2651708      instructions              #    1.11  insn per cycle
__output__ <not supported>      branches
__output__          15058      branch-misses
__output__
__output__    0.001233481 seconds time elapsed
```

If you see an error similar to:

```
__output__ Access to performance monitoring and observability operations is limited.
```

You will need to modify the [PMU access permissions](https://learn.arm.com/install-guides/perf/#access).

### How do I manage PMU access permissions?

On some systems, using Perf to access hardware counters is restricted by the value of `/proc/sys/kernel/perf_event_paranoid`.

Typically the value must be 2 or less to collect Perf metrics.

| perf_event_paranoid | Description                                                       |
|----------------------|-------------------------------------------------------------------|
| 3                    | Disable use of Perf events                                       |
| 2                    | Allow only user-space measurements                                |
| 1                    | Allow kernel and user-space measurements                          |
| 0                    | Allow access to CPU-specific data but not raw trace‐point samples |
| -1                   | No restrictions                                                   |

To set this until the next reboot, run the following command:

```
sudo sysctl -w kernel.perf_event_paranoid=2
```

To permanently set the paranoid level, add the following line to the file `/etc/sysctl.conf`:

```
kernel.perf_event_paranoid=2
```

### What are some additional Perf commands?

There are five common commands used in performance analysis.

- **stat** provides performance counter statistics for the overall execution of a program
- **record** samples the program and records the samples into a data file (perf.data by default)
- **report** generates a report of where the samples occurred
- **annotate** displays the annotated code showing the source and assembly code for the samples

### How do I check the Arm PMU driver?

Arm systems use a kernel driver to expose PMU hardware counters. The driver needs to be enabled in the Linux kernel in order to collect the hardware events.

To check if the driver is running use the `dmesg` command:

```
sudo dmesg | grep "PMU driver"
```

Depending on your system, you might need to use `sudo` to run the `dmesg` command.

If you see output similar to the message below, the Arm PMU driver is installed.

```
__output__ [    0.046063] hw perfevents: enabled with armv8_pmuv3_0 PMU driver, 3 counters available
```

The number of counters available could be between 1 and 7 depending on processor types and virtualization.

If you see multiple instances of the PMU driver, it means the hardware is a [big.LITTLE](https://www.arm.com/en/technologies/big-little) system with different processors, each has its own PMU.

If the message is not in the kernel message log, check both the PMU driver device tree entry and the kernel configuration parameters listed above.

The important kernel parameters are:

```
__output__ CONFIG_HAVE_PERF_EVENTS=y
__output__ CONFIG_PROFILING=y
__output__ CONFIG_PERF_EVENTS=y
__output__ CONFIG_ARM_PMU=y
__output__ CONFIG_HW_PERF_EVENTS=y
```

You are now ready to use Perf on your Arm Linux system.
