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

Kris Van Hees kris.van.hees at oracle.com
Wed Sep 2 13:56:55 PDT 2020


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.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_cg.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 01e8707f..d289e02b 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -674,7 +674,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
@@ -682,12 +684,54 @@ 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;
+	dt_ident_t	*state = dt_dlib_get_map(pcb->pcb_hdl, "state");
+	struct bpf_insn	instr;
 	uint_t		off;
 
+	/* Evaluate the exit code expression. */
 	dt_cg_node(dnp->dn_args, &pcb->pcb_ir, pcb->pcb_regs);
 
+	/*
+	 * 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)
+	 */
+	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));
+
+	/* Record the exit code. */
 	off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, DTRACEACT_EXIT,
 			 sizeof(uint32_t), sizeof(uint32_t), NULL,
 			 DT_ACT_EXIT);
-- 
2.28.0




More information about the DTrace-devel mailing list