You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Revise documentation for profiling Linux kernel modules with Arm Streamline, enhancing clarity and structure across multiple sections, including overviews, setup instructions, and profiling steps for both out-of-tree and in-tree modules.
title: Profile Linux kernel modules with Arm Streamline
3
3
weight: 2
4
4
5
5
### FIXED, DO NOT MODIFY
6
6
layout: learningpathall
7
7
---
8
8
9
-
## Linux kernel profiling with Arm Streamline
9
+
## Overview
10
10
11
-
Performance tuning is not limited to user-space applications—kernel modules can also benefit from careful analysis. [Arm Streamline](https://developer.arm.com/Tools%20and%20Software/Streamline%20Performance%20Analyzer) is a powerful software profiling tool that helps developers understand performance bottlenecks, hotspots, and memory usage, even inside the Linux kernel. This learning path explains how to use Arm Streamline to profile a simple kernel module.
11
+
Performance tuning is not limited to user-space applications as kernel modules can also benefit from careful analysis. [Arm Streamline](https://developer.arm.com/Tools%20and%20Software/Streamline%20Performance%20Analyzer) is a powerful software profiling tool that helps developers understand performance bottlenecks, hotspots, and memory usage, even inside the Linux kernel. This Learning Path explains how to use Arm Streamline to profile a simple kernel module.
12
+
## Benefits of profiling Linux kernel modules with Arm Streamline
12
13
13
-
### Why profile a kernel module?
14
+
Kernel modules often operate in performance-critical paths, such as device drivers or networking subsystems. Even a small inefficiency in a module can affect the overall system performance.
14
15
15
-
Kernel modules often operate in performance-critical paths, such as device drivers or networking subsystems. Even a small inefficiency in a module can affect the overall system performance. Profiling enables you to:
16
+
Profiling enables you to:
16
17
17
-
- Identify hotspots (functions consuming most CPU cycles)
18
-
- Measure cache and memory behavior
19
-
- Understand call stacks for debugging performance issues
18
+
- Identify hotspots (functions consuming most CPU cycles)
19
+
- Measure cache and memory behavior
20
+
- Understand call stacks for debugging performance issues
21
+
- Detect synchronization bottlenecks and race conditions
22
+
- Quantify the impact of code changes on system latency and throughput
23
+
- Validate that optimizations improve performance on Arm-based systems
24
+
25
+
By using Arm Streamline, you gain visibility into how your kernel module interacts with the rest of the system. This insight helps you make data-driven decisions to optimize code paths, reduce resource contention, and ensure your module performs efficiently on Arm platforms. Profiling is especially valuable when porting modules from x86 to Arm, as architectural differences can reveal new optimization opportunities or highlight previously hidden issues.
## Prepare your development environment for Buildroot on Arm
10
10
11
-
```
11
+
Before you build a Linux image with Buildroot, make sure your development environment includes all required packages. These tools and libraries are essential for compiling, configuring, and assembling embedded Linux images on Arm platforms. Installing them now helps you avoid build errors and ensures a smooth workflow.
12
+
13
+
## Install required packages for Buildroot on Arm
14
+
15
+
Run the following commands on your aarch64-based Linux system to update your package list and install the necessary dependencies:
16
+
17
+
```bash
12
18
sudo apt update
13
-
sudo apt install -y which sed make binutils build-essential diffutils gcc g++ bash patch gzip \
19
+
sudo apt install -y which sed make binutils build-essential diffutils gcc g++ bash patch gzip \
14
20
bzip2 perl tar cpio unzip rsync file bc findutils gawk libncurses-dev python-is-python3 \
15
21
gcc-arm-none-eabi
16
22
```
17
23
24
+
These packages ensure that Buildroot can configure, compile, and assemble all the components needed for your custom Linux image. If you encounter missing package errors during the build process, check your distribution's documentation for any additional dependencies specific to your environment.
25
+
26
+
18
27
## Build a debuggable kernel image
19
28
20
-
For this learning path you will be using [Buildroot](https://github.com/buildroot/buildroot) to build a Linux image for Raspberry Pi 3B+ with a debuggable Linux kernel. You will profile Linux kernel modules built out-of-tree and Linux device drivers built in the Linux source code tree.
29
+
For this Learning Path you'll be using [Buildroot](https://github.com/buildroot/buildroot) to build a Linux image for Raspberry Pi 3B+ with a debuggable Linux kernel. You'll profile Linux kernel modules built out-of-tree and Linux device drivers built in the Linux source code tree.
21
30
22
-
1. Clone the Buildroot Repository and initialize the build system with the default configurations.
31
+
Start by cloning the Buildroot Repository and initialize the build system with the default configurations:
If you're not using a Raspberry Pi 3 for this Learning Path, change the `raspberrypi3_64_defconfig` to the option that matches your hardware in `$(BUILDROOT_HOME)/configs`
32
-
{{% /notice %}}
33
-
34
-
2. You will use `menuconfig` to configure the setup. Invoke it with the following command:
39
+
{{% notice Note on using a different board%}}
40
+
If you're not using a Raspberry Pi 3B+ for this Learning Path, select the default configuration that matches your hardware. Replace `raspberrypi3_64_defconfig` with the appropriate file from the `$(BUILDROOT_HOME)/configs` directory. This ensures Buildroot generates an image compatible with your target board.{{% /notice %}}
35
41
36
42
```
37
43
make menuconfig
38
44
```
39
45
40
-

46
+

41
47
42
-
Change Buildroot configurations to enable debugging symbols and SSH access.
48
+
Change Buildroot configurations to enable debugging symbols and SSH access:
43
49
44
50
```plaintext
45
51
Build options --->
@@ -62,37 +68,51 @@ Target packages --->
62
68
[*] server
63
69
[*] key utilities
64
70
```
71
+
You might need to update your default `sshd_config` file to match your network requirements. To do this, set the **Root filesystem overlay directories** option in the **System configuration** menu. Add a directory containing your customized `sshd_config` file. This ensures your SSH server uses the correct settings when the image boots.
65
72
66
-
You might also need to change your default `sshd_config` file according to your network settings. To do that, you need to modify System configuration→ Root filesystem overlay directories to add a directory that contains your modified `sshd_config` file.
73
+
By default, Linux kernel images are stripped of debugging information. To make the image debuggable for profiling, you need to adjust the kernel build settings.
67
74
68
-
3. By default the Linux kernel images are stripped. You will need to make the image debuggable as you'll be using it later.
69
-
70
-
Invoke `linux-menuconfig` and uncheck the option as shown.
75
+
Open the kernel configuration menu with:
71
76
72
77
```bash
73
78
make linux-menuconfig
74
79
```
75
80
81
+
In the menu, navigate to **Kernel hacking** and ensure that debugging options are enabled. Uncheck any option that reduces debugging information. This step preserves the symbols needed for effective kernel debugging and profiling.
82
+
76
83
```plaintext
77
84
Kernel hacking --->
78
85
-*- Kernel debugging
79
86
Compile-time checks and compiler options --->
80
87
Debug information (Rely on the toolchain's implicit default DWARF version)
81
88
[ ] Reduce debugging information # un-check
82
89
```
90
+
Now you're ready to build the Linux image and flash it to your SD card for use with the Raspberry Pi.
83
91
84
-
4. Now you can build the Linux image and flash it to the the SD card to run it on the Raspberry Pi.
92
+
Run the following command to start the build process:
85
93
86
94
```bash
87
95
make -j$(nproc)
88
96
```
89
97
90
-
It will take some time to build the Linux image. When it completes, the output will be in `$BUILDROOT_HOME/output/images/sdcard.img`:
98
+
This step can take a while, depending on your system's performance. When the build finishes, you'll find the generated image at `$BUILDROOT_HOME/output/images/sdcard.img`.
99
+
100
+
To confirm that Buildroot created the SD card image, list the contents of the output directory:
91
101
92
102
```bash
93
103
ls $BUILDROOT_HOME/output/images/ | grep sdcard.img
94
104
```
95
105
106
+
The expected output is:
107
+
108
+
```output
109
+
sdcard.img
110
+
```
111
+
112
+
If you see `sdcard.img` listed, your image is ready to be flashed to your SD card. You can now flash this image to your SD card and boot your Raspberry Pi with a debuggable Linux kernel.
113
+
96
114
For details on flashing the SD card image, see [this helpful article](https://www.ev3dev.org/docs/tutorials/writing-sd-card-image-ubuntu-disk-image-writer/).
97
115
98
-
Now that you have a target running Linux with a debuggable kernel image, you can start writing your kernel module that you want to profile.
116
+
## What you've accomplished and what's next
117
+
118
+
You've successfully built a custom Linux image with debugging features enabled and flashed it to your Raspberry Pi. This milestone means your development board is now running a kernel that's ready for profiling and advanced debugging. Great job reaching this point! Setting up a debuggable environment is a significant step in embedded Linux development. Next, you'll write and profile your own kernel module, building on the solid foundation you've established.
Copy file name to clipboardExpand all lines: content/learning-paths/embedded-and-microcontrollers/streamline-kernel-module/3_oot_module.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ weight: 4
6
6
layout: learningpathall
7
7
---
8
8
9
-
## Creating the Linux Kernel Module
9
+
## Create an out-of-tree Linux kernel module
10
10
11
11
You will now create an example Linux kernel module (Character device) that demonstrates a cache miss issue caused by traversing a 2D array in column-major order. This access pattern is not cache-friendly, as it skips over most of the neighboring elements in memory during each iteration.
12
12
@@ -254,4 +254,4 @@ The module above receives the size of a 2D array as a string through the `char_d
254
254
255
255
The command above passes 10000 to the module, which specifies the size of the 2D array to be created and traversed. The **echo** command takes a long time to complete (around 38 seconds) due to the cache-unfriendly traversal implemented in the `char_dev_cache_traverse()` function.
256
256
257
-
With the kernel module built, the next step is to profile it using Arm Streamline. You will use it to capture runtime behavior, highlight performance bottlenecks, and help identifying issues such as the cache-unfriendly traversal in your module.
257
+
Great job building and running your kernel module! Now that you have a working example, you're ready to take the next step: profiling it with Arm Streamline. In the following section, you'll use Streamline to capture runtime behavior, identify performance bottlenecks, and see firsthand how cache-unfriendly access patterns impact your module. Get ready to gain valuable insights and optimize your code!
0 commit comments