[DTrace-devel] [PATCH v2 02/08] The exit() action must set the activity state to DRAINING

Eugene Loh eugene.loh at oracle.com
Thu Sep 17 12:48:27 PDT 2020


On 09/14/2020 12:50 PM, Kris Van Hees wrote:

> Now that activity state is supported, the exit() action needs to move
> the activity state to DRAINING to prevent further probe firings from
> being processed.
>
> The recording of the exit code is now done using the dt_cg_store_val()
> function since that is the preferred manner of storing values into the
> output buffer.
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>   libdtrace/dt_cg.c | 54 ++++++++++++++++++++++++++++++++++++++---------
>   1 file changed, 44 insertions(+), 10 deletions(-)
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index e94a605f..14e11f06 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -676,7 +676,9 @@ dt_cg_act_discard(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>   }
>   
>   /*
> - * Signal that tracing should be terminated with the given return code.
> + * Signal that tracing should be terminated with the given return code.  This
> + * action also forces the activity state to be set to DRAINING to signal that
> + * tracing is ending.
>    *
>    * Stores:
>    *	integer (4 bytes)		-- return code
> @@ -684,19 +686,51 @@ dt_cg_act_discard(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>   static void
>   dt_cg_act_exit(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>   {
> -	struct bpf_insn	instr;
>   	dt_irlist_t	*dlp = &pcb->pcb_ir;
> -	uint_t		off;
> -
> -	dt_cg_node(dnp->dn_args, &pcb->pcb_ir, pcb->pcb_regs);
> +	dt_ident_t	*state = dt_dlib_get_map(pcb->pcb_hdl, "state");
> +	struct bpf_insn	instr;
>   
> -	off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, DTRACEACT_EXIT,
> -			 sizeof(uint32_t), sizeof(uint32_t), NULL,
> -			 DT_ACT_EXIT);
> +	/* Record the exit code. */
> +	dt_cg_store_val(pcb, dnp->dn_args, DTRACEACT_EXIT, NULL, DT_ACT_EXIT);
>   
> -	instr = BPF_STORE(BPF_W, BPF_REG_9, off, dnp->dn_args->dn_reg);
> +	/*
> +	 * Force the activity state to DRAINING.
> +	 *
> +	 *	key = DT_STATE_ACTIVITY;// stw [%fp + DT_STK_SPILL(0)],
> +	 *				//		DT_STATE_ACTIVITY
> +	 *	val = DT_ACTIVITY_DRAINING;
> +	 *				// stw [%fp + DT_STK_SPILL(1)],
> +	 *				//		DT_ACTIVITY_DRAINING
> +	 *	rc = bpf_map_update_elem(&state, &key, &val, BPF_ANY);
> +	 *				// lddw %r1, &state
> +	 *				// mov %r2, %fp
> +	 *				// add %r2, DT_STK_SPILL(0)
> +	 *				// mov %r3, %fp
> +	 *				// add %r3, DT_STK_SPILL(1)
> +	 *				// mov %r4, BPF_ANY
> +	 *				// call bpf_map_update_elem
> +	 *				//     (%r1 ... %r5 clobbered)
> +	 *				//     (%r0 = map value)

r0 is not a map value but a return status.  Anyhow, we just drop that 
value on the floor, so I would think the comment can be discarded entirely.

In a similar vein, I don't understand the value of the "clobbered" comment.

Meanwhile, something puzzles me and so let me ask a lazy question. 
Should we be allocating (and freeing) registers 0-5 before (and after) 
the helper call?  I don't trust myself to think about these things 
correctly and so would appreciate any comments.

> +	 */
> +	instr = BPF_STORE_IMM(BPF_W, BPF_REG_FP, DT_STK_SPILL(0),
> +			      DT_STATE_ACTIVITY);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_STORE_IMM(BPF_W, BPF_REG_FP, DT_STK_SPILL(1),
> +			      DT_ACTIVITY_DRAINING);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	dt_cg_xsetx(dlp, state, DT_LBL_NONE, BPF_REG_1, state->di_id);
> +	instr = BPF_MOV_REG(BPF_REG_2, BPF_REG_FP);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, DT_STK_SPILL(0));
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_MOV_REG(BPF_REG_3, BPF_REG_FP);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, DT_STK_SPILL(1));
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_MOV_IMM(BPF_REG_4, BPF_ANY);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_CALL_HELPER(BPF_FUNC_map_update_elem);
>   	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> -	dt_regset_free(pcb->pcb_regs, dnp->dn_args->dn_reg);
>   }
>   
>   static void




More information about the DTrace-devel mailing list