mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 11:50:52 +07:00
perf/core improvements and fixes:
. Update attr test with PERF_FLAG_FD_CLOEXEC flag (Jiri Olsa) . Enable close-on-exec flag on perf file descriptor (Yann Droneaud) Signed-off-by: Jiri Olsa <jolsa@kernel.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTyMsUAAoJEPZqUSBWB3s9Oq8P/i1nD9f5HyO3E8J1xrvqfTNV 0H4OHa09zrRuDiHuYjhNgpoCfKT0UA7lvUHTiOyNOL46T1P8FlWznhegdz84mCsP Iz57Yr4qTE9iGIeOPGJWSnkG++tcngZBuop73I/UfZz1sngz02PunQYu9eoQQQTL XGOc6VkgNJK1nfuPNW/e/bwcdcEoEoRqjCX8VHlW32q7HnM/RpH/SinqdETTV2g9 4NA+xSQsaqcYTnb3W8NqgpVoW1SCV8VagR/+pN0ajHouEEtHfwvYlrhWmZsaEBAC GMbFMgTH3LXlFmQgZq56cMvUsKDmlJCwwL4d60fsXiIkkQBzuRU6sfh93oBI+UFr oEI7thFMGvCKXk7q9zICgJn19RkJ0ZeSrmPHLkvtSlWwLxnINFb3XRGpwtgFRdw5 K3esnCbBy+PSmj8rH8TvzQ24aGJ0ohOmlBmJ7zZJMkPEygh1HFWDDC5ICFvY6Bsy ST/8hvbKnLCgZgNUGI4TZhPfj/ldN/GLWeW7UFY2tlCmuJdgnsJtjpr0/QxfDZMF O7u6XIzZe8LCHQHL+WxPJrPpLaCnDPLKXq3Dur5ze8rVdcfmvXSF6XxeaZ6Y3RtP YhTLXMSnKMgm+g0d9qL+msyftyAVzjd2NVy0jumP3T9jC6cxmCxQJWkoCskD4c8l 5D8RUTa++P7zQqy1zzCT =qp4/ -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf into perf/core Pull perf/core improvements and fixes from Jiri Olsa: . Update attr test with PERF_FLAG_FD_CLOEXEC flag (Jiri Olsa) . Enable close-on-exec flag on perf file descriptor (Yann Droneaud) Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
2336ebc326
@ -376,6 +376,7 @@ LIB_OBJS += $(OUTPUT)util/record.o
|
||||
LIB_OBJS += $(OUTPUT)util/srcline.o
|
||||
LIB_OBJS += $(OUTPUT)util/data.o
|
||||
LIB_OBJS += $(OUTPUT)util/tsc.o
|
||||
LIB_OBJS += $(OUTPUT)util/cloexec.o
|
||||
|
||||
LIB_OBJS += $(OUTPUT)ui/setup.o
|
||||
LIB_OBJS += $(OUTPUT)ui/helpline.o
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "../util/util.h"
|
||||
#include "../util/parse-options.h"
|
||||
#include "../util/header.h"
|
||||
#include "../util/cloexec.h"
|
||||
#include "bench.h"
|
||||
#include "mem-memcpy-arch.h"
|
||||
|
||||
@ -83,7 +84,8 @@ static struct perf_event_attr cycle_attr = {
|
||||
|
||||
static void init_cycle(void)
|
||||
{
|
||||
cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0);
|
||||
cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1,
|
||||
perf_event_open_cloexec_flag());
|
||||
|
||||
if (cycle_fd < 0 && errno == ENOSYS)
|
||||
die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "../util/util.h"
|
||||
#include "../util/parse-options.h"
|
||||
#include "../util/header.h"
|
||||
#include "../util/cloexec.h"
|
||||
#include "bench.h"
|
||||
#include "mem-memset-arch.h"
|
||||
|
||||
@ -83,7 +84,8 @@ static struct perf_event_attr cycle_attr = {
|
||||
|
||||
static void init_cycle(void)
|
||||
{
|
||||
cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0);
|
||||
cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1,
|
||||
perf_event_open_cloexec_flag());
|
||||
|
||||
if (cycle_fd < 0 && errno == ENOSYS)
|
||||
die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "util/header.h"
|
||||
#include "util/session.h"
|
||||
#include "util/tool.h"
|
||||
#include "util/cloexec.h"
|
||||
|
||||
#include "util/parse-options.h"
|
||||
#include "util/trace-event.h"
|
||||
@ -434,7 +435,8 @@ static int self_open_counters(void)
|
||||
attr.type = PERF_TYPE_SOFTWARE;
|
||||
attr.config = PERF_COUNT_SW_TASK_CLOCK;
|
||||
|
||||
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
|
||||
fd = sys_perf_event_open(&attr, 0, -1, -1,
|
||||
perf_event_open_cloexec_flag());
|
||||
|
||||
if (fd < 0)
|
||||
pr_err("Error: sys_perf_event_open() syscall returned "
|
||||
|
@ -1,7 +1,8 @@
|
||||
[event]
|
||||
fd=1
|
||||
group_fd=-1
|
||||
flags=0
|
||||
# 0 or PERF_FLAG_FD_CLOEXEC flag
|
||||
flags=0|8
|
||||
cpu=*
|
||||
type=0|1
|
||||
size=96
|
||||
|
@ -1,7 +1,8 @@
|
||||
[event]
|
||||
fd=1
|
||||
group_fd=-1
|
||||
flags=0
|
||||
# 0 or PERF_FLAG_FD_CLOEXEC flag
|
||||
flags=0|8
|
||||
cpu=*
|
||||
type=0
|
||||
size=96
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "tests.h"
|
||||
#include "debug.h"
|
||||
#include "perf.h"
|
||||
#include "cloexec.h"
|
||||
|
||||
static int fd1;
|
||||
static int fd2;
|
||||
@ -78,7 +79,8 @@ static int bp_event(void *fn, int setup_signal)
|
||||
pe.exclude_kernel = 1;
|
||||
pe.exclude_hv = 1;
|
||||
|
||||
fd = sys_perf_event_open(&pe, 0, -1, -1, 0);
|
||||
fd = sys_perf_event_open(&pe, 0, -1, -1,
|
||||
perf_event_open_cloexec_flag());
|
||||
if (fd < 0) {
|
||||
pr_debug("failed opening event %llx\n", pe.config);
|
||||
return TEST_FAIL;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "tests.h"
|
||||
#include "debug.h"
|
||||
#include "perf.h"
|
||||
#include "cloexec.h"
|
||||
|
||||
static int overflows;
|
||||
|
||||
@ -91,7 +92,8 @@ int test__bp_signal_overflow(void)
|
||||
pe.exclude_kernel = 1;
|
||||
pe.exclude_hv = 1;
|
||||
|
||||
fd = sys_perf_event_open(&pe, 0, -1, -1, 0);
|
||||
fd = sys_perf_event_open(&pe, 0, -1, -1,
|
||||
perf_event_open_cloexec_flag());
|
||||
if (fd < 0) {
|
||||
pr_debug("failed opening event %llx\n", pe.config);
|
||||
return TEST_FAIL;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "perf.h"
|
||||
#include "debug.h"
|
||||
#include "tests.h"
|
||||
#include "cloexec.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
@ -104,7 +105,8 @@ static int __test__rdpmc(void)
|
||||
sa.sa_sigaction = segfault_handler;
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
|
||||
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
|
||||
fd = sys_perf_event_open(&attr, 0, -1, -1,
|
||||
perf_event_open_cloexec_flag());
|
||||
if (fd < 0) {
|
||||
pr_err("Error: sys_perf_event_open() syscall returned "
|
||||
"with %d (%s)\n", fd, strerror(errno));
|
||||
|
57
tools/perf/util/cloexec.c
Normal file
57
tools/perf/util/cloexec.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include "util.h"
|
||||
#include "../perf.h"
|
||||
#include "cloexec.h"
|
||||
#include "asm/bug.h"
|
||||
|
||||
static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
|
||||
|
||||
static int perf_flag_probe(void)
|
||||
{
|
||||
/* use 'safest' configuration as used in perf_evsel__fallback() */
|
||||
struct perf_event_attr attr = {
|
||||
.type = PERF_COUNT_SW_CPU_CLOCK,
|
||||
.config = PERF_COUNT_SW_CPU_CLOCK,
|
||||
};
|
||||
int fd;
|
||||
int err;
|
||||
|
||||
/* check cloexec flag */
|
||||
fd = sys_perf_event_open(&attr, 0, -1, -1,
|
||||
PERF_FLAG_FD_CLOEXEC);
|
||||
err = errno;
|
||||
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
WARN_ONCE(err != EINVAL,
|
||||
"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",
|
||||
err, strerror(err));
|
||||
|
||||
/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
|
||||
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
|
||||
err = errno;
|
||||
|
||||
if (WARN_ONCE(fd < 0,
|
||||
"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",
|
||||
err, strerror(err)))
|
||||
return -1;
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long perf_event_open_cloexec_flag(void)
|
||||
{
|
||||
static bool probed;
|
||||
|
||||
if (!probed) {
|
||||
if (perf_flag_probe() <= 0)
|
||||
flag = 0;
|
||||
probed = true;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
6
tools/perf/util/cloexec.h
Normal file
6
tools/perf/util/cloexec.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __PERF_CLOEXEC_H
|
||||
#define __PERF_CLOEXEC_H
|
||||
|
||||
unsigned long perf_event_open_cloexec_flag(void);
|
||||
|
||||
#endif /* __PERF_CLOEXEC_H */
|
@ -29,6 +29,7 @@ static struct {
|
||||
bool sample_id_all;
|
||||
bool exclude_guest;
|
||||
bool mmap2;
|
||||
bool cloexec;
|
||||
} perf_missing_features;
|
||||
|
||||
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
|
||||
@ -994,7 +995,7 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
|
||||
struct thread_map *threads)
|
||||
{
|
||||
int cpu, thread;
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags = PERF_FLAG_FD_CLOEXEC;
|
||||
int pid = -1, err;
|
||||
enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE;
|
||||
|
||||
@ -1003,11 +1004,13 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
|
||||
return -ENOMEM;
|
||||
|
||||
if (evsel->cgrp) {
|
||||
flags = PERF_FLAG_PID_CGROUP;
|
||||
flags |= PERF_FLAG_PID_CGROUP;
|
||||
pid = evsel->cgrp->fd;
|
||||
}
|
||||
|
||||
fallback_missing_features:
|
||||
if (perf_missing_features.cloexec)
|
||||
flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC;
|
||||
if (perf_missing_features.mmap2)
|
||||
evsel->attr.mmap2 = 0;
|
||||
if (perf_missing_features.exclude_guest)
|
||||
@ -1076,7 +1079,10 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
|
||||
if (err != -EINVAL || cpu > 0 || thread > 0)
|
||||
goto out_close;
|
||||
|
||||
if (!perf_missing_features.mmap2 && evsel->attr.mmap2) {
|
||||
if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) {
|
||||
perf_missing_features.cloexec = true;
|
||||
goto fallback_missing_features;
|
||||
} else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) {
|
||||
perf_missing_features.mmap2 = true;
|
||||
goto fallback_missing_features;
|
||||
} else if (!perf_missing_features.exclude_guest &&
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "parse-events.h"
|
||||
#include <api/fs/fs.h>
|
||||
#include "util.h"
|
||||
#include "cloexec.h"
|
||||
|
||||
typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel);
|
||||
|
||||
@ -11,6 +12,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
|
||||
{
|
||||
struct perf_evlist *evlist;
|
||||
struct perf_evsel *evsel;
|
||||
unsigned long flags = perf_event_open_cloexec_flag();
|
||||
int err = -EAGAIN, fd;
|
||||
|
||||
evlist = perf_evlist__new();
|
||||
@ -22,14 +24,14 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
|
||||
|
||||
evsel = perf_evlist__first(evlist);
|
||||
|
||||
fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
|
||||
fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags);
|
||||
if (fd < 0)
|
||||
goto out_delete;
|
||||
close(fd);
|
||||
|
||||
fn(evsel);
|
||||
|
||||
fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
|
||||
fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags);
|
||||
if (fd < 0) {
|
||||
if (errno == EINVAL)
|
||||
err = -EINVAL;
|
||||
@ -219,7 +221,8 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
|
||||
cpu = evlist->cpus->map[0];
|
||||
}
|
||||
|
||||
fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
|
||||
fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1,
|
||||
perf_event_open_cloexec_flag());
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
ret = true;
|
||||
|
Loading…
Reference in New Issue
Block a user