mirror of
https://github.com/torvalds/linux.git
synced 2025-08-16 06:31:34 +02:00
perf target: Remove uid from target
Gathering threads with a uid by scanning /proc is inherently racy leading to perf_event_open failures that quit perf. All users of the functionality now use BPF filters, so remove uid and uid_str from target. Signed-off-by: Ian Rogers <irogers@google.com> Link: https://lore.kernel.org/r/20250604174545.2853620-10-irogers@google.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
parent
278538ddf1
commit
b4c658d4d6
13 changed files with 6 additions and 73 deletions
|
@ -1663,7 +1663,6 @@ int cmd_ftrace(int argc, const char **argv)
|
||||||
int (*cmd_func)(struct perf_ftrace *) = NULL;
|
int (*cmd_func)(struct perf_ftrace *) = NULL;
|
||||||
struct perf_ftrace ftrace = {
|
struct perf_ftrace ftrace = {
|
||||||
.tracer = DEFAULT_TRACER,
|
.tracer = DEFAULT_TRACER,
|
||||||
.target = { .uid = UINT_MAX, },
|
|
||||||
};
|
};
|
||||||
const struct option common_options[] = {
|
const struct option common_options[] = {
|
||||||
OPT_STRING('p', "pid", &ftrace.target.pid, "pid",
|
OPT_STRING('p', "pid", &ftrace.target.pid, "pid",
|
||||||
|
|
|
@ -1871,8 +1871,6 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
|
||||||
kvm->opts.user_interval = 1;
|
kvm->opts.user_interval = 1;
|
||||||
kvm->opts.mmap_pages = 512;
|
kvm->opts.mmap_pages = 512;
|
||||||
kvm->opts.target.uses_mmap = false;
|
kvm->opts.target.uses_mmap = false;
|
||||||
kvm->opts.target.uid_str = NULL;
|
|
||||||
kvm->opts.target.uid = UINT_MAX;
|
|
||||||
|
|
||||||
symbol__init(NULL);
|
symbol__init(NULL);
|
||||||
disable_buildid_cache();
|
disable_buildid_cache();
|
||||||
|
|
|
@ -108,9 +108,7 @@ static struct parse_events_option_args parse_events_option_args = {
|
||||||
|
|
||||||
static bool all_counters_use_bpf = true;
|
static bool all_counters_use_bpf = true;
|
||||||
|
|
||||||
static struct target target = {
|
static struct target target;
|
||||||
.uid = UINT_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
static volatile sig_atomic_t child_pid = -1;
|
static volatile sig_atomic_t child_pid = -1;
|
||||||
static int detailed_run = 0;
|
static int detailed_run = 0;
|
||||||
|
|
|
@ -5399,7 +5399,6 @@ int cmd_trace(int argc, const char **argv)
|
||||||
struct trace trace = {
|
struct trace trace = {
|
||||||
.opts = {
|
.opts = {
|
||||||
.target = {
|
.target = {
|
||||||
.uid = UINT_MAX,
|
|
||||||
.uses_mmap = true,
|
.uses_mmap = true,
|
||||||
},
|
},
|
||||||
.user_freq = UINT_MAX,
|
.user_freq = UINT_MAX,
|
||||||
|
|
|
@ -91,7 +91,6 @@ static int test__backward_ring_buffer(struct test_suite *test __maybe_unused, in
|
||||||
struct parse_events_error parse_error;
|
struct parse_events_error parse_error;
|
||||||
struct record_opts opts = {
|
struct record_opts opts = {
|
||||||
.target = {
|
.target = {
|
||||||
.uid = UINT_MAX,
|
|
||||||
.uses_mmap = true,
|
.uses_mmap = true,
|
||||||
},
|
},
|
||||||
.freq = 0,
|
.freq = 0,
|
||||||
|
|
|
@ -17,9 +17,7 @@
|
||||||
static int attach__enable_on_exec(struct evlist *evlist)
|
static int attach__enable_on_exec(struct evlist *evlist)
|
||||||
{
|
{
|
||||||
struct evsel *evsel = evlist__last(evlist);
|
struct evsel *evsel = evlist__last(evlist);
|
||||||
struct target target = {
|
struct target target = {};
|
||||||
.uid = UINT_MAX,
|
|
||||||
};
|
|
||||||
const char *argv[] = { "true", NULL, };
|
const char *argv[] = { "true", NULL, };
|
||||||
char sbuf[STRERR_BUFSIZE];
|
char sbuf[STRERR_BUFSIZE];
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -28,7 +28,6 @@ static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused
|
||||||
{
|
{
|
||||||
struct record_opts opts = {
|
struct record_opts opts = {
|
||||||
.target = {
|
.target = {
|
||||||
.uid = UINT_MAX,
|
|
||||||
.uses_mmap = true,
|
.uses_mmap = true,
|
||||||
},
|
},
|
||||||
.no_buffering = true,
|
.no_buffering = true,
|
||||||
|
|
|
@ -45,7 +45,6 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
|
||||||
{
|
{
|
||||||
struct record_opts opts = {
|
struct record_opts opts = {
|
||||||
.target = {
|
.target = {
|
||||||
.uid = UINT_MAX,
|
|
||||||
.uses_mmap = true,
|
.uses_mmap = true,
|
||||||
},
|
},
|
||||||
.no_buffering = true,
|
.no_buffering = true,
|
||||||
|
|
|
@ -46,7 +46,6 @@ static int test__task_exit(struct test_suite *test __maybe_unused, int subtest _
|
||||||
struct evsel *evsel;
|
struct evsel *evsel;
|
||||||
struct evlist *evlist;
|
struct evlist *evlist;
|
||||||
struct target target = {
|
struct target target = {
|
||||||
.uid = UINT_MAX,
|
|
||||||
.uses_mmap = true,
|
.uses_mmap = true,
|
||||||
};
|
};
|
||||||
const char *argv[] = { "true", NULL };
|
const char *argv[] = { "true", NULL };
|
||||||
|
|
|
@ -450,7 +450,7 @@ int perf_bpf_filter__prepare(struct evsel *evsel, struct target *target)
|
||||||
struct bpf_program *prog;
|
struct bpf_program *prog;
|
||||||
struct bpf_link *link;
|
struct bpf_link *link;
|
||||||
struct perf_bpf_filter_entry *entry;
|
struct perf_bpf_filter_entry *entry;
|
||||||
bool needs_idx_hash = !target__has_cpu(target) && !target->uid_str;
|
bool needs_idx_hash = !target__has_cpu(target);
|
||||||
|
|
||||||
entry = calloc(MAX_FILTERS, sizeof(*entry));
|
entry = calloc(MAX_FILTERS, sizeof(*entry));
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
|
|
|
@ -1006,8 +1006,7 @@ int evlist__create_maps(struct evlist *evlist, struct target *target)
|
||||||
* per-thread data. thread_map__new_str will call
|
* per-thread data. thread_map__new_str will call
|
||||||
* thread_map__new_all_cpus to enumerate all threads.
|
* thread_map__new_all_cpus to enumerate all threads.
|
||||||
*/
|
*/
|
||||||
threads = thread_map__new_str(target->pid, target->tid, target->uid,
|
threads = thread_map__new_str(target->pid, target->tid, UINT_MAX, all_threads);
|
||||||
all_threads);
|
|
||||||
|
|
||||||
if (!threads)
|
if (!threads)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -28,20 +28,6 @@ enum target_errno target__validate(struct target *target)
|
||||||
ret = TARGET_ERRNO__PID_OVERRIDE_CPU;
|
ret = TARGET_ERRNO__PID_OVERRIDE_CPU;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UID and PID are mutually exclusive */
|
|
||||||
if (target->tid && target->uid_str) {
|
|
||||||
target->uid_str = NULL;
|
|
||||||
if (ret == TARGET_ERRNO__SUCCESS)
|
|
||||||
ret = TARGET_ERRNO__PID_OVERRIDE_UID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UID and CPU are mutually exclusive */
|
|
||||||
if (target->uid_str && target->cpu_list) {
|
|
||||||
target->cpu_list = NULL;
|
|
||||||
if (ret == TARGET_ERRNO__SUCCESS)
|
|
||||||
ret = TARGET_ERRNO__UID_OVERRIDE_CPU;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PID and SYSTEM are mutually exclusive */
|
/* PID and SYSTEM are mutually exclusive */
|
||||||
if (target->tid && target->system_wide) {
|
if (target->tid && target->system_wide) {
|
||||||
target->system_wide = false;
|
target->system_wide = false;
|
||||||
|
@ -49,13 +35,6 @@ enum target_errno target__validate(struct target *target)
|
||||||
ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM;
|
ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UID and SYSTEM are mutually exclusive */
|
|
||||||
if (target->uid_str && target->system_wide) {
|
|
||||||
target->system_wide = false;
|
|
||||||
if (ret == TARGET_ERRNO__SUCCESS)
|
|
||||||
ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BPF and CPU are mutually exclusive */
|
/* BPF and CPU are mutually exclusive */
|
||||||
if (target->bpf_str && target->cpu_list) {
|
if (target->bpf_str && target->cpu_list) {
|
||||||
target->cpu_list = NULL;
|
target->cpu_list = NULL;
|
||||||
|
@ -70,13 +49,6 @@ enum target_errno target__validate(struct target *target)
|
||||||
ret = TARGET_ERRNO__BPF_OVERRIDE_PID;
|
ret = TARGET_ERRNO__BPF_OVERRIDE_PID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BPF and UID are mutually exclusive */
|
|
||||||
if (target->bpf_str && target->uid_str) {
|
|
||||||
target->uid_str = NULL;
|
|
||||||
if (ret == TARGET_ERRNO__SUCCESS)
|
|
||||||
ret = TARGET_ERRNO__BPF_OVERRIDE_UID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BPF and THREADS are mutually exclusive */
|
/* BPF and THREADS are mutually exclusive */
|
||||||
if (target->bpf_str && target->per_thread) {
|
if (target->bpf_str && target->per_thread) {
|
||||||
target->per_thread = false;
|
target->per_thread = false;
|
||||||
|
@ -124,31 +96,19 @@ uid_t parse_uid(const char *str)
|
||||||
return result->pw_uid;
|
return result->pw_uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum target_errno target__parse_uid(struct target *target)
|
|
||||||
{
|
|
||||||
target->uid = parse_uid(target->uid_str);
|
|
||||||
|
|
||||||
return target->uid != UINT_MAX ? TARGET_ERRNO__SUCCESS : TARGET_ERRNO__INVALID_UID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This must have a same ordering as the enum target_errno.
|
* This must have a same ordering as the enum target_errno.
|
||||||
*/
|
*/
|
||||||
static const char *target__error_str[] = {
|
static const char *target__error_str[] = {
|
||||||
"PID/TID switch overriding CPU",
|
"PID/TID switch overriding CPU",
|
||||||
"PID/TID switch overriding UID",
|
|
||||||
"UID switch overriding CPU",
|
|
||||||
"PID/TID switch overriding SYSTEM",
|
"PID/TID switch overriding SYSTEM",
|
||||||
"UID switch overriding SYSTEM",
|
|
||||||
"SYSTEM/CPU switch overriding PER-THREAD",
|
"SYSTEM/CPU switch overriding PER-THREAD",
|
||||||
"BPF switch overriding CPU",
|
"BPF switch overriding CPU",
|
||||||
"BPF switch overriding PID/TID",
|
"BPF switch overriding PID/TID",
|
||||||
"BPF switch overriding UID",
|
|
||||||
"BPF switch overriding THREAD",
|
"BPF switch overriding THREAD",
|
||||||
"Invalid User: %s",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int target__strerror(struct target *target, int errnum,
|
int target__strerror(struct target *target __maybe_unused, int errnum,
|
||||||
char *buf, size_t buflen)
|
char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
@ -173,10 +133,6 @@ int target__strerror(struct target *target, int errnum,
|
||||||
snprintf(buf, buflen, "%s", msg);
|
snprintf(buf, buflen, "%s", msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TARGET_ERRNO__INVALID_UID:
|
|
||||||
snprintf(buf, buflen, msg, target->uid_str);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* cannot reach here */
|
/* cannot reach here */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,9 +9,7 @@ struct target {
|
||||||
const char *pid;
|
const char *pid;
|
||||||
const char *tid;
|
const char *tid;
|
||||||
const char *cpu_list;
|
const char *cpu_list;
|
||||||
const char *uid_str;
|
|
||||||
const char *bpf_str;
|
const char *bpf_str;
|
||||||
uid_t uid;
|
|
||||||
bool system_wide;
|
bool system_wide;
|
||||||
bool uses_mmap;
|
bool uses_mmap;
|
||||||
bool default_per_cpu;
|
bool default_per_cpu;
|
||||||
|
@ -36,32 +34,24 @@ enum target_errno {
|
||||||
|
|
||||||
/* for target__validate() */
|
/* for target__validate() */
|
||||||
TARGET_ERRNO__PID_OVERRIDE_CPU = __TARGET_ERRNO__START,
|
TARGET_ERRNO__PID_OVERRIDE_CPU = __TARGET_ERRNO__START,
|
||||||
TARGET_ERRNO__PID_OVERRIDE_UID,
|
|
||||||
TARGET_ERRNO__UID_OVERRIDE_CPU,
|
|
||||||
TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
|
TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
|
||||||
TARGET_ERRNO__UID_OVERRIDE_SYSTEM,
|
|
||||||
TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD,
|
TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD,
|
||||||
TARGET_ERRNO__BPF_OVERRIDE_CPU,
|
TARGET_ERRNO__BPF_OVERRIDE_CPU,
|
||||||
TARGET_ERRNO__BPF_OVERRIDE_PID,
|
TARGET_ERRNO__BPF_OVERRIDE_PID,
|
||||||
TARGET_ERRNO__BPF_OVERRIDE_UID,
|
|
||||||
TARGET_ERRNO__BPF_OVERRIDE_THREAD,
|
TARGET_ERRNO__BPF_OVERRIDE_THREAD,
|
||||||
|
|
||||||
/* for target__parse_uid() */
|
|
||||||
TARGET_ERRNO__INVALID_UID,
|
|
||||||
|
|
||||||
__TARGET_ERRNO__END,
|
__TARGET_ERRNO__END,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum target_errno target__validate(struct target *target);
|
enum target_errno target__validate(struct target *target);
|
||||||
|
|
||||||
uid_t parse_uid(const char *str);
|
uid_t parse_uid(const char *str);
|
||||||
enum target_errno target__parse_uid(struct target *target);
|
|
||||||
|
|
||||||
int target__strerror(struct target *target, int errnum, char *buf, size_t buflen);
|
int target__strerror(struct target *target, int errnum, char *buf, size_t buflen);
|
||||||
|
|
||||||
static inline bool target__has_task(struct target *target)
|
static inline bool target__has_task(struct target *target)
|
||||||
{
|
{
|
||||||
return target->tid || target->pid || target->uid_str;
|
return target->tid || target->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool target__has_cpu(struct target *target)
|
static inline bool target__has_cpu(struct target *target)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue