[DTrace-devel] [PATCH v2 16/38] Add provider-specific probe_add_clause() for USDT tracing

eugene.loh at oracle.com eugene.loh at oracle.com
Fri Jul 19 04:02:29 UTC 2024


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

To support USDT tracing of processes that start after the dtrace
session starts, we will move to a new USDT trampoline.  Based on
the firing pid, it will look a bit mask up in a BPF map.  It will
walk all its clauses, calling conditionally those clauses that are
in the map for that particular pid (overlying probe).

Thus, for each underlying probe, we need a list of clauses.

There is already a dt_probe_add_clause().  It adds clauses to
overlying probes.

Add the ability for a provider to supply a provider-specific
probe_add_clause() function.

Have the pid and USDT providers supply such a function that adds
a clause to an overlying probe's underlying probes.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_impl.h        |  5 +++++
 libdtrace/dt_probe.c       |  7 ++-----
 libdtrace/dt_prov_uprobe.c | 34 ++++++++++++++++++++++++++++++++++
 libdtrace/dt_provider.h    |  3 +++
 4 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index d15c238c..2132eda2 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -283,6 +283,11 @@ typedef struct dt_percpu_drops {
 
 typedef uint32_t dt_version_t;		/* encoded version (see below) */
 
+typedef struct dt_probe_clause {
+	dt_list_t	list;
+	dt_ident_t	*clause;
+} dt_probe_clause_t;
+
 struct dtrace_hdl {
 	const dtrace_vector_t *dt_vector; /* library vector, if vectored open */
 	void *dt_varg;	/* vector argument, if vectored open */
diff --git a/libdtrace/dt_probe.c b/libdtrace/dt_probe.c
index 0b53121a..48b02e11 100644
--- a/libdtrace/dt_probe.c
+++ b/libdtrace/dt_probe.c
@@ -24,11 +24,6 @@
 #include <dt_list.h>
 #include <dt_bpf.h>
 
-typedef struct dt_probe_clause {
-	dt_list_t	list;
-	dt_ident_t	*clause;
-} dt_probe_clause_t;
-
 typedef struct dt_probe_dependent {
 	dt_list_t	list;
 	dt_probe_t	*probe;
@@ -1359,6 +1354,8 @@ dt_probe_add_clause(dtrace_hdl_t *dtp, dt_probe_t *prp, dt_ident_t *idp)
 		pcp->clause = idp;
 
 	dt_list_append(&prp->clauses, pcp);
+	if (prp->prov->impl->probe_add_clause)
+		return prp->prov->impl->probe_add_clause(dtp, prp, idp);
 
 	return 0;
 }
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index c77063a8..5dbd75e3 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -129,6 +129,38 @@ static void probe_destroy(dtrace_hdl_t *dtp, void *datap)
 	free_probe_list(dtp, datap);
 }
 
+/*
+ * Add clause to probe.
+ */
+static int probe_add_clause(dtrace_hdl_t *dtp, dt_probe_t *prp, dt_ident_t *idp)
+{
+	const list_probe_t	*pup;
+
+	for (pup = prp->prv_data; pup != NULL; pup = dt_list_next(pup)) {
+		dt_probe_t		*uprp = pup->probe;
+		dt_probe_clause_t	*prev, *pcp;
+
+		/*
+		 * Check if the clause is already there.  Since the clauses
+		 * are added "in order," we only need to check the previous
+		 * entry.
+		 */
+		prev = dt_list_prev(&uprp->clauses);
+		if (prev && strcmp(prev->clause->di_name, idp->di_name) == 0)
+			continue;
+
+		/*
+		 * Add the clause.
+		 */
+		pcp = dt_zalloc(dtp, sizeof(dt_probe_clause_t));
+		if (pcp == NULL)
+			return -1;
+		pcp->clause = idp;
+		dt_list_append(&uprp->clauses, pcp);
+	}
+
+	return 0;
+}
 
 /*
  * Look up or create an underlying (real) probe, corresponding directly to a
@@ -811,6 +843,7 @@ dt_provimpl_t	dt_pid = {
 	.prog_type	= BPF_PROG_TYPE_UNSPEC,
 	.provide_probe	= &provide_pid_probe,
 	.enable		= &enable_pid,
+	.probe_add_clause = &probe_add_clause,
 	.probe_destroy	= &probe_destroy,
 };
 
@@ -822,5 +855,6 @@ dt_provimpl_t	dt_usdt = {
 	.prog_type	= BPF_PROG_TYPE_UNSPEC,
 	.provide_probe	= &provide_usdt_probe,
 	.enable		= &enable_usdt,
+	.probe_add_clause = &probe_add_clause,
 	.probe_destroy	= &probe_destroy,
 };
diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
index 17b1844c..b1b1b1b8 100644
--- a/libdtrace/dt_provider.h
+++ b/libdtrace/dt_provider.h
@@ -62,6 +62,9 @@ typedef struct dt_provimpl {
 	int (*probe_info)(dtrace_hdl_t *dtp,	/* get probe info */
 			  const struct dt_probe *prp,
 			  int *argcp, dt_argdesc_t **argvp);
+	int (*probe_add_clause)(dtrace_hdl_t *dtp, /* add clause to probe */
+				struct dt_probe *prp,
+				dt_ident_t *idp);
 	void (*detach)(dtrace_hdl_t *dtp,	/* probe cleanup */
 		       const struct dt_probe *prb);
 	void (*probe_destroy)(dtrace_hdl_t *dtp, /* free probe data */
-- 
2.43.5




More information about the DTrace-devel mailing list