The Linux kernel provides an Arm PMU driver for counting events such as cycles, instructions, and cache metrics. This article explains how to use the Arm Linux PMU driver to gather performance information, using a device driver and a system call.
The steps covered are:
- Configure Linux kernel for profiling
- Confirm the device tree entry for the Arm PMU driver is included in the kernel
- Insert system calls into the Linux application to access performance information
Performance Information from a Linux Application
The perf_event_open system call can be used to obtain performance information from a Linux application. This system call does not have a glibc wrapper so it is called directly using syscall. Most of the available examples create a wrapper function, including the one shown in the manpage to make for easier usage.
- The process is similar to many other Linux system calls. First, get a file descriptor using open() and then use the file descriptor for other operations such as ioctl() and read().
- The perf_event_open system call uses a number of parameters to configure the events to be counted. Sticking with the simple case of instruction count, fill in the perf_event_attr data structure with the desired information, including information about:
- Start enabled or disabled
- Trace child processes or not
- Include hypervisor activity or not
- Include kernel activity or not
Other system call arguments include which event to trace (such as instructions), the process id to trace, and which CPUs to trace on.
A setup function to count instructions could look like this:
The Arm PMU driver and perf_event_open system call provide a far more robust solution for accessing the Arm PMU from Linux applications. The driver takes care of all of the accounting, event counter overflow handling, and provides many flexible options for tracing.
For situations where tracing many events is required, it may be overly cumbersome to use the perf_event_open system call. One of the features of perf_event_open is the ability to use a group file descriptor to create groups of events with one group leader and other group members with all events being traced as a group. While all of this is possible it may be helpful to look at the perf command, which comes with the Linux kernel and provides the ability to control the counters for entire applications.