[DTrace-devel] [PATCH v2 03/13] Compute lquantize() bin only once
eugene.loh at oracle.com
eugene.loh at oracle.com
Tue Dec 8 09:19:22 PST 2020
From: Eugene Loh <eugene.loh at oracle.com>
First, quantize the value into a 0-based bin number. As was done for
quantize(), use C code in the bpf/ subdirectory to be cross-compiled
into BPF when DTrace is built.
Then, the "implementation" function -- which needs to run twice, once
per aggregation copy -- is simply dt_cg_agg_quantize_impl(). That is,
we reuse the same function for lquantize() that was originally introduced
for quantize().
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
bpf/Build | 2 +-
bpf/agg_lqbin.c | 24 +++++++++++
libdtrace/dt_cg.c | 95 +++++++++-----------------------------------
libdtrace/dt_dlibs.c | 1 +
4 files changed, 44 insertions(+), 78 deletions(-)
create mode 100644 bpf/agg_lqbin.c
diff --git a/bpf/Build b/bpf/Build
index ae298f79..e9f2b1e2 100644
--- a/bpf/Build
+++ b/bpf/Build
@@ -22,7 +22,7 @@ bpf_dlib_TARGET = dlibs/bpf_dlib
bpf_dlib_DIR := $(current-dir)
bpf_dlib_SRCDEPS = $(objdir)/include/.dir.stamp
bpf_dlib_SOURCES = \
- agg_qbin.c \
+ agg_lqbin.c agg_qbin.c \
get_bvar.c \
get_gvar.c set_gvar.c \
get_tvar.c set_tvar.c \
diff --git a/bpf/agg_lqbin.c b/bpf/agg_lqbin.c
new file mode 100644
index 00000000..502205f7
--- /dev/null
+++ b/bpf/agg_lqbin.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020, 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
+
+noinline uint64_t dt_agg_lqbin(int64_t val, int64_t base,
+ uint64_t levels, uint64_t step)
+{
+ uint64_t level;
+
+ if (step == 0 || val < base)
+ return 0;
+ level = (val - base) / step;
+ if (level > levels)
+ level = levels;
+ return level + 1;
+}
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 69ecf16c..a73e2423 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -3314,80 +3314,6 @@ dt_cg_agg_llquantize(dt_pcb_t *pcb, dt_ident_t *aid, dt_node_t *dnp,
aid->di_offset = DT_CG_AGG_OFFSET(pcb, sz);
}
-static void
-dt_cg_agg_lquantize_impl(dt_irlist_t *dlp, dt_regset_t *drp, int dreg,
- int vreg, int ireg, int32_t base, uint16_t levels,
- uint16_t step)
-{
- uint_t lbl_l1 = dt_irlist_label(dlp);
- uint_t lbl_l2 = dt_irlist_label(dlp);
- uint_t lbl_add = dt_irlist_label(dlp);
-
- TRACE_REGSET(" Impl: Begin");
-
- /*
- * // (%rd = dreg -- agg data)
- * // (%rv = val)
- * // (%ri = incr)
- * if (val >= base) // jge %rv, base, L1
- * goto L1; //
- *
- * tmp = dreg; // mov %r0, %rd
- * goto ADD; // ja ADD
- */
- emit(dlp, BPF_BRANCH_IMM(BPF_JSGE, vreg, base, lbl_l1));
- dt_regset_xalloc(drp, BPF_REG_0);
- emit(dlp, BPF_MOV_REG(BPF_REG_0, dreg));
- emit(dlp, BPF_JUMP(lbl_add));
-
- /*
- * L1: level = (val - base) / step;
- * // L1:
- * // mov %r0, %rv
- * // sub %r0, base
- * // div %r0, step
- * if (level < levels) // jlt %r0, levels, L2
- * goto L2;
- *
- * tmp = dreg + 8 * (levels + 1);
- * // mov %r0, levels + 1
- * // lsh %r0, 3
- * // add %r0, %rd
- * goto ADD; // ja ADD
- */
- emitl(dlp, lbl_l1,
- BPF_MOV_REG(BPF_REG_0, vreg));
- emit(dlp, BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, base));
- emit(dlp, BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, step));
- emit(dlp, BPF_BRANCH_IMM(BPF_JLT, BPF_REG_0, levels, lbl_l2));
-
- emit(dlp, BPF_MOV_IMM(BPF_REG_0, levels + 1));
- emit(dlp, BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 3));
- emit(dlp, BPF_ALU64_REG(BPF_ADD, BPF_REG_0, dreg));
- emit(dlp, BPF_JUMP(lbl_add));
-
- /*
- * L2: tmp = dreg + 8 * (level + 1);
- * // L2:
- * // add %r0, 1
- * // lsh %r0, 3
- * // add %r0, %rd
- */
- emitl(dlp, lbl_l2,
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1));
- emit(dlp, BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 3));
- emit(dlp, BPF_ALU64_REG(BPF_ADD, BPF_REG_0, dreg));
-
- /*
- * ADD: (*tmp) += incr; // xadd [%r0 + 0], %ri
- */
- emitl(dlp, lbl_add,
- BPF_XADD_REG(BPF_DW, BPF_REG_0, 0, ireg));
- dt_regset_free(drp, BPF_REG_0);
-
- TRACE_REGSET(" Impl: End ");
-}
-
static void
dt_cg_agg_lquantize(dt_pcb_t *pcb, dt_ident_t *aid, dt_node_t *dnp,
dt_irlist_t *dlp, dt_regset_t *drp)
@@ -3410,6 +3336,7 @@ dt_cg_agg_lquantize(dt_pcb_t *pcb, dt_ident_t *aid, dt_node_t *dnp,
uint64_t step = 1;
int64_t baseval, limitval;
int sz, ireg;
+ dt_ident_t *idp;
if (arg1->dn_kind != DT_NODE_INT)
dnerror(arg1, D_LQUANT_BASETYPE, "lquantize( ) argument #1 "
@@ -3525,6 +3452,21 @@ dt_cg_agg_lquantize(dt_pcb_t *pcb, dt_ident_t *aid, dt_node_t *dnp,
dt_cg_node(dnp->dn_aggfun->dn_args, dlp, drp);
+ /* quantize the value to a 0-based bin # using dt_agg_lqbin() */
+ if (dt_regset_xalloc_args(drp) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ emit(dlp, BPF_MOV_REG(BPF_REG_1, dnp->dn_aggfun->dn_args->dn_reg));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_2, baseval));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_3, nlevels));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_4, step));
+ idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_agg_lqbin");
+ assert(idp != NULL);
+ dt_regset_xalloc(drp, BPF_REG_0);
+ emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
+ dt_regset_free_args(drp);
+ emit(dlp, BPF_MOV_REG(dnp->dn_aggfun->dn_args->dn_reg, BPF_REG_0));
+ dt_regset_free(drp, BPF_REG_0);
+
if (incr == NULL) {
if ((ireg = dt_regset_alloc(drp)) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
@@ -3535,9 +3477,8 @@ dt_cg_agg_lquantize(dt_pcb_t *pcb, dt_ident_t *aid, dt_node_t *dnp,
ireg = incr->dn_reg;
}
- DT_CG_AGG_IMPL(aid, sz, dlp, drp, dt_cg_agg_lquantize_impl,
- dnp->dn_aggfun->dn_args->dn_reg, ireg,
- baseval, nlevels, step);
+ DT_CG_AGG_IMPL(aid, sz, dlp, drp, dt_cg_agg_quantize_impl,
+ dnp->dn_aggfun->dn_args->dn_reg, ireg, nlevels + 1);
dt_regset_free(drp, dnp->dn_aggfun->dn_args->dn_reg);
dt_regset_free(drp, ireg);
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index e3ab2231..f1d0b29a 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -52,6 +52,7 @@ static const dt_ident_t dt_bpf_symbols[] = {
/* BPF built-in functions */
DT_BPF_SYMBOL(dt_program, DT_IDENT_FUNC),
/* BPF library (external) functions */
+ DT_BPF_SYMBOL(dt_agg_lqbin, DT_IDENT_SYMBOL),
DT_BPF_SYMBOL(dt_agg_qbin, DT_IDENT_SYMBOL),
DT_BPF_SYMBOL(dt_get_bvar, DT_IDENT_SYMBOL),
DT_BPF_SYMBOL(dt_get_gvar, DT_IDENT_SYMBOL),
--
2.18.4
More information about the DTrace-devel
mailing list