[DTrace-devel] [PATCH 53/61] Add support for aggregation keys
Kris Van Hees
kris.van.hees at oracle.com
Wed Sep 14 18:14:18 UTC 2022
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
... albeit in modified form due to other chagnes I introduced that change the
storage layout for indexed aggregations.
... on dev
On Fri, Jul 08, 2022 at 10:45:37AM -0400, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> In the DTrace port to BPF, the initial support for aggregations
> had the kernel maintaining aggregations in a per-CPU BPF map that
> was statically allocated and managed. Each aggregation had its
> own region of per-CPU memory. That is, run-time aggregation keys
> were not supported.
>
> To support aggregation keys, switch to a per-CPU BPF hash map.
> The hash map key comprises:
>
> *) the aggregation variable ID
>
> *) the aggregation keys (if any)
>
> *) a 64-bit zero (to conform to dynamic variable "tuples")
>
> On the producer (dt_cg.c) side:
>
> *) Use the existing dt_cg_arglist() to process the
> aggregation keys and produce the BPF hash map key.
>
> *) Call the new dt_get_agg() to get a pointer to the
> aggregation data in the BPF hash map. The function call
> will create the element if needed, increment the data
> counter, and advance the pointer to the actual data.
>
> *) Push this pointer to the stack.
>
> *) Call the aggregation function: compute the value
> to be aggregated and pop the stack for the pointer
> to where the aggregation data is.
>
> *) Record the aggregation description (e.g., sizes of
> keys and data) if not already done. This step is
> performed during code generation, though it does not
> generate code per se.
>
> On the consumer (dt_aggregate.c) side, to snapshot aggregation data:
>
> *) Use dt_bpf_map_next_key() to walk the keys of the
> BPF hash map.
>
> *) For each hash map key, read the aggregation data on all CPUs.
>
> *) For each CPU with a nonzero data counter value, check
> dt_aggregate's user-space hash table for this key-specific
> aggregation. Initialize or aggregate the user-space data
> accordingly.
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
> bpf/Build | 1 +
> bpf/get_agg.c | 42 +++
> include/dtrace/faults_defines.h | 1 +
> libdtrace/dt_aggregate.c | 256 ++++++++----------
> libdtrace/dt_bpf.c | 34 ++-
> libdtrace/dt_cg.c | 129 +++++----
> libdtrace/dt_dctx.h | 1 -
> libdtrace/dt_error.c | 1 +
> libdtrace/dt_impl.h | 2 +-
> test/demo/intro/countdown-multiple.d | 3 +-
> test/demo/intro/countdown-quant.d | 3 +-
> test/demo/out/printa.d | 3 +-
> test/demo/script/syscall.d | 3 +-
> test/demo/user/libc.d | 3 +-
> test/stress/buffering/err.resize2.d | 1 -
> .../actions/printa/err.D_PRINTA_AGGKEY.d | 3 +-
> .../actions/printa/err.D_PRINTA_AGGPROTO.d | 3 +-
> test/unittest/aggs/tst.count2.d | 3 +-
> test/unittest/aggs/tst.count3.d | 3 +-
> test/unittest/aggs/tst.denormalizeonly.d | 3 +-
> test/unittest/aggs/tst.fmtnormalize.d | 3 +-
> test/unittest/aggs/tst.forms.d | 3 +-
> test/unittest/aggs/tst.keysort.d | 3 +-
> test/unittest/aggs/tst.lquantize.d | 3 +-
> test/unittest/aggs/tst.lquantrange.d | 3 +-
> test/unittest/aggs/tst.lquantzero.d | 4 +-
> test/unittest/aggs/tst.multiaggs1.d | 3 +-
> test/unittest/aggs/tst.multinormalize.d | 3 +-
> test/unittest/aggs/tst.neglquant.d | 1 -
> test/unittest/aggs/tst.negorder.d | 3 +-
> test/unittest/aggs/tst.negquant.d | 1 -
> test/unittest/aggs/tst.order.d | 3 +-
> test/unittest/aggs/tst.quantize.d | 3 +-
> test/unittest/aggs/tst.quantmany.d | 3 +-
> test/unittest/aggs/tst.quantzero.d | 4 +-
> test/unittest/aggs/tst.signedkeyspos.d | 3 +-
> test/unittest/aggs/tst.valsortkeypos.d | 3 +-
> test/unittest/funcs/substr/tst.substrminate.d | 1 -
> test/unittest/grammar/tst.stmts.d | 3 +-
> test/unittest/misc/tst.haslam.d | 3 +-
> test/unittest/multiaggs/err.D_PRINTA_AGGKEY.d | 4 +-
> .../multiaggs/err.D_PRINTA_AGGPROTO.d | 4 +-
> test/unittest/multiaggs/tst.many.d | 3 +-
> test/unittest/multiaggs/tst.sort.d | 3 +-
> test/unittest/multiaggs/tst.sortpos.d | 3 +-
> test/unittest/multiaggs/tst.zero.d | 3 +-
> test/unittest/multiaggs/tst.zero2.d | 3 +-
> test/unittest/multiaggs/tst.zero3.d | 3 +-
> test/unittest/printa/tst.dynwidth.d | 3 +-
> test/unittest/printa/tst.tuple.d | 3 +-
> 50 files changed, 294 insertions(+), 292 deletions(-)
> create mode 100644 bpf/get_agg.c
>
> diff --git a/bpf/Build b/bpf/Build
> index b29f4b91..41de1bb8 100644
> --- a/bpf/Build
> +++ b/bpf/Build
> @@ -25,6 +25,7 @@ bpf_dlib_SOURCES = \
> agg_lqbin.c agg_qbin.c \
> basename.S \
> dirname.S \
> + get_agg.c \
> get_bvar.c \
> get_dvar.c \
> index.S \
> diff --git a/bpf/get_agg.c b/bpf/get_agg.c
> new file mode 100644
> index 00000000..dc3f8443
> --- /dev/null
> +++ b/bpf/get_agg.c
> @@ -0,0 +1,42 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> + */
> +#include <linux/bpf.h>
> +#include <stdint.h>
> +#include <bpf-helpers.h>
> +
> +#ifndef noinline
> +# define noinline __attribute__((noinline))
> +#endif
> +
> +extern struct bpf_map_def aggs;
> +
> +noinline uint64_t *dt_get_agg(const char *key, const uint64_t *zer, uint64_t val)
> +{
> + uint64_t *valp;
> +
> + /* try to look up the key */
> + valp = bpf_map_lookup_elem(&aggs, key);
> +
> + /* if not found, create it */
> + if (valp == 0) {
> + /* start with all zeroes */
> + if (bpf_map_update_elem(&aggs, key, zer, BPF_ANY) < 0)
> + return 0;
> + valp = bpf_map_lookup_elem(&aggs, key);
> + if (valp == 0)
> + return 0;
> +
> + /* val is nonzero only for min() and max() */
> + valp[1] = val;
> + }
> +
> + /* increment the data counter */
> + valp[0] += 1;
> +
> + /* advance past the data counter */
> + valp += 1;
> +
> + return valp;
> +}
> diff --git a/include/dtrace/faults_defines.h b/include/dtrace/faults_defines.h
> index 3cefb0ee..f671f341 100644
> --- a/include/dtrace/faults_defines.h
> +++ b/include/dtrace/faults_defines.h
> @@ -33,6 +33,7 @@
> #define DTRACEFLT_TUPOFLOW 8 /* Tuple stack overflow */
> #define DTRACEFLT_BADSTACK 9 /* Bad stack */
> #define DTRACEFLT_BADSIZE 10 /* Bad size */
> +#define DTRACEFLT_NOAGGS 11 /* Out of aggregations space */
>
> #define DTRACEFLT_LIBRARY 1000 /* Library-level fault */
>
> diff --git a/libdtrace/dt_aggregate.c b/libdtrace/dt_aggregate.c
> index 10df98da..bfb32b02 100644
> --- a/libdtrace/dt_aggregate.c
> +++ b/libdtrace/dt_aggregate.c
> @@ -409,13 +409,6 @@ dt_aggregate_aggid(dt_ahashent_t *ent)
> typedef void (*agg_cpu_f)(dt_ident_t *aid,
> int64_t *dst, int64_t *src, uint_t realsz);
>
> -typedef struct dt_snapstate {
> - dtrace_hdl_t *dtp;
> - processorid_t cpu;
> - char *buf;
> - dt_aggregate_t *agp;
> -} dt_snapstate_t;
> -
> static void
> dt_agg_one_agg(uint_t act, int64_t *dst, int64_t *src, uint_t realsz)
> {
> @@ -440,29 +433,27 @@ dt_agg_one_agg(uint_t act, int64_t *dst, int64_t *src, uint_t realsz)
> }
>
> static int
> -dt_aggregate_snap_one(dt_idhash_t *dhp, dt_ident_t *aid, dt_snapstate_t *st)
> +dt_aggregate_snap_one(dtrace_hdl_t *dtp, dt_ident_t *aid, char *key, int64_t *src, int cpu)
> {
> - dt_ahash_t *agh = &st->agp->dtat_hash;
> + dt_ahash_t *agh = &dtp->dt_aggregate.dtat_hash;
> dt_ahashent_t *h;
> dtrace_aggdesc_t *agg;
> dtrace_aggdata_t *agd;
> dtrace_recdesc_t *rec;
> - uint64_t hval = aid->di_id;
> + uint64_t hval = aid->di_id; /* FIXME: need better hash value */
> size_t ndx = hval % agh->dtah_size;
> int rval;
> uint_t i, datasz;
> - int64_t *src;
> - int nrecs;
> + int irec, nrecs;
> + caddr_t data;
> + size_t roffs;
>
> - rval = dt_aggid_lookup(st->dtp, aid->di_id, &agg);
> + rval = dt_aggid_lookup(dtp, aid->di_id, &agg);
> if (rval != 0)
> return rval;
>
> nrecs = agg->dtagd_nrecs;
>
> - /* point to the data counter */
> - src = (int64_t *)(st->buf + aid->di_offset);
> -
> /* skip it if data counter is 0 */
> if (*src == 0)
> return 0;
> @@ -478,76 +469,95 @@ dt_aggregate_snap_one(dt_idhash_t *dhp, dt_ident_t *aid, dt_snapstate_t *st)
>
> if (h->dtahe_hval != hval || h->dtahe_size != agg->dtagd_size)
> continue;
> + agd = &h->dtahe_data;
> + data = agd->dtada_data;
> +
> + /* compare the non-data records */
> + for (irec = 0; irec < nrecs - 1; irec++) {
> + rec = &agg->dtagd_recs[irec];
> + roffs = rec->dtrd_offset;
> +
> + if (memcmp(&key[roffs], &data[roffs], rec->dtrd_size))
> + goto hashnext;
> + }
>
> /* Entry found - process the data. */
> - agd = &h->dtahe_data;
> act = ((dt_ident_t *)aid->di_iarg)->di_id;
> -
> rec = &agg->dtagd_recs[nrecs - 1];
> - dt_agg_one_agg(act, (int64_t *)(agd->dtada_data + rec->dtrd_offset),
> - src, datasz);
> + roffs = rec->dtrd_offset;
> + dt_agg_one_agg(act, (int64_t *)&data[roffs], src, datasz);
>
> /* If we keep per-CPU data - process that as well. */
> if (agd->dtada_percpu != NULL)
> - dt_agg_one_agg(act, (int64_t *)agd->dtada_percpu[st->cpu],
> + dt_agg_one_agg(act, (int64_t *)agd->dtada_percpu[cpu],
> src, datasz);
>
> return 0;
> +
> +hashnext:
> + continue;
> }
>
> /* add it to the hash table */
> - h = dt_zalloc(st->dtp, sizeof(dt_ahashent_t));
> + h = dt_zalloc(dtp, sizeof(dt_ahashent_t));
> if (h == NULL)
> - return dt_set_errno(st->dtp, EDT_NOMEM);
> + return dt_set_errno(dtp, EDT_NOMEM);
>
> agd = &h->dtahe_data;
> - 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);
> + data = dt_alloc(dtp, agg->dtagd_size);
> + if (data == NULL) {
> + dt_free(dtp, h);
> + return dt_set_errno(dtp, EDT_NOMEM);
> }
> + agd->dtada_data = data;
>
> /* initialize the variable ID */
> - *((long *)agd->dtada_data) = agg->dtagd_varid;
> + *((long *)data) = agg->dtagd_varid;
>
> - /* FIXME: initialize the keys */
> + /* initialize the non-data records */
> + for (irec = 0; irec < nrecs - 1; irec++) {
> + rec = &agg->dtagd_recs[irec];
> + roffs = rec->dtrd_offset;
> + memcpy(&data[roffs], &key[roffs], rec->dtrd_size);
> + }
>
> /* copy the data */
> rec = &agg->dtagd_recs[nrecs - 1];
> - memcpy(agd->dtada_data + rec->dtrd_offset, src, datasz);
> + roffs = rec->dtrd_offset;
> + memcpy(&data[roffs], src, datasz);
>
> agd->dtada_size = agg->dtagd_size;
> agd->dtada_desc = agg;
> - agd->dtada_hdl = st->dtp;
> + agd->dtada_hdl = dtp;
>
> h->dtahe_hval = hval;
> h->dtahe_size = agg->dtagd_size;
>
> - if (st->agp->dtat_flags & DTRACE_A_PERCPU) {
> - char **percpu = dt_calloc(st->dtp,
> - st->dtp->dt_conf.max_cpuid + 1,
> + if (dtp->dt_aggregate.dtat_flags & DTRACE_A_PERCPU) {
> + char **percpu = dt_calloc(dtp,
> + dtp->dt_conf.max_cpuid + 1,
> sizeof(char *));
>
> if (percpu == NULL) {
> - dt_free(st->dtp, agd->dtada_data);
> - dt_free(st->dtp, h);
> + dt_free(dtp, data);
> + dt_free(dtp, h);
>
> - dt_set_errno(st->dtp, EDT_NOMEM);
> + dt_set_errno(dtp, EDT_NOMEM);
> }
>
> - for (i = 0; i <= st->dtp->dt_conf.max_cpuid; i++) {
> - percpu[i] = dt_zalloc(st->dtp, datasz);
> + for (i = 0; i <= dtp->dt_conf.max_cpuid; i++) {
> + percpu[i] = dt_zalloc(dtp, datasz);
> if (percpu[i] == NULL) {
> while (--i >= 0)
> - dt_free(st->dtp, percpu[i]);
> - dt_free(st->dtp, agd->dtada_data);
> - dt_free(st->dtp, h);
> + dt_free(dtp, percpu[i]);
> + dt_free(dtp, data);
> + dt_free(dtp, h);
>
> - dt_set_errno(st->dtp, EDT_NOMEM);
> + dt_set_errno(dtp, EDT_NOMEM);
> }
> }
>
> - memcpy(percpu[st->cpu], src, datasz);
> + memcpy(percpu[cpu], src, datasz);
> agd->dtada_percpu = percpu;
> }
>
> @@ -567,22 +577,6 @@ dt_aggregate_snap_one(dt_idhash_t *dhp, dt_ident_t *aid, dt_snapstate_t *st)
> return 0;
> }
>
> -static int
> -dt_aggregate_snap_cpu(dtrace_hdl_t *dtp, processorid_t cpu)
> -{
> - dt_aggregate_t *agp = &dtp->dt_aggregate;
> - char *buf = agp->dtat_cpu_buf[cpu];
> - dt_snapstate_t st;
> -
> - st.dtp = dtp;
> - st.cpu = cpu;
> - st.buf = buf;
> - st.agp = agp;
> -
> - return dt_idhash_iter(dtp->dt_aggs,
> - (dt_idhash_f *)dt_aggregate_snap_one, &st);
> -}
> -
> /*
> * Retrieve all aggregation data for the enabled CPUs and aggregate it.
> */
> @@ -590,28 +584,62 @@ int
> dtrace_aggregate_snap(dtrace_hdl_t *dtp)
> {
> dt_aggregate_t *agp = &dtp->dt_aggregate;
> - uint32_t key = 0;
> - int i, rval;
> + int i, fd = dtp->dt_aggmap_fd;
> + uint_t keysiz = dtp->dt_maxtuplesize;
> + uint_t valsiz = dtp->dt_aggsiz;
> + char *buf = agp->dtat_buf;
> + char *key = buf;
> + char *nxt = agp->dtat_nextkey;
> + int64_t *val = (int64_t *)(buf + keysiz);
> + uint32_t *varID_ptr = (uint32_t *)key;
> +
> + if (buf == NULL)
> + return 0;
> +
> + dtrace_aggregate_clear(dtp);
>
> /*
> - * If we do not have a buffer initialized, we will not be processing
> - * aggregations, so there is nothing to be done here.
> + * To start the iteration over BPF hash map keys,
> + * we need a key that will not be recognized.
> + * Just set its varID to an unrecognized value.
> */
> - if (agp->dtat_cpu_buf == NULL)
> - return 0;
> + *varID_ptr = DTRACE_AGGIDNONE;
> +
> + /* now iterate over BPF hash map keys */
> + while (dt_bpf_map_next_key(fd, key, nxt) == 0) {
> + uint32_t varID;
> + dt_ident_t *aid;
> +
> + /* get next value */
> + memcpy(key, nxt, keysiz);
> + if (dt_bpf_map_lookup(fd, key, val) == -1) {
> + printf("FAIL to look up\n");
> + return 1;
> + }
>
> - dtrace_aggregate_clear(dtp);
> + /* read the key's var ID */
> + varID = *varID_ptr;
>
> - rval = dt_bpf_map_lookup(dtp->dt_aggmap_fd, &key, agp->dtat_buf);
> - if (rval != 0)
> - return dt_set_errno(dtp, -rval);
> + /* get the aid */
> + aid = dt_idhash_lookup(dtp->dt_aggs, dtp->dt_adesc[varID]->dtagd_name);
>
> - for (i = 0; i < dtp->dt_conf.num_online_cpus; i++) {
> - rval = dt_aggregate_snap_cpu(dtp, dtp->dt_conf.cpus[i].cpu_id);
> - if (rval != 0)
> - return rval;
> + /* look for on-line CPUs */
> + for (i = 0; i < dtp->dt_conf.num_online_cpus; i++) {
> + int cpu = dtp->dt_conf.cpus[i].cpu_id;
> + int64_t *data = (int64_t*) (((char *)val) + cpu * valsiz);
> +
> + /* look for non-zero data counters */
> + if (*data == 0)
> + continue;
> +
> + /* process it */
> + dt_aggregate_snap_one(dtp, aid, key, data, cpu);
> + }
> }
>
> + /* check for normal end of iteration */
> + assert(errno == ENOENT);
> +
> return 0;
> }
>
> @@ -974,49 +1002,14 @@ dt_aggregate_bundlecmp(const void *lhs, const void *rhs)
> }
> }
>
> -/*
> - * Callback for initializing the min() and max() aggregation functions.
> - * The minimum 64 bit value is set for max() and the maximum 64 bit value is
> - * set for min(), so that any other value fed to the functions will register
> - * properly.
> - *
> - * The data counter of the first aggregation is used as a flag to
> - * indicate whether an initial value was stored for any aggregation.
> - */
> -static int
> -init_minmax(dt_idhash_t *dhp, dt_ident_t *aid, char *buf)
> -{
> - dt_ident_t *fid = aid->di_iarg;
> - int64_t *ptr;
> - int64_t value;
> -
> - assert(aid->di_kind == DT_IDENT_AGG);
> - assert(fid);
> -
> - if (fid->di_id == DT_AGG_MIN)
> - value = INT64_MAX;
> - else if (fid->di_id == DT_AGG_MAX)
> - value = INT64_MIN;
> - else
> - return 0;
> -
> - /* Indicate that we are setting initial values. */
> - *(int64_t *)buf = 1;
> -
> - /* skip ptr[0], it is the data counter */
> - ptr = (int64_t *)(buf + aid->di_offset);
> - ptr[1] = value;
> -
> - return 0;
> -}
> -
> int
> dt_aggregate_go(dtrace_hdl_t *dtp)
> {
> dt_aggregate_t *agp = &dtp->dt_aggregate;
> dt_ahash_t *agh = &agp->dtat_hash;
> - int aggsz, i;
> - uint32_t key = 0;
> + int aggsz;
> + uint_t keysiz = dtp->dt_maxtuplesize;
> + uint_t valsiz = dtp->dt_aggsiz;
>
> /* If there are no aggregations there is nothing to do. */
> aggsz = dt_idhash_datasize(dtp->dt_aggs);
> @@ -1025,53 +1018,27 @@ dt_aggregate_go(dtrace_hdl_t *dtp)
>
> /*
> * Allocate a buffer to hold the aggregation data for all possible
> - * CPUs, and initialize the per-CPU data pointers for CPUs that are
> - * currently enabled.
> + * CPUs. Allocate a buffer to hold the next key in the BPF map.
> */
> - agp->dtat_buf = dt_zalloc(dtp, dtp->dt_conf.num_possible_cpus * aggsz);
> + agp->dtat_buf = dt_zalloc(dtp, keysiz + dtp->dt_conf.num_possible_cpus * valsiz);
> if (agp->dtat_buf == NULL)
> return dt_set_errno(dtp, EDT_NOMEM);
> -
> - agp->dtat_cpu_buf = dt_calloc(dtp, dtp->dt_conf.max_cpuid + 1,
> - sizeof(char *));
> - if (agp->dtat_cpu_buf == NULL) {
> + agp->dtat_nextkey = dt_zalloc(dtp, keysiz);
> + if (agp->dtat_nextkey == NULL) {
> dt_free(dtp, agp->dtat_buf);
> return dt_set_errno(dtp, EDT_NOMEM);
> }
>
> - for (i = 0; i < dtp->dt_conf.num_online_cpus; i++) {
> - int cpu = dtp->dt_conf.cpus[i].cpu_id;
> -
> - agp->dtat_cpu_buf[cpu] = agp->dtat_buf + cpu * aggsz;
> - }
> -
> /* Create the aggregation hash. */
> agh->dtah_size = DTRACE_AHASHSIZE;
> agh->dtah_hash = dt_zalloc(dtp,
> agh->dtah_size * sizeof(dt_ahashent_t *));
> if (agh->dtah_hash == NULL) {
> - dt_free(dtp, agp->dtat_cpu_buf);
> + dt_free(dtp, agp->dtat_nextkey);
> dt_free(dtp, agp->dtat_buf);
> return dt_set_errno(dtp, EDT_NOMEM);
> }
>
> - /* Initialize the starting values for min() and max() aggregations. */
> - dt_idhash_iter(dtp->dt_aggs, (dt_idhash_f *) init_minmax,
> - agp->dtat_buf);
> - if (*(int64_t *)agp->dtat_buf == 0)
> - return 0;
> - *(int64_t *)agp->dtat_buf = 0; /* clear the flag */
> - for (i = 0; i < dtp->dt_conf.num_online_cpus; i++) {
> - int cpu = dtp->dt_conf.cpus[i].cpu_id;
> -
> - /* Data for CPU 0 was populated, so skip it. */
> - if (cpu == 0)
> - continue;
> -
> - memcpy(agp->dtat_cpu_buf[cpu], agp->dtat_buf, aggsz);
> - }
> - dt_bpf_map_update(dtp->dt_aggmap_fd, &key, agp->dtat_buf);
> -
> return 0;
> }
>
> @@ -1845,7 +1812,6 @@ dt_aggregate_destroy(dtrace_hdl_t *dtp)
> hash->dtah_all = NULL;
> hash->dtah_size = 0;
> }
> -
> - dt_free(dtp, agp->dtat_cpu_buf);
> + dt_free(dtp, agp->dtat_nextkey);
> dt_free(dtp, agp->dtat_buf);
> }
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> index 8d7f38f2..107b65a6 100644
> --- a/libdtrace/dt_bpf.c
> +++ b/libdtrace/dt_bpf.c
> @@ -194,9 +194,7 @@ populate_probes_map(dtrace_hdl_t *dtp, int fd)
> * - state: DTrace session state, used to communicate state between BPF
> * programs and userspace. The content of the map is defined in
> * dt_state.h.
> - * - aggs: Aggregation data buffer map, associated with each CPU. The
> - * map is implemented as a global per-CPU map with a singleton
> - * element (key 0).
> + * - aggs: Aggregation data buffer map, a per-CPU hash.
> * - specs: Map associating speculation IDs with a dt_bpf_specs_t struct
> * giving the number of buffers speculated into for this
> * speculation, and the number drained by userspace.
> @@ -271,11 +269,18 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
> /*
> * Check if there is aggregation data to be collected.
> */
> - sz = dt_idhash_datasize(dtp->dt_aggs);
> - if (sz > 0) {
> + if (dtp->dt_aggsiz > 0) {
> + /* FIXME: need a better model for BPF map size */
> + size_t nelems = dtp->dt_options[DTRACEOPT_AGGSIZE]
> + / (dtp->dt_conf.max_cpuid + 1)
> + / (dtp->dt_maxtuplesize + dtp->dt_aggsiz);
> +
> + /* create the map */
> dtp->dt_aggmap_fd = create_gmap(dtp, "aggs",
> - BPF_MAP_TYPE_PERCPU_ARRAY,
> - sizeof(uint32_t), sz, 1);
> + BPF_MAP_TYPE_PERCPU_HASH,
> + dtp->dt_maxtuplesize,
> + dtp->dt_aggsiz,
> + nelems);
> if (dtp->dt_aggmap_fd == -1)
> return -1; /* dt_errno is set for us */
> }
> @@ -367,6 +372,8 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
> /* figure out how big the region of zeroes should be */
> if (dtp->dt_zerosize < dtp->dt_maxtuplesize)
> dtp->dt_zerosize = dtp->dt_maxtuplesize;
> + if (dtp->dt_zerosize < dtp->dt_aggsiz)
> + dtp->dt_zerosize = dtp->dt_aggsiz;
>
> /* global variables, including a region of zeroes */
> dtp->dt_zerooffset = P2ROUNDUP(dt_idhash_datasize(dtp->dt_globals), 8);
> @@ -403,7 +410,18 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
> dt_bpf_map_update(fd, &key, &dflt);
> }
>
> - if (dtp->dt_maxtuplesize > 0 &&
> + /*
> + * Note:
> + *
> + * - dt_maxtuplesize>0 can mean we are using the tuples map
> + * *OR* that we are using aggregations
> + *
> + * - dvarc!=0 can mean we are using the tuples map
> + * *OR* that we are using keyless dvars (e.g., "self->x")
> + *
> + * So check both conditions before creating a "tuples" map.
> + */
> + if (dtp->dt_maxtuplesize > 0 && dvarc != 0 &&
> create_gmap(dtp, "tuples", BPF_MAP_TYPE_HASH,
> dtp->dt_maxtuplesize, sizeof(uint64_t), dvarc) == -1)
> return -1; /* dt_errno is set for us */
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 5a74f5ad..257af074 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -206,8 +206,6 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
> DT_CG_STORE_MAP_PTR("strtab", DCTX_STRTAB);
> if (dtp->dt_options[DTRACEOPT_SCRATCHSIZE] > 0)
> DT_CG_STORE_MAP_PTR("scratchmem", DCTX_SCRATCHMEM);
> - if (dt_idhash_datasize(dtp->dt_aggs) > 0)
> - DT_CG_STORE_MAP_PTR("aggs", DCTX_AGG);
> if (dt_idhash_datasize(dtp->dt_globals) > 0 || dtp->dt_zerosize > 0)
> DT_CG_STORE_MAP_PTR("gvars", DCTX_GVARS);
> if (dtp->dt_maxlvaralloc > 0)
> @@ -2623,9 +2621,31 @@ dt_cg_push_stack(dt_irlist_t *dlp, dt_regset_t *drp, int reg)
> dt_regset_free(drp, tmp);
> }
>
> +static int
> +dt_cg_pop_stack(dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + int reg;
> + int tmp;
> +
> + if ((reg = dt_regset_alloc(drp)) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + if ((tmp = dt_regset_alloc(drp)) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +
> + emit(dlp, BPF_LOAD(BPF_DW, tmp, BPF_REG_FP, DT_STK_SP));
> + emit(dlp, BPF_ALU64_IMM(BPF_ADD, tmp, DT_STK_SLOT_SZ));
> + emit(dlp, BPF_LOAD(BPF_DW, reg, tmp, 0));
> + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_FP, DT_STK_SP, tmp));
> + dt_regset_free(drp, tmp);
> +
> + return reg;
> +}
> +
> /*
> * Generate code to push the specified argument list on to the tuple stack.
> - * We use this routine for handling the index tuple for associative arrays.
> + * We use this routine for handling the index tuple for associative arrays
> + * as well as keys for aggregations.
> + *
> * We must first generate code for all subexpressions because any subexpression
> * could itself require the use of the tuple assembly area and we only provide
> * one.
> @@ -5449,60 +5469,13 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> sizeof(uint64_t) + (sz)); \
> } while (0)
>
> -/*
> - * Return a register that holds a pointer to the aggregation data to be
> - * updated.
> - *
> - * We update the data counter (first value in the aggregation) to
> - * signal that the aggregation has data. The location of data for the
> - * given aggregation is stored in the register returned from this function.
> - */
> -static int
> -dt_cg_agg_buf_prepare(dt_ident_t *aid, int size, dt_irlist_t *dlp,
> - dt_regset_t *drp)
> -{
> - int rptr;
> -
> - TRACE_REGSET(" Prep: Begin");
> -
> - dt_regset_xalloc(drp, BPF_REG_0);
> - rptr = dt_regset_alloc(drp);
> - assert(rptr != -1);
> -
> - /*
> - * ptr = dctx->agg; // lddw %rptr, [%fp + DT_STK_DCTX]
> - * // lddw %rptr, [%rptr + DCTX_AGG]
> - */
> - emit(dlp, BPF_LOAD(BPF_DW, rptr, BPF_REG_FP, DT_STK_DCTX));
> - emit(dlp, BPF_LOAD(BPF_DW, rptr, rptr, DCTX_AGG));
> -
> - /*
> - * *((uint64_t *)(ptr + aid->di_offset))++;
> - * // mov %r0, 1
> - * // xadd [%rptr + aid->di_offset], %r0
> - * ptr += aid->di_offset + sizeof(uint64_t);
> - * // add %rptr, aid->di_offset +
> - * // sizeof(uint64_t)
> - */
> - emit(dlp, BPF_MOV_IMM(BPF_REG_0, 1));
> - emit(dlp, BPF_XADD_REG(BPF_DW, rptr, aid->di_offset, BPF_REG_0));
> - emit(dlp, BPF_ALU64_IMM(BPF_ADD, rptr, aid->di_offset + sizeof(uint64_t)));
> -
> - dt_regset_free(drp, BPF_REG_0);
> -
> - TRACE_REGSET(" Prep: End ");
> -
> - return rptr;
> -}
> -
> #define DT_CG_AGG_IMPL(aid, sz, dlp, drp, f, ...) \
> do { \
> int dreg; \
> \
> TRACE_REGSET(" Upd: Begin "); \
> \
> - dreg = dt_cg_agg_buf_prepare((aid), (sz), (dlp), (drp));\
> - \
> + dreg = dt_cg_pop_stack((dlp), (drp)); \
> (f)((dlp), (drp), dreg, ## __VA_ARGS__); \
> dt_regset_free((drp), dreg); \
> \
> @@ -6524,8 +6497,11 @@ dt_cg_agg(dt_pcb_t *pcb, dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> dtrace_hdl_t *dtp = pcb->pcb_hdl;
> dt_ident_t *aid, *fid;
> dt_cg_aggfunc_f *aggfp;
> - int nrecs, off;
> + int nrecs, off, tup;
> dt_node_t *d;
> + dt_ident_t *zero_off = dt_dlib_get_var(dtp, "ZERO_OFF");
> + dt_ident_t *idp;
> + uint_t Lgot_agg;
>
> /*
> * If the aggregation has no aggregating function applied to it, then
> @@ -6543,17 +6519,56 @@ dt_cg_agg(dt_pcb_t *pcb, dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> dnerror(dnp->dn_aggfun, D_AGG_SCALAR, "%s( ) argument #1 must "
> "be of scalar type\n", fid->di_name);
>
> - /* FIXME */
> - if (dnp->dn_aggtup != NULL)
> - dnerror(dnp->dn_aggtup, D_ARR_BADREF, "indexing is not "
> - "supported yet: @%s\n", dnp->dn_ident->di_name);
> -
> assert(fid->di_id >= DT_AGG_BASE && fid->di_id < DT_AGG_HIGHEST);
>
> dt_cg_clsflags(pcb, DTRACEACT_AGGREGATION, dnp);
> aggfp = _dt_cg_agg[DT_AGG_IDX(fid->di_id)];
> assert(aggfp != NULL);
>
> + /* generate BPF code for keys (if any) */
> + tup = dt_cg_arglist(aid, dnp->dn_aggtup, dlp, drp);
> +
> + /* insert the aggregation var ID in the lead, 4-byte slot */
> + emit(dlp, BPF_STORE_IMM(BPF_W, tup, 0, aid->di_id));
> +
> + /* call dt_get_agg() to get the agg data pointer */
> +
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + emit(dlp, BPF_MOV_REG(BPF_REG_1, tup));
> + dt_regset_free(drp, tup);
> + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_2, BPF_REG_FP, DT_STK_DCTX));
> + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_2, BPF_REG_2, DCTX_GVARS));
> + emite(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -1), zero_off);
> +
> + switch (fid->di_id) {
> + case DT_AGG_MAX:
> + dt_cg_setx(dlp, BPF_REG_3, INT64_MIN);
> + break;
> + case DT_AGG_MIN:
> + dt_cg_setx(dlp, BPF_REG_3, INT64_MAX);
> + break;
> + default:
> + emit(dlp, BPF_MOV_IMM(BPF_REG_3, 0));
> + break;
> + }
> +
> + dt_regset_xalloc(drp, BPF_REG_0);
> + idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_get_agg");
> + assert(idp != NULL);
> + emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
> + dt_regset_free_args(drp);
> + Lgot_agg = dt_irlist_label(dlp);
> + emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, 0, Lgot_agg));
> + dt_cg_probe_error(yypcb, DTRACEFLT_NOAGGS, DT_ISIMM, 0);
> + emitl(dlp, Lgot_agg,
> + BPF_NOP());
> +
> + /* push agg data pointer onto the stack */
> +
> + dt_cg_push_stack(dlp, drp, BPF_REG_0);
> +
> + /* evaluate aggregation */
> (*aggfp)(pcb, aid, dnp, dlp, drp);
>
> /* add this agg id if we are seeing it for the first time */
> diff --git a/libdtrace/dt_dctx.h b/libdtrace/dt_dctx.h
> index c93fff2b..fe084d2e 100644
> --- a/libdtrace/dt_dctx.h
> +++ b/libdtrace/dt_dctx.h
> @@ -66,7 +66,6 @@ typedef struct dt_dctx {
> #define DCTX_MEM offsetof(dt_dctx_t, mem)
> #define DCTX_SCRATCHMEM offsetof(dt_dctx_t, scratchmem)
> #define DCTX_STRTAB offsetof(dt_dctx_t, strtab)
> -#define DCTX_AGG offsetof(dt_dctx_t, agg)
> #define DCTX_GVARS offsetof(dt_dctx_t, gvars)
> #define DCTX_LVARS offsetof(dt_dctx_t, lvars)
>
> diff --git a/libdtrace/dt_error.c b/libdtrace/dt_error.c
> index 576b1199..b9e19014 100644
> --- a/libdtrace/dt_error.c
> +++ b/libdtrace/dt_error.c
> @@ -207,6 +207,7 @@ dtrace_faultstr(dtrace_hdl_t *dtp, int fault)
> { DTRACEFLT_TUPOFLOW, "tuple stack overflow" },
> { DTRACEFLT_BADSTACK, "bad stack" },
> { DTRACEFLT_BADSIZE, "invalid size" },
> + { DTRACEFLT_NOAGGS, "out of aggregations space" },
> { DTRACEFLT_LIBRARY, "library-level fault" },
> { 0, NULL }
> };
> diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
> index be2b0121..85e2b878 100644
> --- a/libdtrace/dt_impl.h
> +++ b/libdtrace/dt_impl.h
> @@ -206,7 +206,7 @@ typedef struct dt_tstring {
> } dt_tstring_t;
>
> typedef struct dt_aggregate {
> - char **dtat_cpu_buf; /* per-CPU agg snapshot buffers */
> + char *dtat_nextkey; /* buffer for next key */
> char *dtat_buf; /* aggregation snapshot buffer */
> int dtat_flags; /* aggregate flags */
> dt_ahash_t dtat_hash; /* aggregate hash table */
> diff --git a/test/demo/intro/countdown-multiple.d b/test/demo/intro/countdown-multiple.d
> index 03db541e..e98f41ee 100644
> --- a/test/demo/intro/countdown-multiple.d
> +++ b/test/demo/intro/countdown-multiple.d
> @@ -1,11 +1,10 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
>
> -/* @@xfail: dtv2 */
> /* @@trigger: none */
>
> /* @@tags: unstable */
> diff --git a/test/demo/intro/countdown-quant.d b/test/demo/intro/countdown-quant.d
> index 2ab29b78..6a4b92a6 100644
> --- a/test/demo/intro/countdown-quant.d
> +++ b/test/demo/intro/countdown-quant.d
> @@ -1,11 +1,10 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
>
> -/* @@xfail: dtv2 */
> /* @@trigger: none */
>
> dtrace:::BEGIN
> diff --git a/test/demo/out/printa.d b/test/demo/out/printa.d
> index 28ba2175..ae63cfc6 100644
> --- a/test/demo/out/printa.d
> +++ b/test/demo/out/printa.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> profile:::tick-997
> {
> diff --git a/test/demo/script/syscall.d b/test/demo/script/syscall.d
> index 69091aa5..0b73d45b 100644
> --- a/test/demo/script/syscall.d
> +++ b/test/demo/script/syscall.d
> @@ -1,11 +1,10 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
>
> -/* @@xfail: dtv2 */
> /* @@runtest-opts: -c /bin/true */
> /* @@trigger: none */
>
> diff --git a/test/demo/user/libc.d b/test/demo/user/libc.d
> index 99e7a51c..dad274b8 100644
> --- a/test/demo/user/libc.d
> +++ b/test/demo/user/libc.d
> @@ -1,11 +1,10 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
>
> -/* @@xfail: dtv2 */
> /* @@runtest-opts: -c /usr/bin/date */
>
> pid$target:libc.so::entry
> diff --git a/test/stress/buffering/err.resize2.d b/test/stress/buffering/err.resize2.d
> index 277ec6cc..9b408958 100644
> --- a/test/stress/buffering/err.resize2.d
> +++ b/test/stress/buffering/err.resize2.d
> @@ -5,7 +5,6 @@
> * http://oss.oracle.com/licenses/upl.
> */
> /* @@timeout: 500 */
> -/* @@xfail: need support for aggregation keys */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/actions/printa/err.D_PRINTA_AGGKEY.d b/test/unittest/actions/printa/err.D_PRINTA_AGGKEY.d
> index c6014316..23859ebe 100644
> --- a/test/unittest/actions/printa/err.D_PRINTA_AGGKEY.d
> +++ b/test/unittest/actions/printa/err.D_PRINTA_AGGKEY.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
> /*
> * ASSERTION: printa() requires aggregation arguments to have matching key
> * signatures
> diff --git a/test/unittest/actions/printa/err.D_PRINTA_AGGPROTO.d b/test/unittest/actions/printa/err.D_PRINTA_AGGPROTO.d
> index d327a9c5..4be6fb45 100644
> --- a/test/unittest/actions/printa/err.D_PRINTA_AGGPROTO.d
> +++ b/test/unittest/actions/printa/err.D_PRINTA_AGGPROTO.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
> /*
> * ASSERTION: printa() requires aggregation arguments to have matching key
> * signatures (matching key component types)
> diff --git a/test/unittest/aggs/tst.count2.d b/test/unittest/aggs/tst.count2.d
> index b03c5cc2..b59a16b5 100644
> --- a/test/unittest/aggs/tst.count2.d
> +++ b/test/unittest/aggs/tst.count2.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.count3.d b/test/unittest/aggs/tst.count3.d
> index 4595fc74..a1884bac 100644
> --- a/test/unittest/aggs/tst.count3.d
> +++ b/test/unittest/aggs/tst.count3.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.denormalizeonly.d b/test/unittest/aggs/tst.denormalizeonly.d
> index c4e15141..d232f95e 100644
> --- a/test/unittest/aggs/tst.denormalizeonly.d
> +++ b/test/unittest/aggs/tst.denormalizeonly.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.fmtnormalize.d b/test/unittest/aggs/tst.fmtnormalize.d
> index 5b5b4154..a08f7368 100644
> --- a/test/unittest/aggs/tst.fmtnormalize.d
> +++ b/test/unittest/aggs/tst.fmtnormalize.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.forms.d b/test/unittest/aggs/tst.forms.d
> index ef129556..06e3996e 100644
> --- a/test/unittest/aggs/tst.forms.d
> +++ b/test/unittest/aggs/tst.forms.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.keysort.d b/test/unittest/aggs/tst.keysort.d
> index 9c157c3d..a8213bf2 100644
> --- a/test/unittest/aggs/tst.keysort.d
> +++ b/test/unittest/aggs/tst.keysort.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/aggs/tst.lquantize.d b/test/unittest/aggs/tst.lquantize.d
> index e09214a9..e1764238 100644
> --- a/test/unittest/aggs/tst.lquantize.d
> +++ b/test/unittest/aggs/tst.lquantize.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.lquantrange.d b/test/unittest/aggs/tst.lquantrange.d
> index 4b42d566..cd0a3fab 100644
> --- a/test/unittest/aggs/tst.lquantrange.d
> +++ b/test/unittest/aggs/tst.lquantrange.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/aggs/tst.lquantzero.d b/test/unittest/aggs/tst.lquantzero.d
> index 1b869ebb..8f69d9a9 100644
> --- a/test/unittest/aggs/tst.lquantzero.d
> +++ b/test/unittest/aggs/tst.lquantzero.d
> @@ -1,14 +1,12 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> -
> BEGIN
> {
> a = 7;
> diff --git a/test/unittest/aggs/tst.multiaggs1.d b/test/unittest/aggs/tst.multiaggs1.d
> index 371aa720..c9afd225 100644
> --- a/test/unittest/aggs/tst.multiaggs1.d
> +++ b/test/unittest/aggs/tst.multiaggs1.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.multinormalize.d b/test/unittest/aggs/tst.multinormalize.d
> index 90b8a32d..6abf76c2 100644
> --- a/test/unittest/aggs/tst.multinormalize.d
> +++ b/test/unittest/aggs/tst.multinormalize.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.neglquant.d b/test/unittest/aggs/tst.neglquant.d
> index 6629438b..63e3796b 100644
> --- a/test/unittest/aggs/tst.neglquant.d
> +++ b/test/unittest/aggs/tst.neglquant.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 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/aggs/tst.negorder.d b/test/unittest/aggs/tst.negorder.d
> index c6b2bba1..4d5e6386 100644
> --- a/test/unittest/aggs/tst.negorder.d
> +++ b/test/unittest/aggs/tst.negorder.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/aggs/tst.negquant.d b/test/unittest/aggs/tst.negquant.d
> index 78fa96ba..b9dff159 100644
> --- a/test/unittest/aggs/tst.negquant.d
> +++ b/test/unittest/aggs/tst.negquant.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 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/aggs/tst.order.d b/test/unittest/aggs/tst.order.d
> index e8a8b469..9777cab6 100644
> --- a/test/unittest/aggs/tst.order.d
> +++ b/test/unittest/aggs/tst.order.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/aggs/tst.quantize.d b/test/unittest/aggs/tst.quantize.d
> index db7b4190..3ae31449 100644
> --- a/test/unittest/aggs/tst.quantize.d
> +++ b/test/unittest/aggs/tst.quantize.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.quantmany.d b/test/unittest/aggs/tst.quantmany.d
> index b58f5326..de7d5635 100644
> --- a/test/unittest/aggs/tst.quantmany.d
> +++ b/test/unittest/aggs/tst.quantmany.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/aggs/tst.quantzero.d b/test/unittest/aggs/tst.quantzero.d
> index 8fc80b41..0b7d9fdf 100644
> --- a/test/unittest/aggs/tst.quantzero.d
> +++ b/test/unittest/aggs/tst.quantzero.d
> @@ -1,14 +1,12 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> -
> BEGIN
> {
> a = 7;
> diff --git a/test/unittest/aggs/tst.signedkeyspos.d b/test/unittest/aggs/tst.signedkeyspos.d
> index 93803a7e..9530ab5c 100644
> --- a/test/unittest/aggs/tst.signedkeyspos.d
> +++ b/test/unittest/aggs/tst.signedkeyspos.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/aggs/tst.valsortkeypos.d b/test/unittest/aggs/tst.valsortkeypos.d
> index 9f8fe0dd..d1de72b4 100644
> --- a/test/unittest/aggs/tst.valsortkeypos.d
> +++ b/test/unittest/aggs/tst.valsortkeypos.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/funcs/substr/tst.substrminate.d b/test/unittest/funcs/substr/tst.substrminate.d
> index 84aa60c7..573a2076 100644
> --- a/test/unittest/funcs/substr/tst.substrminate.d
> +++ b/test/unittest/funcs/substr/tst.substrminate.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 */
>
> #pragma D option quiet
> #pragma D option aggsortkey
> diff --git a/test/unittest/grammar/tst.stmts.d b/test/unittest/grammar/tst.stmts.d
> index 18ed60b2..919c3166 100644
> --- a/test/unittest/grammar/tst.stmts.d
> +++ b/test/unittest/grammar/tst.stmts.d
> @@ -1,6 +1,6 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> @@ -13,7 +13,6 @@
> *
> */
>
> -/* @@xfail: dtv2 */
> /* @@timeout: 25 */
>
> BEGIN
> diff --git a/test/unittest/misc/tst.haslam.d b/test/unittest/misc/tst.haslam.d
> index 997d22df..406a9ead 100644
> --- a/test/unittest/misc/tst.haslam.d
> +++ b/test/unittest/misc/tst.haslam.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION: test for off-by-one error in the format lookup code
> diff --git a/test/unittest/multiaggs/err.D_PRINTA_AGGKEY.d b/test/unittest/multiaggs/err.D_PRINTA_AGGKEY.d
> index a5b5c522..a9ea789b 100644
> --- a/test/unittest/multiaggs/err.D_PRINTA_AGGKEY.d
> +++ b/test/unittest/multiaggs/err.D_PRINTA_AGGKEY.d
> @@ -1,10 +1,10 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
> +
> #pragma D option quiet
>
> BEGIN
> diff --git a/test/unittest/multiaggs/err.D_PRINTA_AGGPROTO.d b/test/unittest/multiaggs/err.D_PRINTA_AGGPROTO.d
> index 238421f4..b8887e81 100644
> --- a/test/unittest/multiaggs/err.D_PRINTA_AGGPROTO.d
> +++ b/test/unittest/multiaggs/err.D_PRINTA_AGGPROTO.d
> @@ -1,10 +1,10 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
> +
> #pragma D option quiet
>
> BEGIN
> diff --git a/test/unittest/multiaggs/tst.many.d b/test/unittest/multiaggs/tst.many.d
> index 5c94d2da..168cca13 100644
> --- a/test/unittest/multiaggs/tst.many.d
> +++ b/test/unittest/multiaggs/tst.many.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option destructive
> #pragma D option quiet
> diff --git a/test/unittest/multiaggs/tst.sort.d b/test/unittest/multiaggs/tst.sort.d
> index c61e2c1a..f9be92df 100644
> --- a/test/unittest/multiaggs/tst.sort.d
> +++ b/test/unittest/multiaggs/tst.sort.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/multiaggs/tst.sortpos.d b/test/unittest/multiaggs/tst.sortpos.d
> index f6adb378..36763186 100644
> --- a/test/unittest/multiaggs/tst.sortpos.d
> +++ b/test/unittest/multiaggs/tst.sortpos.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/multiaggs/tst.zero.d b/test/unittest/multiaggs/tst.zero.d
> index acfb99e1..197949cd 100644
> --- a/test/unittest/multiaggs/tst.zero.d
> +++ b/test/unittest/multiaggs/tst.zero.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/multiaggs/tst.zero2.d b/test/unittest/multiaggs/tst.zero2.d
> index 28cd4cbf..cba509bc 100644
> --- a/test/unittest/multiaggs/tst.zero2.d
> +++ b/test/unittest/multiaggs/tst.zero2.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/multiaggs/tst.zero3.d b/test/unittest/multiaggs/tst.zero3.d
> index 31b41acc..6dd3763f 100644
> --- a/test/unittest/multiaggs/tst.zero3.d
> +++ b/test/unittest/multiaggs/tst.zero3.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/printa/tst.dynwidth.d b/test/unittest/printa/tst.dynwidth.d
> index 06051ae1..d6039ca3 100644
> --- a/test/unittest/printa/tst.dynwidth.d
> +++ b/test/unittest/printa/tst.dynwidth.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> #pragma D option quiet
>
> diff --git a/test/unittest/printa/tst.tuple.d b/test/unittest/printa/tst.tuple.d
> index 4fc05e6a..2996edaa 100644
> --- a/test/unittest/printa/tst.tuple.d
> +++ b/test/unittest/printa/tst.tuple.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> --
> 2.18.4
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list