[DTrace-devel] [PATCH 41/61] Fix data section for dt_aggregate

eugene.loh at oracle.com eugene.loh at oracle.com
Fri Jul 8 14:45:25 UTC 2022


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

The user-space consumer has a hash table, dtp->dt_aggregate, of
aggregations that it is tracking.

In legacy DTrace, the data section, dtada_data, for such an aggregation
was described by the corresponding aggregation description -- that is,
the actual data was preceded by the variable ID and the aggregation's
keys, if any.

In the port to BPF, only aggregation data was kept.  Problems include:

*)  This breaks some dependent code.

*)  There is no information about the keys, if any.

Change the data section back to legacy style.  This impacts the use
of the dtada_data pointer, the size dtada_size of that data, and the
overall size dtahe_size of a hash table entry.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_aggregate.c | 41 +++++++++++++++++++++++++++-------------
 libdtrace/dt_consume.c   |  8 ++++----
 libdtrace/dt_printf.c    | 10 +++++-----
 3 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/libdtrace/dt_aggregate.c b/libdtrace/dt_aggregate.c
index 13595515..f2501ad4 100644
--- a/libdtrace/dt_aggregate.c
+++ b/libdtrace/dt_aggregate.c
@@ -458,36 +458,41 @@ dt_aggregate_snap_one(dt_idhash_t *dhp, dt_ident_t *aid, dt_snapstate_t *st)
 	dt_ahashent_t		*h;
 	dtrace_aggdesc_t	*agg;
 	dtrace_aggdata_t	*agd;
+	dtrace_recdesc_t	*rec;
 	uint64_t		hval = aid->di_id;
 	size_t			ndx = hval % agh->dtah_size;
 	int			rval;
-	uint_t			i, realsz;
+	uint_t			i, datasz;
 	int64_t			*src;
+	int			nrecs;
 
 	rval = dt_aggid_lookup(st->dtp, aid->di_id, &agg);
 	if (rval != 0)
 		return rval;
 
+	nrecs = agg->dtagd_nrecs;
+
 	/* point to the latch sequence number */
 	src = (int64_t *)(st->buf + aid->di_offset);
 
-	/* real size excludes latch sequence number and second data copy, if any */
-	realsz = (aid->di_size - sizeof(uint64_t)) / DT_AGG_NUM_COPIES;
+	datasz = agg->dtagd_recs[nrecs - 1].dtrd_size;
 
 	/* See if we already have an entry for this aggregation. */
 	for (h = agh->dtah_hash[ndx]; h != NULL; h = h->dtahe_next) {
-		if (h->dtahe_hval != hval || h->dtahe_size != realsz)
+		if (h->dtahe_hval != hval || h->dtahe_size != agg->dtagd_size)
 			continue;
 
 		/* Entry found - process the data. */
 		agd = &h->dtahe_data;
 
-		st->fun(aid, (int64_t *)agd->dtada_data, src, realsz);
+		rec = &agg->dtagd_recs[nrecs - 1];
+		st->fun(aid, (int64_t *)(agd->dtada_data + rec->dtrd_offset),
+			       src, datasz);
 
 		/* If we keep per-CPU data - process that as well. */
 		if (agd->dtada_percpu != NULL)
 			st->fun(aid, (int64_t *)agd->dtada_percpu[st->cpu],
-			    src, realsz);
+			    src, datasz);
 
 		return 0;
 	}
@@ -496,26 +501,36 @@ dt_aggregate_snap_one(dt_idhash_t *dhp, dt_ident_t *aid, dt_snapstate_t *st)
 	if (*src == 0)
 		return 0;
 
+	/* advance past the latch sequence number */
+	src++;
+
 	/* add it to the hash table */
 	h = dt_zalloc(st->dtp, sizeof(dt_ahashent_t));
 	if (h == NULL)
 		return dt_set_errno(st->dtp, EDT_NOMEM);
 
 	agd = &h->dtahe_data;
-	agd->dtada_data = dt_alloc(st->dtp, realsz);
+	agd->dtada_data = dt_alloc(st->dtp, agg->dtagd_size);
 	if (agd->dtada_data == NULL) {
 		dt_free(st->dtp, h);
 		return dt_set_errno(st->dtp, EDT_NOMEM);
 	}
 
-	src++;
-	memcpy(agd->dtada_data, src, realsz);
-	agd->dtada_size = realsz;
+	/* initialize the variable ID */
+	*((long *)agd->dtada_data) = agg->dtagd_varid;
+
+	/* FIXME: initialize the keys */
+
+	/* copy the data */
+	rec = &agg->dtagd_recs[nrecs - 1];
+	memcpy(agd->dtada_data + rec->dtrd_offset, src, datasz);
+
+	agd->dtada_size = agg->dtagd_size;
 	agd->dtada_desc = agg;
 	agd->dtada_hdl = st->dtp;
 
 	h->dtahe_hval = hval;
