Skip to content

Commit bcfab08

Browse files
captain5050acmel
authored andcommitted
perf intel-tpebs: Filter non-workload samples
If perf is running with a benchmark then we want the retirement latency samples associated with the benchmark rather than from the system as a whole. Use the workload's PID to filter out samples that aren't from the workload or its children. Signed-off-by: Ian Rogers <irogers@google.com> Tested-by: Weilin Wang <weilin.wang@intel.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: https://lore.kernel.org/r/20250430200108.243234-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 1c5721c commit bcfab08

1 file changed

Lines changed: 58 additions & 1 deletion

File tree

tools/perf/util/intel-tpebs.c

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* intel_tpebs.c: Intel TPEBS support
44
*/
55

6-
6+
#include <api/fs/fs.h>
77
#include <sys/param.h>
88
#include <subcmd/run-command.h>
99
#include <thread.h>
@@ -121,6 +121,59 @@ static int evsel__tpebs_start_perf_record(struct evsel *evsel)
121121
return ret;
122122
}
123123

124+
static bool is_child_pid(pid_t parent, pid_t child)
125+
{
126+
if (parent < 0 || child < 0)
127+
return false;
128+
129+
while (true) {
130+
char path[PATH_MAX];
131+
char line[256];
132+
FILE *fp;
133+
134+
new_child:
135+
if (parent == child)
136+
return true;
137+
138+
if (child <= 0)
139+
return false;
140+
141+
scnprintf(path, sizeof(path), "%s/%d/status", procfs__mountpoint(), child);
142+
fp = fopen(path, "r");
143+
if (!fp) {
144+
/* Presumably the process went away. Assume not a child. */
145+
return false;
146+
}
147+
while (fgets(line, sizeof(line), fp) != NULL) {
148+
if (strncmp(line, "PPid:", 5) == 0) {
149+
fclose(fp);
150+
if (sscanf(line + 5, "%d", &child) != 1) {
151+
/* Unexpected error parsing. */
152+
return false;
153+
}
154+
goto new_child;
155+
}
156+
}
157+
/* Unexpected EOF. */
158+
fclose(fp);
159+
return false;
160+
}
161+
}
162+
163+
static bool should_ignore_sample(const struct perf_sample *sample, const struct tpebs_retire_lat *t)
164+
{
165+
pid_t workload_pid = t->evsel->evlist->workload.pid;
166+
pid_t sample_pid = sample->pid;
167+
168+
if (workload_pid < 0 || workload_pid == sample_pid)
169+
return false;
170+
171+
if (!t->evsel->core.attr.inherit)
172+
return true;
173+
174+
return !is_child_pid(workload_pid, sample_pid);
175+
}
176+
124177
static int process_sample_event(const struct perf_tool *tool __maybe_unused,
125178
union perf_event *event __maybe_unused,
126179
struct perf_sample *sample,
@@ -140,6 +193,10 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
140193
mutex_unlock(tpebs_mtx_get());
141194
return -EINVAL;
142195
}
196+
if (should_ignore_sample(sample, t)) {
197+
mutex_unlock(tpebs_mtx_get());
198+
return 0;
199+
}
143200
/*
144201
* Need to handle per core results? We are assuming average retire
145202
* latency value will be used. Save the number of samples and the sum of

0 commit comments

Comments
 (0)