Commit bf1976dd authored by Ian Rogers's avatar Ian Rogers Committed by Namhyung Kim
Browse files

perf trace: Switch user option to use BPF filter



Finding user processes by scanning /proc is inherently racy and
results in perf_event_open failures. Use a BPF filter to drop samples
where the uid doesn't match. Ensure adding the BPF filter forces
system-wide.

Signed-off-by: default avatarIan Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250604174545.2853620-8-irogers@google.com


Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
parent 38f83cc9
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ struct trace {
		struct ordered_events	data;
		u64			last;
	} oe;
	const char		*uid_str;
};

static void trace__load_vmlinux_btf(struct trace *trace __maybe_unused)
@@ -4412,8 +4413,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
		evlist__add(evlist, pgfault_min);
	}

	/* Enable ignoring missing threads when -u/-p option is defined. */
	trace->opts.ignore_missing_thread = trace->opts.target.uid != UINT_MAX || trace->opts.target.pid;
	/* Enable ignoring missing threads when -p option is defined. */
	trace->opts.ignore_missing_thread = trace->opts.target.pid;

	if (trace->sched &&
	    evlist__add_newtp(evlist, "sched", "sched_stat_runtime", trace__sched_stat_runtime))
@@ -5445,8 +5446,7 @@ int cmd_trace(int argc, const char **argv)
		    "child tasks do not inherit counters"),
	OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages",
		     "number of mmap data pages", evlist__parse_mmap_pages),
	OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user",
		   "user to profile"),
	OPT_STRING('u', "uid", &trace.uid_str, "user", "user to profile"),
	OPT_CALLBACK(0, "duration", &trace, "float",
		     "show only events with duration > N.M ms",
		     trace__set_duration),
@@ -5804,12 +5804,20 @@ int cmd_trace(int argc, const char **argv)
		goto out_close;
	}

	err = target__parse_uid(&trace.opts.target);
	if (err) {
		target__strerror(&trace.opts.target, err, bf, sizeof(bf));
		fprintf(trace.output, "%s", bf);
	if (trace.uid_str) {
		uid_t uid = parse_uid(trace.uid_str);

		if (uid == UINT_MAX) {
			ui__error("Invalid User: %s", trace.uid_str);
			err = -EINVAL;
			goto out_close;
		}
		err = parse_uid_filter(trace.evlist, uid);
		if (err)
			goto out_close;

		trace.opts.target.system_wide = true;
	}

	if (!argc && target__none(&trace.opts.target))
		trace.opts.target.system_wide = true;