[DTrace-devel] [PATCH] Allow dt_cg_arglist() to handle the NULL case
Kris Van Hees
kris.van.hees at oracle.com
Tue Aug 16 05:05:19 UTC 2022
On Mon, Aug 15, 2022 at 07:35:37PM -0700, Eugene Loh via DTrace-devel wrote:
> Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
Thanks.
> That said, this patch bewilders me with its complexity. The previous patch
> (return register) seemed quite a bit simpler. I do not understand the
> rationale for the increased complexity.
Yes, but the previous patch was a bit of a hack I think. One option could
have been to rewrite dt_cg_arglist() to always return the register holding
the tuple pointer and not store it in args->dn_reg at all. That would
require the callers to be modified but that was certainly an option. But
it would make dt_cg_arglist() quite different from most other codegen funcs
that generate code for the node tree they are given, decorating the given
node with the register that holds the resulting value.
I opted to stick with the typical way codegen funcs are implemented.
> A few more comments embedded...
>
>
> On 8/15/22 11:45, Kris Van Hees via DTrace-devel wrote:
>
> Even if an argument is empty, we might want to call dt_cg_arglist() to
> construct a pointer to a tuple.
>
> Callers can use the following pseudo-code to accomplish this:
>
>
> Given the trickiness, it's good to see an explanation of how to use arglist()
> in the NULL case. I would think, however, that the explanation should go in a
> comment block for dt_cg_arglist() rather than in the commit history. The
> former is a much easier place for users to find such info.
It is here in the commit message because adding it as a comment would be rather
overkill, especially once the next patch goes in which adds the code that makes
use of this functionality. So there will be a sample of how to use it right in
the code anyway.
> ââââââdt_node_tââânoargs = {
> ââââââââââââââââââââââââdnp->dn_ctfp,
> ââââââââââââââââââââââââdtp->dt_type_void,
> ââââââââââââââââââ};
>
> ââââââ...
>
> ââââââif (dnp->dn_aggtup == NULL)
> ââââââââââââdnp->dn_aggtup = &noargs;
>
>
> Why is dnp->dn_aggtup being set to anything (and restored later)? It's not
> being used. Or, is the point that you did not mean to hardwire noargs into the
> arglist call? Maybe you meant something like
The sample I am using prefigures the following patch that modifies the way
aggregations are implemented. I didn't want to put too much extra code in,
so by using dnp->dn_aggtup I convey what node we are working with. It is
pseudo code after all.
> dt_node_t *args = dnp->dn_aggtup ? dnp->dn_aggtup : &noargs;
> dt_cg_arglist(aid, args, dlp, drp);
> // use args->dn_reg
>
>
> ââââââdt_cg_arglist(aid, &noargs, dlp, drp);
>
> ââââââ... <use dnp->dn_aggtup->dn_reg> ...
>
> ââââââif (dnp->aggtup == &noargs)
> ââââââââââââdnp->aggtup = NULL;
>
> ââââââ... <dnp->dn_aggtup->dn_reg is not used anympre> ...
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
> libdtrace/dt_bpf.c | 18 +++++++++++-------
> libdtrace/dt_cg.c | 10 +++++++---
> libdtrace/dt_impl.h | 1 +
> libdtrace/dt_open.c | 4 +++-
> 4 files changed, 22 insertions(+), 11 deletions(-)
>
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> index 4cb0eec6..f3f8c79d 100644
> --- a/libdtrace/dt_bpf.c
> +++ b/libdtrace/dt_bpf.c
> @@ -510,15 +510,19 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
> âââââââââââdvarc = dtp->dt_options[DTRACEOPT_DYNVARSIZE] /
> âââââââââââââââââdtp->dt_maxdvarsize;
>
> -âââââif (dvarc > 0 &&
> -âââââ create_gmap(dtp, "dvars", BPF_MAP_TYPE_HASH,
> -âââââââââââââââââsizeof(uint64_t), dtp->dt_maxdvarsize, dvarc) == -1)
> +âââââif (dvarc > 0) {
> +âââââââââââif (create_gmap(dtp, "dvars", BPF_MAP_TYPE_HASH,
> +âââââââââââââââââââââââsizeof(uint64_t), dtp->dt_maxdvarsize,
> +âââââââââââââââââââââââdvarc) == -1)
> âââââââââââââââââreturn -1;ââ/* dt_errno is set for us */
>
> -âââââif (dtp->dt_maxtuplesize > 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 */
> +âââââââââââassert(dtp->dt_maxtuplesize > 0);
> +
> +âââââââââââif (create_gmap(dtp, "tuples", BPF_MAP_TYPE_HASH,
> +âââââââââââââââââ dtp->dt_maxtuplesize, sizeof(uint64_t),
> +âââââââââââââââââ dvarc) == -1)
> +âââââââââââââââââreturn -1;ââ/* dt_errno is set for us */
> +âââââ}
>
> âââââ/* Populate the 'cpuinfo' map. */
> âââââdt_bpf_map_update(ci_mapfd, &key, dtp->dt_conf.cpus);
>
> Do the dt_bpf.c changes really belong in this patch? I'm fine with the
> changes, but surprised they are included here.
It could go in its own patch as well, but in a sense it is related to the
change here because it expands the notion of a tuple beyond dynamic variables,
which means that we may have a max tuple size without using dynamic variables.
That would result in a tuples map being created with a maximum number of
entries of 0 (dvarc = 0) and that triggers a map creation failure. Since that
is directly related to this patch, the fix for it is included in it.
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 175c4b95..0963f202 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -2600,13 +2600,17 @@ dt_cg_arglist(dt_ident_t *idp, dt_node_t *args,
> dt_irlist_t *dlp,
> âââââconst dt_idsig_tââ*isp = idp->di_data;
> âââââdt_node_tâââââââââ*dnp;
> âââââdt_ident_tââââââââ*maxtupsz = dt_dlib_get_var(dtp, "TUPSZ");
> -âââââintâââââââââââââââi;
> +âââââintâââââââââââââââi = 0;
> âââââintâââââââââââââââtreg, areg;
> âââââuint_tââââââââââââââââââtuplesize;
>
> âââââTRACE_REGSET(" arglist: Begin");
>
> -âââââfor (dnp = args, i = 0; dnp != NULL; dnp = dnp->dn_list, i++) {
> +âââââ/* A 'void' args node indicates an empty argument list. */
> +âââââif (dt_node_is_void(args))
> +âââââââââââgoto empty_args;
> +
> +âââââfor (dnp = args; dnp != NULL; dnp = dnp->dn_list, i++) {
> âââââââââââ/* Bail early if we run out of tuple slots. */
> âââââââââââif (i > dtp->dt_conf.dtc_diftupregs)
> âââââââââââââââââlongjmp(yypcb->pcb_jmpbuf, EDT_NOTUPREG);
> @@ -2623,6 +2627,7 @@ dt_cg_arglist(dt_ident_t *idp, dt_node_t *args,
> dt_irlist_t *dlp,
> âââââââââââdt_regset_free(drp, BPF_REG_0);
> âââââ}
>
> +empty_args:
> âââââTRACE_REGSET(" arglist: Stack");
>
> âââââ/*
>
>
> I have a question about the looping (which we do not see in the patch text).
> The first loop computes values. The second loop stores the values. In the
> "NULL" case, we have an "if" statement that jumps over the first loop. In
> contrast, the second loop gets executed. Its first iteration short circuits
> due to size==0. Then the second iteration exits. I *think* that's what's
> going on and should work, but would not mind a sanity check since it was not at
> first clear to me what was going on.
That is indeed what happens.
>
> @@ -6669,7 +6674,6 @@ dt_cg_agg(dt_pcb_t *pcb, dt_node_t *dnp, dt_irlist_t
> *dlp, dt_regset_t *drp)
> âââââââââââ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);
> diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
> index c1ff6256..85a1e7c9 100644
> --- a/libdtrace/dt_impl.h
> +++ b/libdtrace/dt_impl.h
> @@ -329,6 +329,7 @@ struct dtrace_hdl {
> âââââctf_id_t dt_type_stack;â/* cached CTF identifier for stack type */
> âââââctf_id_t dt_type_symaddr; /* cached CTF identifier for _symaddr type
> */
> âââââctf_id_t dt_type_usymaddr; /* cached CTF ident. for _usymaddr type */
> +âââââctf_id_t dt_type_void;ââ/* cached CTF identifier for void type */
> âââââdtrace_epid_t dt_nextepid; /* next enabled probe ID to assign */
> âââââsize_t dt_maxprobe;âââââ/* max enabled probe ID */
> âââââdtrace_datadesc_t **dt_ddesc; /* probe data descriptions */
> diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
> index f5cbd499..581172e2 100644
> --- a/libdtrace/dt_open.c
> +++ b/libdtrace/dt_open.c
> @@ -1055,10 +1055,12 @@ dt_vopen(int version, int flags, int *errp,
> âââââdtp->dt_type_usymaddr = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
> âââââ "_usymaddr", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
>
> +âââââdtp->dt_type_void = ctf_lookup_by_name(dmp->dm_ctfp, "void");
> +
> âââââif (dtp->dt_type_func == CTF_ERR || dtp->dt_type_fptr == CTF_ERR ||
> âââââ dtp->dt_type_str == CTF_ERR || dtp->dt_type_dyn == CTF_ERR ||
> âââââ dtp->dt_type_stack == CTF_ERR || dtp->dt_type_symaddr == CTF_ERR
> ||
> -âââââ dtp->dt_type_usymaddr == CTF_ERR) {
> +âââââ dtp->dt_type_usymaddr == CTF_ERR || dtp->dt_type_void == CTF_ERR)
> {
> âââââââââââdt_dprintf("failed to add intrinsic to D container: %s\n",
> âââââââââââ ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
> âââââââââââreturn set_open_errno(dtp, errp, EDT_CTF);
> --
> 2.34.1
>
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
>
> _______________________________________________
> 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