]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
- sched-tick SDT probe.
authorKris Van Hees <kris.van.hees@oracle.com>
Thu, 19 Apr 2012 21:19:40 +0000 (17:19 -0400)
committerKris Van Hees <kris.van.hees@oracle.com>
Thu, 19 Apr 2012 21:19:40 +0000 (17:19 -0400)
- FBT probe point discovery and probe creation.
- Moving code around for the kernel pseudo-module handling since it gets used
  by both the SDT code and the FBT code.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
dtrace/dtrace_dev.c
dtrace/dtrace_util.c
dtrace/fbt.h [deleted file]
dtrace/fbt_dev.c
dtrace/fbt_mod.c
dtrace/sdt_dev.c
dtrace/sdt_impl.h

index c3e76af41f0e78ee6a7026efb1946592c5175100..3f68182db370ce2c1320ed06ad82a0cf07d11a92 100644 (file)
@@ -1213,6 +1213,8 @@ int dtrace_dev_init(void)
                return rc;
        }
 
+       dtrace_os_init();
+
        dtrace_modload = dtrace_module_loaded;
        dtrace_modunload = dtrace_module_unloaded;
 #ifdef FIXME
@@ -1328,4 +1330,6 @@ void dtrace_dev_exit(void)
        misc_deregister(&dtrace_dev);
 
        dtrace_probe_exit();
+
+       dtrace_os_exit();
 }
index beb222d44d88e42fcd07af9e623b8ccaadeb62e8..79bd70cc6e5dd8d74e976113cf7b3dca8ce59797 100644 (file)
@@ -51,6 +51,7 @@ void *dtrace_vzalloc_try(unsigned long size)
                         __GFP_NORETRY | __GFP_NOWARN | __GFP_ZERO,
                         PAGE_KERNEL);
 }
+EXPORT_SYMBOL(dtrace_vzalloc_try);
 
 /*
  * Return a duplicate copy of a string.  If the specified string is NULL, this
diff --git a/dtrace/fbt.h b/dtrace/fbt.h
deleted file mode 100644 (file)
index 6b61349..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _FBT_H_
-#define _FBT_H_
-
-extern int fbt_dev_init(void);
-extern void fbt_dev_exit(void);
-
-#endif /* _FBT_H_ */
index f46dc89369f8747873969bbe4d79a67da3dc158b..2b367db078f5f9cbaf39660be96d71b85eaeb2a5 100644 (file)
 
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
+#include <linux/kallsyms.h>
+#include <linux/slab.h>
+#include <asm/insn.h>
 
+#include "dtrace.h"
 #include "dtrace_dev.h"
+#include "fbt_impl.h"
+
+#define FBT_PATCHVAL   0xf0
+#define FBT_ADDR2NDX(addr)     ((((uintptr_t)(addr)) >> 4) & fbt_probetab_mask)
+#define FBT_PROBETAB_SIZE      0x8000          /* 32k entries -- 128K total */
+
+static fbt_probe_t             **fbt_probetab;
+static int                     fbt_probetab_size;
+static int                     fbt_probetab_mask;
+
+static unsigned long   fbt_cnt_entry = 0;
+static unsigned long   fbt_cnt_return = 0;
+
+static void *fbt_provide_probe(struct module *mp, char *func,
+                                     uint8_t opc, uint8_t *addr,
+                                     void *pfbt)
+{
+       fbt_probe_t     *fbt;
+       fbt_probe_t     *prev;
+
+       switch (opc) {
+       case FBT_PUSHL_EBP:
+               fbt = kzalloc(sizeof(fbt_probe_t), GFP_KERNEL);
+               fbt->fbp_name = func;
+               fbt->fbp_id = dtrace_probe_create(fbt_id, mp->name, func,
+                                                 "entry", 3, fbt);
+               fbt->fbp_module = mp;
+               fbt->fbp_loadcnt = 1; /* FIXME */
+               fbt->fbp_primary = 1; /* FIXME */
+               fbt->fbp_patchpoint = addr;
+               fbt->fbp_patchval = FBT_PATCHVAL;
+               fbt->fbp_savedval = *addr;
+               fbt->fbp_rval = opc;
+                fbt->fbp_hashnext = fbt_probetab[FBT_ADDR2NDX(addr)];
+
+               fbt_probetab[FBT_ADDR2NDX(addr)] = fbt;
+
+                mp->fbt_nprobes++;
+
+               fbt_cnt_entry++;
+
+               return fbt;
+       case FBT_RET:
+       case FBT_RET_IMM16:
+               fbt = kzalloc(sizeof(fbt_probe_t), GFP_KERNEL);
+               fbt->fbp_name = func;
+
+               prev = (fbt_probe_t *)pfbt;
+               if (prev != NULL) {
+                       prev->fbp_next = fbt;
+                       fbt->fbp_id = prev->fbp_id;
+               } else {
+                       fbt->fbp_id = dtrace_probe_create(fbt_id, mp->name,
+                                                         func, "return", 3,
+                                                         fbt);
+               }
+
+               fbt->fbp_module = mp;
+               fbt->fbp_loadcnt = 1; /* FIXME */
+               fbt->fbp_primary = 1; /* FIXME */
+               fbt->fbp_patchpoint = addr;
+               fbt->fbp_patchval = FBT_PATCHVAL;
+               fbt->fbp_savedval = *addr;
+               fbt->fbp_rval = opc;
+                fbt->fbp_hashnext = fbt_probetab[FBT_ADDR2NDX(addr)];
+
+               fbt_probetab[FBT_ADDR2NDX(addr)] = fbt;
+
+               mp->fbt_nprobes++;
+
+               fbt_cnt_return++;
+
+               return fbt;
+       default:
+               printk(KERN_INFO "FBT: Invalid opcode for %s\n", func);
+
+               return NULL;
+       }
+}
+
+void fbt_provide_module(void *arg, struct module *mp)
+{
+       printk(KERN_INFO "FBT: provide_module(%s)...\n", mp->name);
+
+       /*
+        * Nothing to do if the module FBT probes were already created.
+        */
+       if (mp->fbt_nprobes != 0)
+               return;
+
+#if 1
+{
+ktime_t tm0;
+ktime_t tm1;
+
+tm0 = dtrace_gethrtime();
+       dtrace_fbt_init(fbt_provide_probe);
+tm1 = dtrace_gethrtime();
+printk(KERN_INFO "FBT: dtrace_fbt_init() took %lld nsec\n", (signed long long)tm1.tv64 - tm0.tv64);
+}
+
+       printk(KERN_INFO "FBT: Number of entry probes:  %lu\n", fbt_cnt_entry);
+       printk(KERN_INFO "FBT: Number of return probes: %lu\n", fbt_cnt_return);
+#else
+       analyze_symbols();
+#endif
+}
+
+int _fbt_enable(void *arg, dtrace_id_t id, void *parg)
+{
+       return 1;
+}
+
+void _fbt_disable(void *arg, dtrace_id_t id, void *parg)
+{
+}
+
+void fbt_destroy(void *arg, dtrace_id_t id, void *parg)
+{ 
+       fbt_probe_t     *fbt = parg;
+       fbt_probe_t     *nxt, *hbp, *lst;
+       struct module   *mp = fbt->fbp_module;
+       int             ndx;
+
+       do {
+               if (mp != NULL)
+                       mp->fbt_nprobes--;
+
+               ndx = FBT_ADDR2NDX(fbt->fbp_patchpoint);
+               lst = NULL;
+               hbp = fbt_probetab[ndx];
+
+               while (hbp != fbt) {
+                       ASSERT(hbp != NULL);
+
+                       lst = hbp;
+                       hbp = hbp->fbp_hashnext;
+               }
+
+               if (lst != NULL)
+                       lst->fbp_hashnext = fbt->fbp_hashnext;
+               else
+                       fbt_probetab[ndx] = fbt->fbp_hashnext;
+
+               nxt = fbt->fbp_next;
+
+               kfree(fbt);
+
+               fbt = nxt;
+       } while (fbt != NULL);
+}
 
 static long fbt_ioctl(struct file *file,
                         unsigned int cmd, unsigned long arg)
