[DTrace-devel] [PATCH 09/12] Defer creation of uprobes and kprobes for dtrace and fbt

eugene.loh at oracle.com eugene.loh at oracle.com
Sat Jul 11 17:38:33 PDT 2020


From: Eugene Loh <eugene.loh at oracle.com>

The dtrace and fbt providers were creating uprobes and kprobes
unnecessarily early.  Those probes are not needed for determining
argument types since these providers do not provide typed arguments.
Hence, the uprobes and kprobes do not need to be created until and
unless we are going to attach BPF programs to them.  This avoids,
for example, the unnecessary creation of many tens of thousands of
kprobes for "dtrace -lP fbt" (once that works) or "dtrace -lv".

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_prov_dtrace.c | 96 ++++++++++++++++++++------------------
 libdtrace/dt_prov_fbt.c    | 91 +++++++++++++++++++-----------------
 2 files changed, 100 insertions(+), 87 deletions(-)

diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
index dcddafa3..e1842521 100644
--- a/libdtrace/dt_prov_dtrace.c
+++ b/libdtrace/dt_prov_dtrace.c
@@ -232,57 +232,63 @@ out:
 static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
 		      int *argcp, dt_argdesc_t **argvp)
 {
-	char	*spec;
-	char	*fn = NULL;
-	int	fd;
-	FILE	*f;
-	int	rc = -ENOENT;
-	size_t	len;
-	tp_probe_t	*datap = prp->prv_data;
-
-        /* if we have an event ID, no need to retrieve it again */
-        if (datap->event_id != -1)
-		return -1;
-
 	*argcp = 0;			/* no arguments */
 	*argvp = NULL;
 
-	/* get a uprobe specification for this probe */
-	spec = uprobe_spec(dtp, prp->desc->prb);
-	if (spec == NULL)
-		return -ENOENT;
-
-	/* add a uprobe */
-	fd = open(UPROBE_EVENTS, O_WRONLY | O_APPEND);
-	if (fd == -1)
-		goto out;
-
-	rc = dprintf(fd, "p:" GROUP_FMT "/%s %s\n",
-		     GROUP_DATA, prp->desc->prb, spec);
-	close(fd);
-	if (rc == -1)
-		goto out;
-
-	len = snprintf(NULL, 0, "%s" GROUP_FMT "/%s/format",
-		       EVENTSFS, GROUP_DATA, prp->desc->prb) + 1;
-	fn = dt_alloc(dtp, len);
-	if (fn == NULL)
-		goto out;
+	return 0;
+}
 
-	snprintf(fn, len, "%s" GROUP_FMT "/%s/format",
-		 EVENTSFS, GROUP_DATA, prp->desc->prb);
-	f = fopen(fn, "r");
-	if (f == NULL)
-		goto out;
+static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
+{
+	tp_probe_t *datap = prp->prv_data;
 
-	rc = tp_event_info(dtp, f, 0, datap, NULL, NULL);
-	fclose(f);
+	if (datap->event_id == -1) {
+		char	*spec;
+		char	*fn;
+		FILE	*f;
+		size_t	len;
+		int	fd, rc = -1;
 
-out:
-	dt_free(dtp, spec);
-	dt_free(dtp, fn);
+		/* get a uprobe specification for this probe */
+		spec = uprobe_spec(dtp, prp->desc->prb);
+		if (spec == NULL)
+			return -ENOENT;
+
+		/* add a uprobe */
+		fd = open(UPROBE_EVENTS, O_WRONLY | O_APPEND);
+		if (fd != -1) {
+			rc = dprintf(fd, "p:" GROUP_FMT "/%s %s\n",
+				     GROUP_DATA, prp->desc->prb, spec);
+			close(fd);
+		}
+		dt_free(dtp, spec);
+		if (rc == -1)
+			return -ENOENT;
+
+		/* open format file */
+		len = snprintf(NULL, 0, "%s" GROUP_FMT "/%s/format",
+			       EVENTSFS, GROUP_DATA, prp->desc->prb) + 1;
+		fn = dt_alloc(dtp, len);
+		if (fn == NULL)
+			return -ENOENT;
+
+		snprintf(fn, len, "%s" GROUP_FMT "/%s/format",
+			 EVENTSFS, GROUP_DATA, prp->desc->prb);
+		f = fopen(fn, "r");
+		dt_free(dtp, fn);
+		if (f == NULL)
+			return -ENOENT;
+
+		/* read event id from format file */
+		rc = tp_event_info(dtp, f, 0, datap, NULL, NULL);
+		fclose(f);
+
+		if (rc < 0)
+			return -ENOENT;
+	}
 
-	return rc;
+	/* attach BPF program to the probe */
+	return tp_attach(dtp, prp, bpf_fd);
 }
 
 /*
@@ -317,7 +323,7 @@ dt_provimpl_t	dt_dtrace = {
 	.populate	= &populate,
 	.trampoline	= &trampoline,
 	.probe_info	= &probe_info,
-	.attach		= &tp_attach,
+	.attach		= &attach,
 	.probe_destroy	= &tp_probe_destroy,
 	.probe_fini	= &probe_fini,
 };
diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index ceefa173..6481c5a0 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -275,54 +275,61 @@ static void trampoline(dt_pcb_t *pcb)
 static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
 		      int *argcp, dt_argdesc_t **argvp)
 {
-	int	fd;
-	char	*fn;
-	size_t	len;
-	FILE	*f;
-	int	rc = -1;
-	tp_probe_t	*datap = prp->prv_data;
-
-        /* if we have an event ID, no need to retrieve it again */
-        if (datap->event_id != -1)
-		return -1;
-
 	*argcp = 0;			/* no arguments by default */
 	*argvp = NULL;
 
