Simplifying Function Tracing for the Modern GCC
Steven Rostedt wanted to do a little housekeeping, specifically with the function
tracing code used in debugging the kernel. Up until then, the kernel could enable
function tracing using either GCC's -pg
flag or a
combination of -pg
and
-mfentry
. In each case, GCC would create a special routine that would execute at the
start of each function, so the kernel could track calls to all functions. With just
-pg
, GCC would create a call to mcount()
in all C functions,
although with -pg
coupled
with -mfentry
, it would create a call to fentry()
.
Steven pointed out that using -mfentry
was generally regarded as superior, so much so
that the kernel build system always would choose it over the mcount()
alternative by
testing GCC at compile time to see if it actually supported that command-line argument.
This is all very normal. Since any user might have any version of a given piece of software in the toolchain, or a variety of different CPUs and so on, each with different capabilities, the kernel build system runs many tests to identify the best available features that the kernel will be able to rely on.
But in this case, Steven noticed that for Linux version 4.19,
Linus Torvalds had agreed to bump
the minimum supported GCC version to 4.6. Coincidentally, as Steven now pointed out,
GCC version 4.6 was the first to support the -mfentry
argument. And, this was his
point—all supported versions of GCC now supported the better function tracing
option, and so there was no need for the kernel build system to cling to the
mcount()
implementation at all.
Steven posted a patch to rip it out by the roots.
Peter Zijlstra gave his support for this plan, as did Jiri
Kosina. And, Jiri in
particular spat upon the face of the mcount()
solution.
Linus also liked Steven's patch, and he pointed out that with mcount() out of the
picture, there were several more areas in the kernel that had existed simply to help
choose between mcount()
and fentry()
, and that those now also could be removed. But Steven
replied that, although yes this should be done, he still wanted to do split it up into
a separate patch, for cleanliness' sake.
As it turned out, Steven's patch actually applied only to the x86 kernel port. A lot of
other architectures still used mcount()
, as Josh
Poimboeuf pointed out. And Steven
confirmed, "fentry works nicely when you have a single instruction that pushes the
return address on the stack and then jumps to another location. It's much trickier to
implement with link registers. There's a few different implementations for other archs,
but mcount happens to be the one supported by most."
And that was that. Steven's patch certainly will go into the kernel as soon as it's fully ready. It's enjoyable to watch these details shake out, after the relatively large decision to change the minimum supported GCC version. I imagine there are several more areas of the kernel that can be simplified and cleaned up, now that they don't have to support older versions of GCC.
Note: if you're mentioned above and want to post a response above the comment section, send a message with your response text to ljeditor@linuxjournal.com.