Repository navigation
[DNS] [PROTOTYPE] traced_perf: scope callstacks to a target's descendants - #7797
Draft
LalitMaganti wants to merge 1 commit into
Draft
LalitMaganti wants to merge 1 commit into
LalitMaganti wants to merge 1 commit into
Conversation
Profiling a program by its pid unwinds that one process. What it forks is sampled and then dropped: the children's pids are not targets, and their names need not match a target_cmdline. A server's workers and a build's compilers are the usual case, and perf record follows children by default, so people expect it. Scope.target_pid_descendants puts a process in scope when one of its ancestors is a target pid. Ancestry is read from the parent chain in /proc/<pid>/stat when the process is first sampled, which is where the unwinding decision is already made and cached per pid. This is the first option of #7630 and has the weakness the issue names for it: a process whose parent exited before its first sample has been reparented, and is not covered. Following forks through ftrace, or through perf's own inheritance with per-process events, would close that at the costs the issue describes. This change does not rule either out. Test: perfetto_unittests TargetFilterTest.TargetPidDescendants. nginx under h2load for 8 s, scoped to the master's pid, two recordings each: no callstacks from 27.7k and 27.9k samples without the option; 5,885 and 5,970 callstacks from four worker processes with it.
LalitMaganti
force-pushed
the
dev/lalitm/perf-descendants
branch
from
October 6, 2026 19:58
38bff60 to
0708be8
Compare
🎨 Perfetto UI Builds & Tests
|
LalitMaganti
commented
Oct 6, 2026
| // The parent pid of |pid|, from /proc/<pid>/stat, whose fourth field it is. | ||
| // The second field is the command name in parentheses, which can itself | ||
| // hold spaces and parentheses, so the fields after it are found from the | ||
| // last ')'. |
Member
Author
There was a problem hiding this comment.
@rsavitski this was the most brute force way I could solve this problem but not at all pretty. Do you have any magic thing you know which could solve the problem I have in this PR without needing this? I know that we could do this if we were to use per-thread per-cpu mode but that seems like a bunch bigger change.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add support in traced_perf to allow profiling a target but
also any descendents it forks. We do this by adding a new
target_pid_descendantsoption to the scope: when it's set,a process is in scope if any of its ancestors is one of the
target pids.
We work out the ancestry by walking the parent chain in
/proc//stat the first time we see a sample for a
process. That's the same place we already decide whether to
unwind a pid and cache the answer, so nothing new happens
per sample.
This is the first option from #7630 and it has the downside
discussed there: if a process's parent has already exited by
the time we first sample it, it has been reparented and we
miss it, along with everything below it. Tracking forks via
ftrace or using perf's own inheritance would fix that, but
both are bigger changes. This doesn't stop us doing either
later.
Tested with a new unittest and by profiling nginx under
h2load for 8s with the scope set to the master's pid.
Without the option we get no callstacks at all: every one
of the ~27k samples is dropped. With it we get ~5.9k
callstacks across the 4 busy worker processes.
Issue: #7630