-	/*
-	 * Register the kprobe with the tracing subsystem.  This will
-	 * create a tracepoint event.
-	 */
-	fd = open(KPROBE_EVENTS, O_WRONLY | O_APPEND);
-	if (fd == -1)
-		return -1;
-
-	rc = dprintf(fd, "%c:" FBT_GROUP_FMT "/%s %s\n",
-		     prp->desc->prb[0] == 'e' ? 'p' : 'r', FBT_GROUP_DATA,
-		     prp->desc->fun, prp->desc->fun);
-	close(fd);
-	if (rc == -1)
-		return -1;
-
-	len = snprintf(NULL, 0, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
-		       FBT_GROUP_DATA, prp->desc->fun) + 1;
-	fn = dt_alloc(dtp, len);
-	if (fn == NULL)
-		goto out;
+	return 0;
+}
 
-	snprintf(fn, len, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
-		 FBT_GROUP_DATA, prp->desc->fun);
-	f = fopen(fn, "r");
-	if (f == NULL)
-		goto out;
+static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
+{
+	tp_probe_t *datap = prp->prv_data;
 
-	rc = tp_event_info(dtp, f, 0, datap, NULL, NULL);
-	fclose(f);
+	if (datap->event_id == -1) {
+		char	*fn;
+		FILE	*f;
+		size_t	len;
+		int	fd, rc = -1;
 
-out:
-	dt_free(dtp, fn);
+		/*
+		 * Register the kprobe with the tracing subsystem.  This will
+		 * create a tracepoint event.
+		 */
+		fd = open(KPROBE_EVENTS, O_WRONLY | O_APPEND);
+		if (fd == -1)
+			return -ENOENT;
+
+		rc = dprintf(fd, "%c:" FBT_GROUP_FMT "/%s %s\n",
+			     prp->desc->prb[0] == 'e' ? 'p' : 'r', FBT_GROUP_DATA,
+			     prp->desc->fun, prp->desc->fun);
+		close(fd);
+		if (rc == -1)
+			return -ENOENT;
+
+		/* open format file */
+		len = snprintf(NULL, 0, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
+			       FBT_GROUP_DATA, prp->desc->fun) + 1;
+		fn = dt_alloc(dtp, len);
+		if (fn == NULL)
+			return -ENOENT;
+
+		snprintf(fn, len, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
+			 FBT_GROUP_DATA, prp->desc->fun);
+		f = fopen(fn, "r");
+		dt_free(dtp, fn);
+		if (f == NULL)
+			return -ENOENT;
+
+		/* read event id from format file */
+		rc = tp_event_info(dtp, f, 0, datap, NULL, NULL);
+		fclose(f);
+
+		if (rc < 0)
+			return -ENOENT;
+	}
 
-	return rc;
+	/* attach BPF program to the probe */
+	return tp_attach(dtp, prp, bpf_fd);
 }
 
 /*
@@ -358,7 +365,7 @@ dt_provimpl_t	dt_fbt = {
 	.populate	= &populate,
 	.trampoline	= &trampoline,
 	.probe_info	= &probe_info,
-	.attach		= &tp_attach,
+	.attach		= &attach,
 	.probe_destroy	= &tp_probe_destroy,
 	.probe_fini	= &probe_fini,
 };
-- 
2.18.2




More information about the DTrace-devel mailing list