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

eugene.loh at oracle.com eugene.loh at oracle.com
Sun Jun 28 23:23:30 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 | 27 ++++++++++++++++++---------
 libdtrace/dt_prov_fbt.c    | 27 ++++++++++++++++++---------
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
index c5c2a84d..e854c2ca 100644
--- a/libdtrace/dt_prov_dtrace.c
+++ b/libdtrace/dt_prov_dtrace.c
@@ -245,20 +245,23 @@ out:
 static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
 		      int *argcp, dt_argdesc_t **argvp)
 {
+	*argcp = 0;			/* no arguments */
+	*argvp = NULL;
+
+	return 0;
+}
+
+static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
+{
+        prv_data_t *datap = prp->prv_data;
 	char	*spec;
 	char	*fn = NULL;
 	int	fd;
 	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;
-
-	*argcp = 0;			/* no arguments */
-	*argvp = NULL;
+	assert(datap->event_id == -1);
 
 	/* get a uprobe specification for this probe */
 	spec = uprobe_spec(dtp, prp->desc->prb);
@@ -288,9 +291,15 @@ static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
 	if (f == NULL)
 		goto out;
 
-	rc = tp_event_info(dtp, f, 0, idp, NULL, NULL);
+	rc = tp_event_info(dtp, f, 0, &datap->event_id, NULL, NULL);
 	fclose(f);
 
+	if (rc < 0)
+		goto out;
+
+	/* attach BPF program to the uprobe */
+	rc = tp_event_attach(dtp, prp, bpf_fd);
+
 out:
 	dt_free(dtp, spec);
 	dt_free(dtp, fn);
@@ -335,6 +344,6 @@ dt_provimpl_t	dt_dtrace = {
 	.populate	= &populate,
 	.trampoline	= &trampoline,
 	.probe_info	= &probe_info,
-	.attach		= &tp_event_attach,
+	.attach		= &attach,
 	.probe_fini	= &probe_fini,
 };
diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index a58584c0..b5647d91 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -291,19 +291,22 @@ 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)
 {
+	*argcp = 0;			/* no arguments by default */
+	*argvp = NULL;
+
+	return 0;
+}
+
+static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
+{
+	prv_data_t *datap = prp->prv_data;
 	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;
-
-	*argcp = 0;			/* no arguments by default */
-	*argvp = NULL;
+	assert(datap->event_id == -1);
 
 	/*
 	 * Register the kprobe with the tracing subsystem.  This will
@@ -332,9 +335,15 @@ static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
 	if (f == NULL)
 		goto out;
 
-	rc = tp_event_info(dtp, f, 0, idp, NULL, NULL);
+	rc = tp_event_info(dtp, f, 0, &datap->event_id, NULL, NULL);
 	fclose(f);
 
+	if (rc < 0)
+		goto out;
+
+	/* attach BPF program to the kprobe */
+        rc = tp_event_attach(dtp, prp, bpf_fd);
+
 out:
 	dt_free(dtp, fn);
 
@@ -379,6 +388,6 @@ dt_provimpl_t	dt_fbt = {
 	.populate	= &populate,
 	.trampoline	= &trampoline,
 	.probe_info	= &probe_info,
-	.attach		= &tp_event_attach,
+	.attach		= &attach,
 	.probe_fini	= &probe_fini,
 };
-- 
2.18.2




More information about the DTrace-devel mailing list