[DTrace-devel] [PATCH 06/13] Add provider-dependent struct in dt_probe_t
eugene.loh at oracle.com
eugene.loh at oracle.com
Wed Jul 1 19:41:11 PDT 2020
From: Eugene Loh <eugene.loh at oracle.com>
The dt_probe_t struct had members like event_id and event_fd.
This made sense for the providers we were supporting, since they
were all tracepoint-like. For future providers, however, those
members might not make sense and others will be needed. Therefore,
replace event_id and event_fd with an opaque pointer to a
provider-dependent struct.
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_probe.c | 19 +++-------
libdtrace/dt_probe.h | 4 +--
libdtrace/dt_prov_dtrace.c | 42 +++++++++++++++-------
libdtrace/dt_prov_fbt.c | 41 +++++++++++++++------
libdtrace/dt_prov_sdt.c | 72 +++++++++++++++++++++++--------------
libdtrace/dt_prov_syscall.c | 34 +++++++++++++-----
libdtrace/dt_provider.h | 6 ++--
7 files changed, 143 insertions(+), 75 deletions(-)
diff --git a/libdtrace/dt_probe.c b/libdtrace/dt_probe.c
index be407dd2..496ba11e 100644
--- a/libdtrace/dt_probe.c
+++ b/libdtrace/dt_probe.c
@@ -505,6 +505,7 @@ dt_probe_destroy(dt_probe_t *prp)
if (prp->prov && prp->prov->impl && prp->prov->impl->probe_fini)
prp->prov->impl->probe_fini(dtp, prp);
+ dt_free(dtp, prp->prv_data);
dt_node_list_free(&prp->nargs);
dt_node_list_free(&prp->xargs);
@@ -665,7 +666,8 @@ dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp)
}
dt_probe_t *
-dt_probe_insert(dtrace_hdl_t *dtp, dt_provider_t *prov, const char *prv,
+dt_probe_insert(dtrace_hdl_t *dtp, dt_provider_t *prov, const void *prv_data,
+ const char *prv,
const char *mod, const char *fun, const char *prb)
{
dt_probe_t *prp;
@@ -711,8 +713,7 @@ dt_probe_insert(dtrace_hdl_t *dtp, dt_provider_t *prov, const char *prv,
prp->desc = desc;
prp->prov = prov;
- prp->event_id = -1;
- prp->event_fd = -1;
+ prp->prv_data = prv_data;
dt_htab_insert(dtp->dt_byprv, prp);
dt_htab_insert(dtp->dt_bymod, prp);
@@ -872,26 +873,16 @@ dt_probe_delete(dtrace_hdl_t *dtp, dt_probe_t *prp)
static void
dt_probe_args_info(dtrace_hdl_t *dtp, dt_probe_t *prp)
{
- int id = DTRACE_IDNONE;
int argc = 0;
dt_argdesc_t *argv = NULL;
int i, nc, xc;
dtrace_typeinfo_t dtt;
- /*
- * If we already have an event ID information for this probe, there is
- * no need to retrieve it again.
- */
- if (prp->event_id != -1)
- return;
-
if (!prp->prov->impl->probe_info)
return;
- if (prp->prov->impl->probe_info(dtp, prp, &id, &argc, &argv) < 0)
+ if (prp->prov->impl->probe_info(dtp, prp, &argc, &argv) < 0)
return;
- if (id > 0)
- prp->event_id = id;
if (!argc || !argv)
return;
diff --git a/libdtrace/dt_probe.h b/libdtrace/dt_probe.h
index 7feeeff2..92768f9b 100644
--- a/libdtrace/dt_probe.h
+++ b/libdtrace/dt_probe.h
@@ -38,8 +38,7 @@ typedef struct dt_probe {
struct dt_hentry he_fun; /* function name htab links */
struct dt_hentry he_prb; /* probe name htab link */
struct dt_hentry he_fqn; /* fully qualified name htab link */
- int event_id; /* tracing event id */
- int event_fd; /* perf event file descriptor */
+ void *prv_data; /* provider-specific data */
dt_ident_t *pr_ident; /* pointer to probe identifier */
const char *pr_name; /* pointer to name component */
dt_node_t *nargs; /* native argument list */
@@ -70,6 +69,7 @@ extern int dt_probe_define(dt_provider_t *, dt_probe_t *,
extern dt_node_t *dt_probe_tag(dt_probe_t *, uint_t, dt_node_t *);
extern dt_probe_t *dt_probe_insert(dtrace_hdl_t *dtp, dt_provider_t *prov,
+ const void *prv_data,
const char *prv, const char *mod,
const char *fun, const char *prb);
extern dt_probe_t *dt_probe_lookup(dtrace_hdl_t *dtp,
diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
index 34c99388..c5c2a84d 100644
--- a/libdtrace/dt_prov_dtrace.c
+++ b/libdtrace/dt_prov_dtrace.c
@@ -15,6 +15,11 @@
#include "dt_provider.h"
#include "dt_probe.h"
+typedef struct prv_data {
+ int event_id;
+ int event_fd;
+} prv_data_t;
+
static const char prvname[] = "dtrace";
static const char modname[] = "";
static const char funname[] = "";
@@ -34,18 +39,26 @@ static const dtrace_pattr_t pattr = {
static int populate(dtrace_hdl_t *dtp)
{
dt_provider_t *prv;
- int n = 0;
+ int i, n = 0;
+ char *prbnames[] = { "BEGIN", "END", "ERROR" };
prv = dt_provider_create(dtp, prvname, &dt_dtrace, &pattr);
if (prv == NULL)
return 0;
- if (dt_probe_insert(dtp, prv, prvname, modname, funname, "BEGIN"))
- n++;
- if (dt_probe_insert(dtp, prv, prvname, modname, funname, "END"))
- n++;
- if (dt_probe_insert(dtp, prv, prvname, modname, funname, "ERROR"))
- n++;
+ for (i = 0; i < sizeof (prbnames) / sizeof (*prbnames); i++) {
+ prv_data_t *datap;
+
+ datap = dt_zalloc(dtp, sizeof (prv_data_t));
+ if (datap == NULL)
+ continue;
+ datap->event_id = -1;
+ datap->event_fd = -1;
+ if (dt_probe_insert(dtp, prv, datap, prvname, modname, funname, prbnames[i]))
+ n++;
+ else
+ dt_free(dtp, datap);
+ }
return n;
}
@@ -230,7 +243,7 @@ out:
}
static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
- int *idp, int *argcp, dt_argdesc_t **argvp)
+ int *argcp, dt_argdesc_t **argvp)
{
char *spec;
char *fn = NULL;
@@ -238,8 +251,12 @@ static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
FILE *f;
int rc = -ENOENT;
size_t len;
+ int *idp = &((prv_data_t *)(prp->prv_data))->event_id;
+
+ /* if we have an event ID, no need to retrieve it again */
+ if (*idp != -1)
+ return -1;
- *idp = -1;
*argcp = 0; /* no arguments */
*argvp = NULL;
@@ -295,10 +312,11 @@ out:
static int probe_fini(dtrace_hdl_t *dtp, dt_probe_t *prp)
{
int fd;
+ prv_data_t *datap = prp->prv_data;
- if (prp->event_fd != -1) {
- close(prp->event_fd);
- prp->event_fd = -1;
+ if (datap->event_fd != -1) {
+ close(datap->event_fd);
+ datap->event_fd = -1;
}
fd = open(UPROBE_EVENTS, O_WRONLY | O_APPEND);
diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index cb80082e..a58584c0 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -37,6 +37,11 @@
#include "dt_probe.h"
#include "dt_pt_regs.h"
+typedef struct prv_data {
+ int event_id;
+ int event_fd;
+} prv_data_t;
+
static const char prvname[] = "fbt";
static const char modname[] = "vmlinux";
@@ -65,9 +70,10 @@ static int populate(dtrace_hdl_t *dtp)
char buf[256];
char *p;
const char *mod = modname;
- int n = 0;
+ int i, n = 0;
dtrace_syminfo_t sip;
dtrace_probedesc_t pd;
+ char *prbnames[] = { "entry", "return" };
prv = dt_provider_create(dtp, prvname, &dt_fbt, &pattr);
if (prv == NULL)
@@ -136,10 +142,20 @@ static int populate(dtrace_hdl_t *dtp)
if (dt_probe_lookup(dtp, &pd) != NULL)
continue;
- if (dt_probe_insert(dtp, prv, prvname, mod, buf, "entry"))
- n++;
- if (dt_probe_insert(dtp, prv, prvname, mod, buf, "return"))
- n++;
+ for (i = 0; i < sizeof (prbnames) / sizeof (*prbnames); i++) {
+ prv_data_t *datap;
+
+ datap = dt_zalloc(dtp, sizeof (prv_data_t));
+ if (datap == NULL)
+ continue;
+ datap->event_id = -1;
+ datap->event_fd = -1;
+ if (dt_probe_insert(dtp, prv, datap, prvname, mod,
+ buf, prbnames[i]))
+ n++;
+ else
+ dt_free(dtp, datap);
+ }
}
fclose(f);
@@ -273,15 +289,19 @@ static void trampoline(dt_pcb_t *pcb)
}
static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
- int *idp, int *argcp, dt_argdesc_t **argvp)
+ int *argcp, dt_argdesc_t **argvp)
{
int fd;
char *fn;
size_t len;
FILE *f;
int rc = -1;
+ int *idp = &((prv_data_t *)(prp->prv_data))->event_id;
+
+ /* if we have an event ID, no need to retrieve it again */
+ if (*idp != -1)
+ return -1;
- *idp = -1;
*argcp = 0; /* no arguments by default */
*argvp = NULL;
@@ -335,10 +355,11 @@ out:
static int probe_fini(dtrace_hdl_t *dtp, dt_probe_t *prp)
{
int fd;
+ prv_data_t *datap = prp->prv_data;
- if (prp->event_fd != -1) {
- close(prp->event_fd);
- prp->event_fd = -1;
+ if (datap->event_fd != -1) {
+ close(datap->event_fd);
+ datap->event_fd = -1;
}
fd = open(KPROBE_EVENTS, O_WRONLY | O_APPEND);
diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
index 1a445c65..9a76f029 100644
--- a/libdtrace/dt_prov_sdt.c
+++ b/libdtrace/dt_prov_sdt.c
@@ -34,6 +34,11 @@
#include "dt_probe.h"
#include "dt_pt_regs.h"
+typedef struct prv_data {
+ int event_id;
+ int event_fd;
+} prv_data_t;
+
static const char prvname[] = "sdt";
static const char modname[] = "vmlinux";
@@ -226,29 +231,31 @@ done:
return 0;
}
-int tp_event_attach(dtrace_hdl_t *dtp, dt_probe_t *prp, int bpf_fd)
+int tp_event_attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
{
- if (prp->event_fd == -1) {
- int fd;
- struct perf_event_attr attr = { 0, };
+ prv_data_t *datap = prp->prv_data;
+
+ if (datap->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;
+ attr.type = PERF_TYPE_TRACEPOINT;
+ attr.sample_type = PERF_SAMPLE_RAW;
+ attr.sample_period = 1;
+ attr.wakeup_events = 1;
+ attr.config = datap->event_id;
- fd = perf_event_open(&attr, -1, 0, -1, 0);
- if (fd < 0)
- return dt_set_errno(dtp, errno);
+ fd = perf_event_open(&attr, -1, 0, -1, 0);
+ if (fd < 0)
+ return dt_set_errno(dtp, errno);
- prp->event_fd = fd;
- }
+ datap->event_fd = fd;
+ }
- if (ioctl(prp->event_fd, PERF_EVENT_IOC_SET_BPF, bpf_fd) < 0)
- return dt_set_errno(dtp, errno);
+ if (ioctl(datap->event_fd, PERF_EVENT_IOC_SET_BPF, bpf_fd) < 0)
+ return dt_set_errno(dtp, errno);
- return 0;
+ return 0;
}
/*
@@ -275,8 +282,10 @@ static int populate(dtrace_hdl_t *dtp)
return 0;
while (fgets(buf, sizeof(buf), f)) {
- int dummy;
- char str[sizeof(buf)];
+ int dummy;
+ char str[sizeof(buf)];
+ const char *mod, *prb;
+ prv_data_t *datap;
p = strchr(buf, '\n');
if (p)
@@ -301,13 +310,21 @@ static int populate(dtrace_hdl_t *dtp)
strcmp(buf, UPROBES) == 0)
continue;
- if (dt_probe_insert(dtp, prv, prvname, buf, "", p))
- n++;
+ mod = buf;
+ prb = p;
} else {
- if (dt_probe_insert(dtp, prv, prvname, modname, "",
- buf))
- n++;
+ mod = modname;
+ prb = buf;
}
+ datap = dt_zalloc(dtp, sizeof (prv_data_t));
+ if (datap == NULL)
+ continue;
+ datap->event_id = -1;
+ datap->event_fd = -1;
+ if (dt_probe_insert(dtp, prv, datap, prvname, mod, "", prb))
+ n++;
+ else
+ dt_free(dtp, datap);
}
fclose(f);
@@ -408,13 +425,16 @@ static void trampoline(dt_pcb_t *pcb)
}
static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
- int *idp, int *argcp, dt_argdesc_t **argvp)
+ int *argcp, dt_argdesc_t **argvp)
{
FILE *f;
char fn[256];
int rc;
+ int *idp = &((prv_data_t *)(prp->prv_data))->event_id;
- *idp = -1;
+ /* if we have an event ID, no need to retrieve it again */
+ if (*idp != -1)
+ return -1;
strcpy(fn, EVENTSFS);
strcat(fn, prp->desc->mod);
diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
index cb54ce5a..ecab4545 100644
--- a/libdtrace/dt_prov_syscall.c
+++ b/libdtrace/dt_prov_syscall.c
@@ -35,6 +35,11 @@
#include "dt_probe.h"
#include "dt_pt_regs.h"
+typedef struct prv_data {
+ int event_id;
+ int event_fd;
+} prv_data_t;
+
static const char prvname[] = "syscall";
static const char modname[] = "vmlinux";
@@ -85,6 +90,7 @@ static int populate(dtrace_hdl_t *dtp)
while (fgets(buf, sizeof(buf), f)) {
char *p;
+ char *prb;
/* Here buf is "group:event". */
p = strchr(buf, '\n');
@@ -107,22 +113,31 @@ static int populate(dtrace_hdl_t *dtp)
p = buf;
if (memcmp(p, PROV_PREFIX, sizeof(PROV_PREFIX) - 1) != 0)
continue;
-
p += sizeof(PROV_PREFIX) - 1;
+
/*
* Now p will be just "event", and we are only interested in
* events that match "sys_enter_*" or "sys_exit_*".
*/
+ prb = NULL;
if (!memcmp(p, ENTRY_PREFIX, sizeof(ENTRY_PREFIX) - 1)) {
p += sizeof(ENTRY_PREFIX) - 1;
- if (dt_probe_insert(dtp, prv, prvname, modname, p,
- "entry"))
- n++;
+ prb = "entry";
} else if (!memcmp(p, EXIT_PREFIX, sizeof(EXIT_PREFIX) - 1)) {
p += sizeof(EXIT_PREFIX) - 1;
- if (dt_probe_insert(dtp, prv, prvname, modname, p,
- "return"))
+ prb = "return";
+ }
+ if (prb != NULL) {
+ prv_data_t *datap = dt_zalloc(dtp, sizeof (prv_data_t));
+
+ if (datap == NULL)
+ continue;
+ datap->event_id = -1;
+ datap->event_fd = -1;
+ if (dt_probe_insert(dtp, prv, datap, prvname, modname, p, prb))
n++;
+ else
+ dt_free(dtp, datap);
}
}
@@ -235,13 +250,16 @@ static void trampoline(dt_pcb_t *pcb)
}
static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
- int *idp, int *argcp, dt_argdesc_t **argvp)
+ int *argcp, dt_argdesc_t **argvp)
{
FILE *f;
char fn[256];
int rc;
+ int *idp = &((prv_data_t *)(prp->prv_data))->event_id;
- *idp = -1;
+ /* if we have an event ID, no need to retrieve it again */
+ if (*idp != -1)
+ return -1;
/*
* We know that the probe name is either "entry" or "return", so we can
diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
index acd01983..9ea89898 100644
--- a/libdtrace/dt_provider.h
+++ b/libdtrace/dt_provider.h
@@ -61,19 +61,19 @@ typedef struct dt_provimpl {
int (*populate)(dtrace_hdl_t *dtp); /* register probes */
int (*probe_info)(dtrace_hdl_t *dtp, /* get probe info */
const struct dt_probe *prp,
- int *idp, int *argcp, dt_argdesc_t **argvp);
+ int *argcp, dt_argdesc_t **argvp);
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);
+ const 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 int tp_event_attach(dtrace_hdl_t *dtp, const 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