From ae127d2b21531a2a512325e8df8f523e98fc7e5b Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Thu, 23 May 2013 10:52:00 -0400 Subject: [PATCH] Finish the implementation of is-enabled USDT probes. This commit completes the implementation of is-enabled USDT probes, i.e. probes that when fired cause an execution flow change. This makes it possible (when using USDT) to encode more complex code sections that are only executed if a specific USDT probe has been enabled, i.e. when a consumer is listening for s specific USDT probe. This is most commonly used for cases where a USDT probe might require additional computation for one or more of its arguments, and so it would be too expensive to always do that computation, whether the probe is enabled or not. With is-enabled probes, the overhead when DTrace is not used is negligible (2 NOPs), and when DTrace is in use but the guarded probe is not enabled, the cost is a single probe firing (without calling dtrace_probe()). Signed-off-by: Kris Van Hees --- dtrace/dtrace_dof.c | 2 +- dtrace/fasttrap_dev.c | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/dtrace/dtrace_dof.c b/dtrace/dtrace_dof.c index 833213eed3e3..58c67a0523e8 100644 --- a/dtrace/dtrace_dof.c +++ b/dtrace/dtrace_dof.c @@ -1651,7 +1651,7 @@ static void dtrace_helper_provide_one(dof_helper_t *dhp, dof_sec_t *sec, if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 && prov->dofpv_prenoffs != DOF_SECT_NONE) { enoff_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff + - prov->dofpv_proffs * + prov->dofpv_prenoffs * dof->dofh_secsize); enoff = (uint32_t *)(uintptr_t)(daddr + enoff_sec->dofs_offset); diff --git a/dtrace/fasttrap_dev.c b/dtrace/fasttrap_dev.c index c399e311393f..2711d9427ab4 100644 --- a/dtrace/fasttrap_dev.c +++ b/dtrace/fasttrap_dev.c @@ -73,24 +73,49 @@ static volatile uint64_t fasttrap_mod_gen; static void fasttrap_pid_cleanup(void); -static void fasttrap_pid_probe(fasttrap_machtp_t *mtp, struct pt_regs *regs) { +static int fasttrap_pid_probe(fasttrap_machtp_t *mtp, struct pt_regs *regs) { fasttrap_tracepoint_t *tp = container_of(mtp, fasttrap_tracepoint_t, ftt_mtp); fasttrap_id_t *id; + int is_enabled = 0; +pr_info("fasttrap_pid_probe(PID %d, PC %lx) regs(ip %lx, ax %lx)\n", tp->ftt_pid, tp->ftt_pc, regs->ip, regs->ax); pr_info("fasttrap_pid_probe(PID %d, PC %lx)\n", tp->ftt_pid, tp->ftt_pc); if (atomic64_read(&tp->ftt_proc->ftpc_acount) == 0) { pr_info(" Ignored (no longer active)\n"); - return; + return 0; } for (id = tp->ftt_ids; id != NULL; id = id->fti_next) { fasttrap_probe_t *ftp = id->fti_probe; + if (id->fti_ptype == DTFTP_IS_ENABLED) { +pr_info(" Probe ID %d for PID %d (is-enabled)\n", ftp->ftp_id, ftp->ftp_pid); + is_enabled = 1; + } else if (ftp->ftp_argmap == NULL) { pr_info(" Probe ID %d for PID %d\n", ftp->ftp_id, ftp->ftp_pid); - dtrace_probe(ftp->ftp_id, regs->di, regs->si, regs->dx, - regs->cx, regs->r8); + dtrace_probe(ftp->ftp_id, regs->di, regs->si, regs->dx, + regs->cx, regs->r8); + } else { + uintptr_t t[5]; + +#ifdef FIXME + fasttrap_usdt_args64(probe, regs, + sizeof(t) / sizeof(t[0]), t); +#endif +pr_info(" Probe ID %d for PID %d (arg-mapped)\n", ftp->ftp_id, ftp->ftp_pid); + dtrace_probe(ftp->ftp_id, t[0], t[1], t[2], t[3], + t[4]); + } } + + if (is_enabled) +{ +pr_info(" Setting EAX to 1 due to is-enabled probe\n"); + regs->ax = 1; +} + + return 0; } static void fasttrap_pid_provide(void *arg, const dtrace_probedesc_t *desc) @@ -183,6 +208,7 @@ static int fasttrap_tracepoint_enable(fasttrap_probe_t *probe, uint_t index) pid = probe->ftp_pid; pc = probe->ftp_tps[index].fit_tp->ftt_pc; id = &probe->ftp_tps[index].fit_id; +pr_info("fasttrap_tracepoint_enable(ID %d, index %d) -> (pid %d, pc %lx)\n", probe->ftp_id, index, pid, pc); ASSERT(probe->ftp_tps[index].fit_tp->ftt_pid == pid); @@ -529,6 +555,7 @@ static int fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) * tracepoint's list of active probes. */ for (i = 0; i < probe->ftp_ntps; i++) { +pr_info("fasttrap_pid_enable() -> Calling fasttrap_tracepoint_enable(ID %d, i %d)\n", probe->ftp_id, i); if ((rc = fasttrap_tracepoint_enable(probe, i)) != 0) { /* * If enabling the tracepoint failed completely, @@ -772,6 +799,7 @@ void fasttrap_meta_create_probe(void *arg, void *parg, tp->ftt_proc = provider->ftp_proc; tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_offs[i]; tp->ftt_pid = provider->ftp_pid; +pr_info("%s: Creating tp %d (pid %d, pc %lx) [regular]\n", __FUNCTION__, i, tp->ftt_pid, tp->ftt_pc); pp->ftp_tps[i].fit_tp = tp; pp->ftp_tps[i].fit_id.fti_probe = pp; @@ -791,6 +819,7 @@ void fasttrap_meta_create_probe(void *arg, void *parg, tp->ftt_proc = provider->ftp_proc; tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_enoffs[j]; tp->ftt_pid = provider->ftp_pid; +pr_info("%s: Creating tp %d (pid %d, pc %lx) [is-enabled]\n", __FUNCTION__, i, tp->ftt_pid, tp->ftt_pc); pp->ftp_tps[i].fit_tp = tp; pp->ftp_tps[i].fit_id.fti_probe = pp; -- 2.50.1