]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Cleanup (and adding) of SDT probe points.
authorKris Van Hees <kris.van.hees@oracle.com>
Sun, 9 Sep 2012 20:56:15 +0000 (16:56 -0400)
committerKris Van Hees <kris.van.hees@oracle.com>
Sun, 9 Sep 2012 20:56:15 +0000 (16:56 -0400)
Changed io SDT probe points to be located at the buffer_head level rather than
the bio level.  This may need to be revisted depending on further analysis,
but doing it this way provides consistent semantics that were not guaranteed by
the previous bio-based placement.

Changed the sched STD probes to not pass irrelevant arguments, and to pass
specific runqueue CPU information.  The CPU information is not available from
the task structure, so it needs to be passed explicily.

Added proc SDT probes start and lwp-start.

Added proc SDT probes for signal-discard and signal-clear.

Corrected the argument to the exit proc SDT probe, which should indicate the
reason for the process termination (exit, killed, core dumped) rather than the
return code of the process.

Provided argument information for all the new (and changed) SDT probe points.
This depends on working xlator support in userspace.

Enabling of SDT probes now uses a generic dtrace_invop_(enable|disable) rather
than SDT-specific functions.

SDT probes are not destroyed correctly, to ensure that subsequent uses will not
result in unpleasant events.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
dtrace/sdt_dev.c
dtrace/sdt_mod.c

index 847a4dc60e13769f57350f3dbd492593b231bee2..a876626ceb45feda3fad27d1a7e7491e532b2bea 100644 (file)
@@ -43,24 +43,67 @@ static int          sdt_probetab_size;
 static int             sdt_probetab_mask;
 
 static sdt_argdesc_t   sdt_args[] = {
-       { "proc", "create", 0, 0, "struct task_struct *", },
+       /*
+        * { name, provider, ndx, mapping, native, xlate }
+        */
+       { "io", "done", 0, 0, "struct buffer_head *", "bufinfo_t *" },
+       { "io", "done", 1, 0, "struct buffer_head *", "devinfo_t *" },
+       { "io", "done", 2, 0, "struct buffer_head *", "fileinfo_t *" },
+       { "io", "start", 0, 0, "struct buffer_head *", "bufinfo_t *" },
+       { "io", "start", 1, 0, "struct buffer_head *", "devinfo_t *" },
+       { "io", "start", 2, 0, "struct buffer_head *", "fileinfo_t *" },
+       { "io", "wait-done", 0, 0, "struct buffer_head *", "bufinfo_t *" },
+       { "io", "wait-done", 1, 0, "struct buffer_head *", "devinfo_t *" },
+       { "io", "wait-done", 2, 0, "struct buffer_head *", "fileinfo_t *" },
+       { "io", "wait-start", 0, 0, "struct buffer_head *", "bufinfo_t *" },
+       { "io", "wait-start", 1, 0, "struct buffer_head *", "devinfo_t *" },
+       { "io", "wait-start", 2, 0, "struct buffer_head *", "fileinfo_t *" },
+
+       { "proc", "create", 0, 0, "struct task_struct *", "psinfo_t *" },
        { "proc", "exec", 0, 0, "char *", },
        { "proc", "exec-failure", 0, 0, "int", },
        { "proc", "exit", 0, 0, "int", },
-       { "proc", "lwp_create", 0, 0, "struct task_struct *", },
+#if 0
+       { "proc", "fault", 0, 0, "int", },
+       { "proc", "fault", 1, 1, "siginfo_t", },
+#endif
+       { "proc", "lwp_create", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "proc", "lwp_create", 1, 0, "struct task_struct *", "psinfo_t *" },
        { "proc", "lwp_exit", 0, 0, "int", },
+       { "proc", "signal-clear", 0, 0, "int", },
+       { "proc", "signal-discard", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "proc", "signal-discard", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "proc", "signal-discard", 2, 1, "int", },
        { "proc", "signal-handle", 0, 0, "int" },
-       { "proc", "signal-handle", 1, 0 /* 1 */, "siginfo_t *" },
-       { "proc", "signal-handle", 2, 0 /* 2 */, "void (*)(void)" },
-       { "proc", "signal-send", 0, 0, "struct task_struct *", },
-       { "proc", "signal-send", 1, 0, "int", },
-
-       { "sched", "tick", 0, 0, "struct task_struct *", },
+       { "proc", "signal-handle", 1, 1, "siginfo_t *" },
+       { "proc", "signal-handle", 2, 2, "void (*)(void)" },
+       { "proc", "signal-send", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "proc", "signal-send", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "proc", "signal-send", 2, 1, "int", },
+
+       { "sched", "change-pri", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "sched", "change-pri", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "sched", "change-pri", 2, 1, "int", },
+       { "sched", "dequeue", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "sched", "dequeue", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "sched", "dequeue", 2, 1, "cpuinfo_t *", },
+       { "sched", "dequeue", 3, 2, "int", },
+       { "sched", "enqueue", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "sched", "enqueue", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "sched", "enqueue", 2, 1, "cpuinfo_t *", },
+       { "sched", "off-cpu", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "sched", "off-cpu", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "sched", "surrender", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "sched", "surrender", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "sched", "tick", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "sched", "tick", 1, 0, "struct task_struct *", "psinfo_t *" },
+       { "sched", "wakeup", 0, 0, "struct task_struct *", "lwpsinfo_t *" },
+       { "sched", "wakeup", 1, 0, "struct task_struct *", "psinfo_t *" },
 
        { NULL, }
 };
 