@@ -64,6 +219,13 @@ int fbt_dev_init(void)
 {
        int ret = 0;
 
+       if (fbt_probetab_size == 0)
+               fbt_probetab_size = FBT_PROBETAB_SIZE;
+
+       fbt_probetab_mask = fbt_probetab_size - 1;
+       fbt_probetab = dtrace_vzalloc_try(fbt_probetab_size *
+                                         sizeof (fbt_probe_t *));
+
        ret = misc_register(&fbt_dev);
        if (ret)
                pr_err("%s: Can't register misc device %d\n",
@@ -75,4 +237,8 @@ int fbt_dev_init(void)
 void fbt_dev_exit(void)
 {
        misc_deregister(&fbt_dev);
+
+       vfree(fbt_probetab);
+       fbt_probetab_mask = 0;
+       fbt_probetab_size = 0;
 }
index c1accf70221f7c9a9873183acf9359d254bae8a0..d1fdb08c409c085e2de7a085a7271f9a27aef406 100644 (file)
 
 #include "dtrace.h"
 #include "dtrace_dev.h"
-#include "fbt.h"
+#include "fbt_impl.h"
 
 MODULE_AUTHOR("Kris Van Hees (kris.van.hees@oracle.com)");
 MODULE_DESCRIPTION("Function Boundary Tracing");
 MODULE_VERSION("v0.1");
+#if 0
 MODULE_LICENSE("CDDL");
+#else
+MODULE_LICENSE("GPL"); /* FIXME - Cheating */
+#endif
 
 static const dtrace_pattr_t fbt_attr = {
+{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
+{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
+{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
 };
 
+DT_PROVIDER_POPS(fbt)
+
 static dtrace_pops_t fbt_pops = {
+       NULL,
+       fbt_provide_module,
+       fbt_enable,
+       fbt_disable,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       fbt_destroy
 };
 
-DT_PROVIDER_MODULE(fbt, DTRACE_PRIV_KERNEL);
+DT_PROVIDER_MODULE(fbt, DTRACE_PRIV_KERNEL)
index 07e08bf78a828e5aac2f811e6e2ee58a161d8400..847a4dc60e13769f57350f3dbd492593b231bee2 100644 (file)
@@ -54,6 +54,9 @@ static sdt_argdesc_t  sdt_args[] = {
        { "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 *", },
+
        { NULL, }
 };
 
index c6a066d56e1a1ec0c1c540531fc43d2aed45c90f..e26f795de507771eb26c1ed4f1b72f76f091f2b1 100644 (file)
@@ -20,6 +20,15 @@ typedef struct sdt_probe {
        struct sdt_probe        *sdp_hashnext;  /* next on hash */
 } sdt_probe_t;
 
+typedef struct sdt_argdesc  {
+       char                    *sda_provider;
+       char                    *sda_name;
+       int                     sda_ndx;
+       int                     sda_mapping;
+       char                    *sda_native;
+       char                    *sda_xlate;
+} sdt_argdesc_t;
+
 extern dtrace_mprovider_t sdt_providers[];
 
 extern void sdt_provide_module(void *, struct module *);