[DTrace-devel] [PATCH] Implement the trunc() action

Kris Van Hees kris.van.hees at oracle.com
Thu Aug 3 05:09:23 UTC 2023


Some tests will not yield the desired results yet due to issues with
switchrate/aggrate/statusrate implementation details that those
tests depend on.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_aggregate.c          | 22 ++++++++++++++++++++++
 libdtrace/dt_cg.c                 | 27 ++++-----------------------
 libdtrace/dt_consume.c            | 19 +++++++++++++------
 libdtrace/dt_open.c               |  2 +-
 test/unittest/aggs/tst.negtrunc.d |  1 -
 test/unittest/aggs/tst.trunc.d    |  1 -
 6 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/libdtrace/dt_aggregate.c b/libdtrace/dt_aggregate.c
index 7c09908d..24faf1c1 100644
--- a/libdtrace/dt_aggregate.c
+++ b/libdtrace/dt_aggregate.c
@@ -1086,6 +1086,26 @@ no_mem:
 	return dt_set_errno(dtp, EDT_NOMEM);
 }
 
+static int
+dt_aggwalk_remove(dtrace_hdl_t *dtp, dt_ahashent_t *h)
+{
+	dtrace_aggdata_t	*agd = &h->dtahe_data;
+	int			i, ncpus = dtp->dt_conf.num_online_cpus;
+
+	for (i = 0; i < ncpus; i++) {
+		int	cpu = dtp->dt_conf.cpus[i].cpu_id;
+		int	fd = dt_bpf_map_lookup_fd(dtp->dt_aggmap_fd, &cpu);
+
+		if (fd < 0)
+			return DTRACE_WORKSTATUS_ERROR;
+
+		dt_bpf_map_delete(fd, agd->dtada_key);
+		close(fd);
+	}
+
+	return DTRACE_WORKSTATUS_OKAY;
+}
+
 static int
 dt_aggwalk_rval(dtrace_hdl_t *dtp, dt_ahashent_t *h, int rval)
 {
@@ -1148,6 +1168,8 @@ dt_aggwalk_rval(dtrace_hdl_t *dtp, dt_ahashent_t *h, int rval)
 			dt_free(dtp, aggdata->dtada_percpu);
 		}
 
+		dt_aggwalk_remove(dtp, h);
+
 		dt_free(dtp, aggdata->dtada_key);
 		dt_free(dtp, aggdata->dtada_data);
 		dt_free(dtp, h);
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 5391a143..82db9bd7 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -2261,11 +2261,6 @@ dt_cg_act_trunc(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
 	dt_node_t	*anp, *trunc;
 	dt_ident_t	*aid;
 	char		n[DT_TYPE_NAMELEN];
-	int		argc = 0;
-
-	for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
-		argc++;
-	assert(argc == 1 || argc == 2);
 
 	anp = dnp->dn_args;
 	assert(anp != NULL);
@@ -2276,32 +2271,18 @@ dt_cg_act_trunc(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
 			dnp->dn_ident->di_name,
 			dt_node_type_name(anp, n, sizeof(n)));
 
-	trunc = anp->dn_list;
-	if (argc == 2)
-		assert(trunc != NULL && dt_node_is_scalar(trunc));
-
 	aid = anp->dn_ident;
 	if (aid->di_gen == pcb->pcb_hdl->dt_gen &&
 	    !(aid->di_flags & DT_IDFLG_MOD))
 		dnerror(dnp, D_TRUNC_AGGBAD,
 			"undefined aggregation: @%s\n", aid->di_name);
 
-	/*
-	 * FIXME: Needs implementation
-	 * TODO: Emit code to truncate the given aggregation.
-	 * DEPENDS ON: How aggregations are implemented using eBPF (hashmap?).
-	 * AGGID = aid->di_id
-	 */
+	trunc = anp->dn_list;
+	if (trunc == NULL)
+		trunc = dt_node_int(0);
+
 	dt_cg_store_val(pcb, anp, DTRACEACT_LIBACT, NULL, DT_ACT_TRUNC);
-#ifdef FIXME
-	/*
-	 * FIXME: There is an optional trunction value.
-	 * if (argc == 1), the optional value is missing, but "0" may be
-	 * specified.
-	 */
 	dt_cg_store_val(pcb, trunc, DTRACEACT_LIBACT, NULL, DT_ACT_TRUNC);
-#endif
-	dnerror(dnp, D_UNKNOWN, "trunc() is not implemented (yet)\n");
 }
 
 static void
diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
index 43a9cea3..a67c0f7b 100644
--- a/libdtrace/dt_consume.c
+++ b/libdtrace/dt_consume.c
@@ -1537,7 +1537,6 @@ dt_clear(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec)
 	return 0;
 }
 
-#ifdef FIXME
 typedef struct dt_trunc {
 	dtrace_aggid_t	dttd_id;
 	uint64_t	dttd_remaining;
@@ -1594,19 +1593,19 @@ dt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec)
 	addr = base + rec->dtrd_offset;
 
 	switch (rec->dtrd_size) {
-	case sizeof(uint64_t):
+	case sizeof(int64_t):
 		/* LINTED - alignment */
 		remaining = *((int64_t *)addr);
 		break;
-	case sizeof(uint32_t):
+	case sizeof(int32_t):
 		/* LINTED - alignment */
 		remaining = *((int32_t *)addr);
 		break;
-	case sizeof(uint16_t):
+	case sizeof(int16_t):
 		/* LINTED - alignment */
 		remaining = *((int16_t *)addr);
 		break;
-	case sizeof(uint8_t):
+	case sizeof(int8_t):
 		remaining = *((int8_t *)addr);
 		break;
 	default:
@@ -1626,7 +1625,6 @@ dt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec)
 
 	return 0;
 }
-#endif
 
 static int
 dt_print_datum(dtrace_hdl_t *dtp, FILE *fp, dtrace_recdesc_t *rec,
@@ -2344,6 +2342,15 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 				if (dt_clear(dtp, data, rec) != 0)
 					return DTRACE_WORKSTATUS_ERROR;
 
+				continue;
+			case DT_ACT_TRUNC:
+				if (i == epd->dtdd_nrecs - 1)
+					return dt_set_errno(dtp, EDT_BADTRUNC);
+
+				if (dt_trunc(dtp, data, rec) != 0)
+					return DTRACE_WORKSTATUS_ERROR;
+
+				i++;
 				continue;
 			case DT_ACT_FTRUNCATE:
 				if (fp == NULL)
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index b6a0b623..93e8535a 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -343,7 +343,7 @@ static const dt_ident_t _dtrace_globals[] = {
 	DT_ATTR_STABCMN, DT_VERS_1_0,
 	&dt_idops_func, "void(@, size_t, [size_t])" },
 { "trunc", DT_IDENT_ACTFUNC, 0, DT_ACT_TRUNC, DT_ATTR_STABCMN,
-	DT_VERS_1_0, &dt_idops_func, "void(@, [uint64_t])" },
+	DT_VERS_1_0, &dt_idops_func, "void(@, [int64_t])" },
 { "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN,
 	DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
 { "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN,
diff --git a/test/unittest/aggs/tst.negtrunc.d b/test/unittest/aggs/tst.negtrunc.d
index 2c35151b..97db1967 100644
--- a/test/unittest/aggs/tst.negtrunc.d
+++ b/test/unittest/aggs/tst.negtrunc.d
@@ -4,7 +4,6 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 - requires trunc() */
 
 #pragma D option quiet
 
diff --git a/test/unittest/aggs/tst.trunc.d b/test/unittest/aggs/tst.trunc.d
index 0c0496a5..dbaeb09a 100644
--- a/test/unittest/aggs/tst.trunc.d
+++ b/test/unittest/aggs/tst.trunc.d
@@ -4,7 +4,6 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 - requires trunc() */
 
 #pragma D option quiet
 
-- 
2.40.1




More information about the DTrace-devel mailing list