[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