[DTrace-devel] [PATCH 05/13] Make a provider-specific attach()
eugene.loh at oracle.com
eugene.loh at oracle.com
Wed Jul 1 19:41:10 PDT 2020
From: Eugene Loh <eugene.loh at oracle.com>
We used dt_bpf_attach() to attach BPF programs to probes. This
was suitable for the tracepoint-like providers to date, which used
established event IDs to enable probes to get their file descriptors
and then attach the BPF program fd; however, the approach is
inadequate for some other providers.
Remove dt_bpf_attach(), instead calling a provider-specific attach()
function.
Note that many providers actually are tracepoint-like. So, they can
share a common attach() function. That function, tp_event_attach(),
is supplied by the sdt provider in the same way as that provider
supplies the common tp_event_info() function.
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_bpf.c | 37 +++----------------------------------
libdtrace/dt_prov_dtrace.c | 1 +
libdtrace/dt_prov_fbt.c | 1 +
libdtrace/dt_prov_sdt.c | 29 +++++++++++++++++++++++++++++
libdtrace/dt_prov_syscall.c | 1 +
libdtrace/dt_provider.h | 3 +++
6 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index d5282b94..573c8357 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -317,39 +317,6 @@ dt_bpf_load_prog(dtrace_hdl_t *dtp, const dt_probe_t *prp,
return rc;
}
-/*
- * Attach a BPF program to a probe.
- */
-int
-dt_bpf_attach(dtrace_hdl_t *dtp, dt_probe_t *prp, int bpf_fd)
-{
- /*
- * If we have not yet created a perf event for this probe, do that now
- * and cache the file descriptor so we only need to do this once.
- */
- if (prp->event_fd == -1) {
- int fd;
- struct perf_event_attr attr = { 0, };
-
- attr.type = PERF_TYPE_TRACEPOINT;
- attr.sample_type = PERF_SAMPLE_RAW;
- attr.sample_period = 1;
- attr.wakeup_events = 1;
- attr.config = prp->event_id;
-
- fd = perf_event_open(&attr, -1, 0, -1, 0);
- if (fd < 0)
- return dt_set_errno(dtp, errno);
-
- prp->event_fd = fd;
- }
-
- if (ioctl(prp->event_fd, PERF_EVENT_IOC_SET_BPF, bpf_fd) < 0)
- return dt_set_errno(dtp, errno);
-
- return 0;
-}
-
int
dt_bpf_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp,
void *data)
@@ -369,7 +336,9 @@ dt_bpf_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp,
if (fd < 0)
return fd;
- rc = dt_bpf_attach(dtp, prp, fd);
+ if (!prp->prov->impl->attach)
+ return -1;
+ rc = prp->prov->impl->attach(dtp, prp, fd);
if (rc < 0)
return rc;
diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
index fe9759de..34c99388 100644
--- a/libdtrace/dt_prov_dtrace.c
+++ b/libdtrace/dt_prov_dtrace.c
@@ -317,5 +317,6 @@ dt_provimpl_t dt_dtrace = {
.populate = &populate,
.trampoline = &trampoline,
.probe_info = &probe_info,
+ .attach = &tp_event_attach,
.probe_fini = &probe_fini,
};
diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index 1aa3ca3c..cb80082e 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -358,5 +358,6 @@ dt_provimpl_t dt_fbt = {
.populate = &populate,
.trampoline = &trampoline,
.probe_info = &probe_info,
+ .attach = &tp_event_attach,
.probe_fini = &probe_fini,
};
diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
index 6d99653a..1a445c65 100644
--- a/libdtrace/dt_prov_sdt.c
+++ b/libdtrace/dt_prov_sdt.c
@@ -19,13 +19,16 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/ioctl.h>
#include <linux/bpf.h>
+#include <linux/perf_event.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <bpf_asm.h>
#include "dt_impl.h"
+#include "dt_bpf.h"
#include "dt_bpf_builtins.h"
#include "dt_provider.h"
#include "dt_probe.h"
@@ -223,6 +226,31 @@ done:
return 0;
}
+int tp_event_attach(dtrace_hdl_t *dtp, dt_probe_t *prp, int bpf_fd)
+{
+ if (prp->event_fd == -1) {
+ int fd;
+ struct perf_event_attr attr = { 0, };
+
+ attr.type = PERF_TYPE_TRACEPOINT;
+ attr.sample_type = PERF_SAMPLE_RAW;
+ attr.sample_period = 1;
+ attr.wakeup_events = 1;
+ attr.config = prp->event_id;
+
+ fd = perf_event_open(&attr, -1, 0, -1, 0);
+ if (fd < 0)
+ return dt_set_errno(dtp, errno);
+
+ prp->event_fd = fd;
+ }
+
+ if (ioctl(prp->event_fd, PERF_EVENT_IOC_SET_BPF, bpf_fd) < 0)
+ return dt_set_errno(dtp, errno);
+
+ return 0;
+}
+
/*
* The PROBE_LIST file lists all tracepoints in a <group>:<name> format.
* We need to ignore these groups:
@@ -409,5 +437,6 @@ dt_provimpl_t dt_sdt = {
.prog_type = BPF_PROG_TYPE_TRACEPOINT,
.populate = &populate,
.trampoline = &trampoline,
+ .attach = &tp_event_attach,
.probe_info = &probe_info,
};
diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
index 0b0ca954..cb54ce5a 100644
--- a/libdtrace/dt_prov_syscall.c
+++ b/libdtrace/dt_prov_syscall.c
@@ -271,4 +271,5 @@ dt_provimpl_t dt_syscall = {
.populate = &populate,
.trampoline = &trampoline,
.probe_info = &probe_info,
+ .attach = &tp_event_attach,
};
diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
index 50f663f1..acd01983 100644
--- a/libdtrace/dt_provider.h
+++ b/libdtrace/dt_provider.h
@@ -65,12 +65,15 @@ typedef struct dt_provimpl {
int (*provide)(dtrace_hdl_t *dtp, /* provide probes */
const dtrace_probedesc_t *pdp);
void (*trampoline)(dt_pcb_t *pcb); /* generate BPF trampoline */
+ int (*attach)(dtrace_hdl_t *dtp, /* attach BPF program to probe */
+ struct dt_probe *prp, int bpf_fd);
int (*probe_fini)(dtrace_hdl_t *dtp, /* probe cleanup */
struct dt_probe *prb);
} dt_provimpl_t;
extern int tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, int *idp,
int *argcp, dt_argdesc_t **argvp);
+extern int tp_event_attach(dtrace_hdl_t *dtp, struct dt_probe *prp, int bpf_fd);
extern dt_provimpl_t dt_dtrace;
extern dt_provimpl_t dt_fbt;
--
2.18.2
More information about the DTrace-devel
mailing list