-static int sdt_invop(struct pt_regs *regs)
+static uint8_t sdt_invop(struct pt_regs *regs)
 {
        sdt_probe_t     *sdt = sdt_probetab[SDT_ADDR2NDX(regs->ip)];
 
@@ -164,7 +207,7 @@ int _sdt_enable(void *arg, dtrace_id_t id, void *parg)
 {
        sdt_probe_t     *sdp = parg;
 
-       sdt_probe_enable(sdp->sdp_patchpoint);
+       dtrace_invop_enable(sdp->sdp_patchpoint);
        return 0;
 }
 
@@ -172,7 +215,7 @@ void _sdt_disable(void *arg, dtrace_id_t id, void *parg)
 {
        sdt_probe_t     *sdp = parg;
 
-       sdt_probe_disable(sdp->sdp_patchpoint);
+       dtrace_invop_disable(sdp->sdp_patchpoint, sdp->sdp_savedval);
 }
 
 void sdt_getargdesc(void *arg, dtrace_id_t id, void *parg,
@@ -219,6 +262,33 @@ uint64_t sdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
 
 void sdt_destroy(void *arg, dtrace_id_t id, void *parg)
 {
+       sdt_probe_t     *sdp = parg;
+
+       sdp->sdp_module->sdt_nprobes--;
+
+       while (sdp != NULL) {
+               sdt_probe_t     *old = sdp, *last, *hash;
+               int             ndx;
+
+               ndx = SDT_ADDR2NDX(sdp->sdp_patchpoint);
+               last = NULL;
+               hash = sdt_probetab[ndx];
+
+               while (hash != sdp) {
+                       ASSERT(hash != NULL);
+                       last = hash;
+                       hash = hash->sdp_hashnext;
+               }
+
+               if (last != NULL)
+                       last->sdp_hashnext = sdp->sdp_hashnext;
+               else
+                       sdt_probetab[ndx] = sdp->sdp_hashnext;
+
+               kfree(sdp->sdp_name);
+               sdp = sdp->sdp_next;
+               kfree(old);
+       }
 }
 
 static long sdt_ioctl(struct file *file,
@@ -260,8 +330,6 @@ int sdt_dev_init(void)
                pr_err("%s: Can't register misc device %d\n",
                       sdt_dev.name, sdt_dev.minor);
 
-       dtrace_register_builtins();     /* FIXME */
-
        if (sdt_probetab_size == 0)
                sdt_probetab_size = SDT_PROBETAB_SIZE;
 
index 55f7c862097e67cd970805a128588c2654f64ecf..d9b93f539d08e0f3d5df8fa8a57f8db053750f5a 100644 (file)
@@ -119,7 +119,7 @@ static dtrace_pops_t sdt_pops = {
        NULL,
        NULL,
        sdt_getargdesc,
-       sdt_getarg,
+       NULL /* sdt_getarg */,
        NULL,
        sdt_destroy,
 };