Measure stack usage of kernel functions
This article describes how to measure the stack usage of kernel functions and how to apprach the dreaded “Stack frame exceeds limit message”.
Overview
In Linux kernel development the stack size available is limited. It is important to verify that the stack size requirement for a function stay within an acceptable range. The linux kernel development directory contains several tools that help with analyzing the requirements.
In addition when you submit a patch the testing infrastructure will verify that your stack frame requirements do not pass certain limits. These checks are not perfect and can report false positives.
“Stack frame exceeds limit warning”
After you submitted a patch, it is possible that you get an email from the CI infrastructure that your patch passed certain limits. The following is an example of such an email. At this point it is necessary to analyze the stack growth of the reported functions and compare the stack frame size before and after applying your patch.
It is important to consider that this is not necessarily a problem with your patch. There are other factor that can contribute to the warning like
- You made a small change and this just caused the limit to be reached
- The code layout has changed with your change and this caused the increase in the stack frame size. This is generally especially a problem with functions that are defined inline or that get inlined.
General Approach
To find out if this is a real problem or a false positive its best to compare before and after applying the patch. Sometimes it is necessary to dump the object file with objdump to compare the differences.
stackusage
In the scripts directory there is the stackusage
script. The stackusage script allows to
recompile the kernel and create an output file. The output file contains a line for each
function with its stack size.
The script can be invoked like this. The -o
option specifies the output file.
|
|
Let’s assume we are interested in the functions in the file ksm.c
in the memory
management layer, we can run the following command. It will search for all the functions
in the file ksm.c
, sort them in ascending order by the third column (the stack size) and
then format them in tabular format. The functions with the biggest stack sizes are
reported last.
|
|
This helps in finding the biggest stack consumers. The disadvantage of this utility is that needs to recompile the kernel to be able to produce the stack usage report. This can run for a while
stackdelta
The stackdelta
utility allows to compare to stackusage reports. This allows to analyze which
functions have changed in terms of stack frame size. Assuming I have two different stackusage
report su.txt and su2.txt, a diff report of the two can be created. The report only includes
functions that are part of both kernels and whose stack size has changed.
|
|
checkstack.pl
The checkstack.pl
script is a quicker way to produce a stack usage report. It uses the
objdump
tool to create the stack usage breakdown. Here is an example:
|
|
gcc options
frame-larger-than
The gcc compiler provides the option -Wframe-larger-than=<len>
. This can be used to warn
if a function uses more than len bytes stack space.
stack-usage
The gcc compiler now also contains -fstack-usage
option. If files get compiled with this
option and additional file per translation unit gets created. The file has the extension
.su
. It contains the stack usage per file. The output is pretty similar to the above
output of the stackusage command.
Analyzing the stack usage in a live system
The ftrace kernel tracing framework provides the ability to trace the stack size of a live system. The stack tracing functionality can be enabled with the following commands:
|
|
The stack tracer has one configuration option: stack_trace_filter
. If stack_trace_filter
is specified it will only include these functions that have been stored in the
stack_trace_filter file.
The file stack_max_size
in the same directory reports the maximum stack size.
Specifying CONFIG_FRAME_WARN
The kernel can be configured with the CONFIG_FRAME_WARN
option. In that case it will create
warnings for all functions that use use more than the specified allocation size.
|
|
Under the covers it uses the above described gcc option -Wframe-larger-than
.
Stack size debugging with /proc/vmstat
The Linux kernel 6.12 introduces a new configuration option called CONFIG_DEBUG_STACK_USAGE
.
The new configuration option needs to be enabled when building a kernel. It can be found
under:
|
|
Once the kernel is built with the stack usage option, we can query the vmstat
file for the
size of the kernel stacks.
|
|
It doesn’t give the exact numbers, but we can see in which size buckets the kernel allocation generally falls.