]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Finish the implementation of is-enabled USDT probes.
authorKris Van Hees <kris.van.hees@oracle.com>
Thu, 23 May 2013 14:52:00 +0000 (10:52 -0400)
committerKris Van Hees <kris.van.hees@oracle.com>
Thu, 23 May 2013 14:52:00 +0000 (10:52 -0400)
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 <kris.van.hees@oracle.com>
dtrace/dtrace_dof.c
dtrace/fasttrap_dev.c

index 833213eed3e311314c0c2ff368076ce33b39676e..58c67a0523e85f6980fde8e697c1cdb43534bcae 100644 (file)
@@ -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);
index c399e311393f0cd3c59e55390a0bb3b6384c6ce6..2711d9427ab42c291ea150f9346eeef6a1b95052 100644 (file)
@@ -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;