[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220225103114.144239-5-nakamura.shun@fujitsu.com>
Date: Fri, 25 Feb 2022 19:31:11 +0900
From: Shunsuke <nakamura.shun@...itsu.com>
To: peterz@...radead.org, mingo@...hat.com, acme@...nel.org,
mark.rutland@....com, alexander.shishkin@...ux.intel.com,
jolsa@...hat.com, namhyung@...nel.org
Cc: linux-kernel@...r.kernel.org, linux-perf-users@...r.kernel.org,
Shunsuke Nakamura <nakamura.shun@...itsu.com>
Subject: [RFC PATCH 4/7] libperf: Add perf_evsel__set_signal() functions
From: Shunsuke Nakamura <nakamura.shun@...itsu.com>
Add the following functions:
perf_evsel__set_signal()
perf_evsel__set_signal_cpu()
to set the parameters to get the overflow signal.
Signed-off-by: Shunsuke Nakamura <nakamura.shun@...itsu.com>
---
tools/lib/perf/Documentation/libperf.txt | 4 +
tools/lib/perf/evsel.c | 105 +++++++++++++++++++++++
tools/lib/perf/include/perf/evsel.h | 6 ++
tools/lib/perf/libperf.map | 2 +
4 files changed, 117 insertions(+)
diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt
index 8f523293fb9d..d0aa57c6ca97 100644
--- a/tools/lib/perf/Documentation/libperf.txt
+++ b/tools/lib/perf/Documentation/libperf.txt
@@ -151,6 +151,10 @@ SYNOPSIS
int cpu_map_idx);
int perf_evsel__period(struct perf_evsel *evsel, int period);
int perf_evsel__period_cpu(struct perf_evsel *evsel, int period, int cpu_map_idx);
+ int perf_evsel__set_signal(struct perf_evsel *evsel, int owner_type, unsigned int signal,
+ struct sigaction *sig);
+ int perf_evsel__set_signal_cpu(struct perf_evsel *evsel, int owner_type, unsigned int signal,
+ struct sigaction *sig, int cpu_map_idx);
struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel);
struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index 8348545874e4..991ab04112b1 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -1,4 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
@@ -16,6 +19,9 @@
#include <internal/lib.h>
#include <linux/string.h>
#include <sys/ioctl.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/types.h>
#include <sys/mman.h>
#include <asm/bug.h>
@@ -351,6 +357,28 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
return 0;
}
+static int perf_evsel__run_fcntl(struct perf_evsel *evsel,
+ unsigned int cmd, unsigned long arg,
+ int cpu_map_idx)
+{
+ int thread;
+
+ for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
+ int err;
+ int *fd = FD(evsel, cpu_map_idx, thread);
+
+ if (!fd || *fd < 0)
+ return -1;
+
+ err = fcntl(*fd, cmd, arg);
+
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx)
{
return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0, cpu_map_idx);
@@ -437,6 +465,83 @@ int perf_evsel__period(struct perf_evsel *evsel, __u64 period)
return err;
}
+int perf_evsel__set_signal_cpu(struct perf_evsel *evsel, int owner_type, unsigned int signal,
+ struct sigaction *sig, int cpu_map_idx)
+{
+ int err = 0;
+ struct f_owner_ex owner;
+
+ switch (owner_type) {
+ case F_OWNER_PID:
+ owner.pid = getpid();
+ break;
+ case F_OWNER_TID:
+ owner.pid = syscall(SYS_gettid);
+ break;
+ default:
+ return -1;
+ }
+
+ err = perf_evsel__run_fcntl(evsel, F_SETFL, (O_RDWR | O_NONBLOCK | O_ASYNC), cpu_map_idx);
+ if (err)
+ return err;
+
+ err = perf_evsel__run_fcntl(evsel, F_SETSIG, signal, cpu_map_idx);
+ if (err)
+ return err;
+
+ err = perf_evsel__run_fcntl(evsel, F_SETOWN_EX, (unsigned long)&owner, cpu_map_idx);
+ if (err)
+ return err;
+
+ err = sigaction(signal, sig, NULL);
+ if (err)
+ return err;
+
+ return err;
+}
+
+int perf_evsel__set_signal(struct perf_evsel *evsel, int owner_type, unsigned int signal,
+ struct sigaction *sig)
+{
+ int i;
+ int err = 0;
+ struct f_owner_ex owner;
+
+ switch (owner_type) {
+ case F_OWNER_PID:
+ owner.pid = getpid();
+ break;
+ case F_OWNER_TID:
+ owner.pid = syscall(SYS_gettid);
+ break;
+ default:
+ return -1;
+ }
+
+ owner.type = owner_type;
+
+ for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++) {
+ err = perf_evsel__run_fcntl(evsel, F_SETFL, (O_RDWR | O_NONBLOCK | O_ASYNC), i);
+ if (err)
+ return err;
+
+ err = perf_evsel__run_fcntl(evsel, F_SETSIG, signal, i);
+ if (err)
+ return err;
+
+ err = perf_evsel__run_fcntl(evsel, F_SETOWN_EX, (unsigned long)&owner, i);
+ if (err)
+ return err;
+ }
+
+ err = sigaction(signal, sig, NULL);
+ if (err)
+ return err;
+
+ return err;
+}
+
int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter)
{
int err = 0, i;
diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h
index 9ec24a5f5f9f..15768fc91910 100644
--- a/tools/lib/perf/include/perf/evsel.h
+++ b/tools/lib/perf/include/perf/evsel.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <perf/core.h>
#include <stdbool.h>
+#include <signal.h>
#include <linux/types.h>
struct perf_evsel;
@@ -43,6 +44,11 @@ LIBPERF_API int perf_evsel__refresh_cpu(struct perf_evsel *evsel, int refresh,
int cpu_map_idx);
LIBPERF_API int perf_evsel__period(struct perf_evsel *evsel, __u64 period);
LIBPERF_API int perf_evsel__period_cpu(struct perf_evsel *evsel, __u64 period, int cpu_map_idx);
+LIBPERF_API int perf_evsel__set_signal(struct perf_evsel *evsel, int owner_type,
+ unsigned int signal, struct sigaction *sig);
+LIBPERF_API int perf_evsel__set_signal_cpu(struct perf_evsel *evsel, int owner_type,
+ unsigned int signal, struct sigaction *sig,
+ int cpu_map_idx);
LIBPERF_API struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel);
LIBPERF_API struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
LIBPERF_API struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map
index 83ecbce9cfbb..5e04fe2b611c 100644
--- a/tools/lib/perf/libperf.map
+++ b/tools/lib/perf/libperf.map
@@ -32,6 +32,8 @@ LIBPERF_0.0.1 {
perf_evsel__refresh_cpu;
perf_evsel__period;
perf_evsel__period_cpu;
+ perf_evsel__set_signal;
+ perf_evsel__set_signal_cpu;
perf_evsel__cpus;
perf_evsel__threads;
perf_evsel__attr;
--
2.31.1
Powered by blists - more mailing lists