[DTrace-devel] [PATCH v3 5/9] Handle stack() and ustack() args in a separate function

Kris Van Hees kris.van.hees at oracle.com
Wed Jan 31 03:47:05 UTC 2024


On Tue, Jan 30, 2024 at 06:31:08PM -0500, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
> 
> Currently, dt_cg_act_stack() and dt_cg_act_ustack() generate BPF code
> to implement the stack() and ustack() actions.  However, it should also
> be possible to use stack() and ustack() as aggregation keys.  So, it
> would be nice to move the main work of the code-generation functions
> to separate functions that can be used by different callers.
> 
> Therefore, start refactoring these cg functions so that what they do
> can be invoked by multiple callers.  Here, simply move the handling of
> the stack() and ustack() args out into a separate function.  (Actually,
> that handling does not even involve any code generation.)
> 
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>

Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>

> ---
>  libdtrace/dt_cg.c | 118 ++++++++++++++++++++++++++--------------------
>  1 file changed, 67 insertions(+), 51 deletions(-)
> 
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 1e4bb707..1f70ccb3 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -2501,34 +2501,77 @@ dt_cg_act_speculate(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  	dt_regset_free(drp, dnp->dn_reg);
>  }
>  
> +static uint64_t
> +dt_cg_stack_arg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_actkind_t kind)
> +{
> +	int		nframes;
> +	int		strsize = 0;
> +	dt_node_t	*arg0 = dnp->dn_args;
> +	dt_node_t	*arg1 = arg0 != NULL ? arg0->dn_list : NULL;
> +	int		indopt, def, inderr;
> +	char		*fname;
> +
> +	if (kind == DTRACEACT_USTACK) {
> +		indopt = DTRACEOPT_USTACKFRAMES;
> +		def = _dtrace_ustackframes;
> +		inderr = D_USTACK_FRAMES;
> +		fname = "ustack";
> +	} else if (kind == DTRACEACT_STACK) {
> +		indopt = DTRACEOPT_STACKFRAMES;
> +		def = _dtrace_stackframes;
> +		inderr = D_STACK_SIZE;
> +		fname = "stack";
> +	} else {
> +		assert(0);
> +	}
> +
> +	/* Get the default number. */
> +	nframes = dtp->dt_options[indopt];
> +	if (nframes == DTRACEOPT_UNSET)
> +		nframes = def;
> +
> +	/* Get the specified value, if any. */
> +	if (arg0 != NULL) {
> +		if (!dt_node_is_posconst(arg0))
> +			dnerror(arg0, inderr,
> +				"%s( ) argument #1 must be a non-zero positive integer constant\n",
> +				fname);
> +		nframes = arg0->dn_value;
> +	}
> +
> +	/* If more frames are requested than allowed, silently reduce nframes. */
> +	if (nframes > dtp->dt_options[DTRACEOPT_MAXFRAMES])
> +		nframes = dtp->dt_options[DTRACEOPT_MAXFRAMES];
> +
> +	/* For user stacks, process one more argument. */
> +	if (kind == DTRACEACT_USTACK && arg1 != NULL) {
> +		if (arg1->dn_kind != DT_NODE_INT ||
> +		    ((arg1->dn_flags & DT_NF_SIGNED) &&
> +		    (int64_t)arg1->dn_value < 0))
> +			dnerror(arg1, D_USTACK_STRSIZE,
> +				"ustack( ) argument #2 must be a positive integer constant\n");
> +
> +		/* FIXME: for now, accept non-zero strsize, but it does nothing */
> +		strsize = arg1->dn_value;
> +	}
> +
> +	return DTRACE_USTACK_ARG(nframes, strsize);
> +}
> +
>  static void
>  dt_cg_act_stack(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  {
>  	dtrace_hdl_t	*dtp = pcb->pcb_hdl;
>  	dt_irlist_t	*dlp = &pcb->pcb_ir;
>  	dt_regset_t	*drp = pcb->pcb_regs;
> -	dt_node_t	*arg = dnp->dn_args;
> -	int		nframes = dtp->dt_options[DTRACEOPT_STACKFRAMES];
> +	uint64_t	arg;
> +	int		nframes;
>  	int		skip = 0;
>  	uint_t		off;
>  	uint_t		lbl_valid = dt_irlist_label(dlp);
>  
> -	if (nframes == DTRACEOPT_UNSET)
> -		nframes = _dtrace_stackframes;
> -
> -	if (arg != NULL) {
> -		if (!dt_node_is_posconst(arg))
> -			dnerror(arg, D_STACK_SIZE, "stack( ) argument #1 must "
> -				"be a non-zero positive integer constant\n");
> -
> -		nframes = arg->dn_value;
> -	}
> -
> -	/*
> -	 * If more frames are requested than allowed, silently reduce nframes.
> -	 */
> -	if (nframes > dtp->dt_options[DTRACEOPT_MAXFRAMES])
> -		nframes = dtp->dt_options[DTRACEOPT_MAXFRAMES];
> +	arg = dt_cg_stack_arg(dtp, dnp, DTRACEACT_STACK);
> +	nframes = DTRACE_USTACK_NFRAMES(arg);
>  
>  	/* Reserve space in the output buffer. */
>  	off = dt_rec_add(dtp, dt_cg_fill_gap, DTRACEACT_STACK,
> @@ -2711,46 +2754,19 @@ dt_cg_act_ustack(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  	dt_irlist_t	*dlp = &pcb->pcb_ir;
>  	dt_regset_t	*drp = pcb->pcb_regs;
>  	dtrace_hdl_t	*dtp = pcb->pcb_hdl;
> -	int		nframes = dtp->dt_options[DTRACEOPT_USTACKFRAMES];
> -	int		strsize = 0;
> -	int		stacksize;
> -	dt_node_t	*arg0 = dnp->dn_args;
> -	dt_node_t	*arg1 = arg0 != NULL ? arg0->dn_list : NULL;
> +	uint64_t	arg;
> +	int		nframes, stacksize;
>  	int		skip = 0;
>  	uint_t		off;
>  	uint_t		lbl_valid = dt_irlist_label(dlp);
>  
> -	if (nframes == DTRACEOPT_UNSET)
> -		nframes = _dtrace_ustackframes;
> -
> -	if (arg0 != NULL) {
> -		if (!dt_node_is_posconst(arg0))
> -			dnerror(arg0, D_USTACK_FRAMES, "ustack( ) argument #1 "
> -				"must be a non-zero positive integer "
> -				"constant\n");
> -
> -		nframes = arg0->dn_value;
> -	}
> -
> -	if (nframes > dtp->dt_options[DTRACEOPT_MAXFRAMES])
> -		nframes = dtp->dt_options[DTRACEOPT_MAXFRAMES];
> -
> -	/* FIXME: for now, accept non-zero strsize, but it does nothing */
> -	if (arg1 != NULL) {
> -		if (arg1->dn_kind != DT_NODE_INT ||
> -		    ((arg1->dn_flags & DT_NF_SIGNED) &&
> -		    (int64_t)arg1->dn_value < 0))
> -			dnerror(arg1, D_USTACK_STRSIZE, "ustack( ) argument #2 "
> -				"must be a positive integer constant\n");
> -
> -		strsize = arg1->dn_value;
> -	}
> +	arg = dt_cg_stack_arg(dtp, dnp, DTRACEACT_USTACK);
> +	nframes = DTRACE_USTACK_NFRAMES(arg);
> +	stacksize = nframes * sizeof(uint64_t);
>  
>  	/* Reserve space in the output buffer. */
> -	stacksize = nframes * sizeof(uint64_t);
>  	off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, DTRACEACT_USTACK,
> -			 8 + stacksize, 8, NULL,
> -			 DTRACE_USTACK_ARG(nframes, strsize));
> +			 8 + stacksize, 8, NULL, arg);
>  
>  	if (dt_regset_xalloc_args(drp) == -1)
>  		longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> -- 
> 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