-	h->dtahe_size = realsz;
+	h->dtahe_size = agg->dtagd_size;
 
 	if (st->agp->dtat_flags & DTRACE_A_PERCPU) {
 		char	**percpu = dt_calloc(st->dtp,
@@ -530,7 +545,7 @@ dt_aggregate_snap_one(dt_idhash_t *dhp, dt_ident_t *aid, dt_snapstate_t *st)
 		}
 
 		for (i = 0; i <= st->dtp->dt_conf.max_cpuid; i++) {
-			percpu[i] = dt_zalloc(st->dtp, realsz);
+			percpu[i] = dt_zalloc(st->dtp, datasz);
 			if (percpu[i] == NULL) {
 				while (--i >= 0)
 					dt_free(st->dtp, percpu[i]);
@@ -541,7 +556,7 @@ dt_aggregate_snap_one(dt_idhash_t *dhp, dt_ident_t *aid, dt_snapstate_t *st)
 			}
 		}
 
-		memcpy(percpu[st->cpu], src, realsz);
+		memcpy(percpu[st->cpu], src, datasz);
 		agd->dtada_percpu = percpu;
 	}
 
diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
index 28fed161..308a08b8 100644
--- a/libdtrace/dt_consume.c
+++ b/libdtrace/dt_consume.c
@@ -1002,8 +1002,8 @@ dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
 		return dt_printf(dtp, fp, "  %-*s", width, s);
 	}
 
-        /* print the bytes raw */
-        return dt_print_rawbytes(dtp, fp, addr, nbytes);
+	/* print the bytes raw */
+	return dt_print_rawbytes(dtp, fp, addr, nbytes);
 }
 
 #ifdef FIXME
@@ -1710,7 +1710,7 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
 
 	/*
 	 * Iterate over each record description in the key, printing the traced
-	 * data.
+	 * data, skipping the first record (the variable ID).
 	 */
 	for (i = 1; i < agg->dtagd_nrecs; i++) {
 		rec = &agg->dtagd_recs[i];
@@ -1736,7 +1736,7 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
 		aggdata = aggsdata[i];
 		agg = aggdata->dtada_desc;
 		rec = &agg->dtagd_recs[aggact];
-		addr = aggdata->dtada_data;
+		addr = aggdata->dtada_data + rec->dtrd_offset;
 		size = rec->dtrd_size;
 
 		assert(DTRACEACT_ISAGG(rec->dtrd_action));
diff --git a/libdtrace/dt_printf.c b/libdtrace/dt_printf.c
index cfbf394c..825c9883 100644
--- a/libdtrace/dt_printf.c
+++ b/libdtrace/dt_printf.c
@@ -1381,8 +1381,8 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
 				curagg++;
 
 			rec = &agg->dtagd_recs[aggrec];
-			addr = aggdata->dtada_data;
-			limit = addr + aggdata->dtada_size;
+			addr = aggdata->dtada_data + rec->dtrd_offset;
+			limit = addr + rec->dtrd_size;
 			normal = agg->dtagd_normal;
 			sig = agg->dtagd_sig;
 			flags = DTRACE_BUFDATA_AGGVAL;
@@ -1817,7 +1817,7 @@ dt_fprinta(const dtrace_aggdata_t *adp, void *arg)
 	if (pfw->pfw_aid != agg->dtagd_id)
 		return 0;	/* id does not match */
 
-	if (dt_printf_format(dtp, pfw->pfw_fp, pfw->pfw_argv, rec, nrecs,
+	if (dt_printf_format(dtp, pfw->pfw_fp, pfw->pfw_argv, ++rec, --nrecs,
 			     adp->dtada_data, adp->dtada_size, &adp, 1) == -1)
 		return (pfw->pfw_err = dtp->dt_errno);
 
@@ -1835,8 +1835,8 @@ dt_fprintas(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
 {
 	const dtrace_aggdata_t	*aggdata = aggsdata[0];
 	const dtrace_aggdesc_t	*agg = aggdata->dtada_desc;
-	const dtrace_recdesc_t	*rec = agg->dtagd_recs;
-	uint_t			nrecs = agg->dtagd_nrecs;
+	const dtrace_recdesc_t	*rec = &agg->dtagd_recs[1];
+	uint_t			nrecs = agg->dtagd_nrecs - 1;
 	dt_pfwalk_t		*pfw = arg;
 	dtrace_hdl_t		*dtp = pfw->pfw_argv->pfv_dtp;
 	int			i;
-- 
2.18.4




More information about the DTrace-devel mailing list