]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: minimal cyclic implementation and debug code.
authorKris Van Hees <kris.van.hees@oracle.com>
Mon, 13 Jun 2011 18:53:27 +0000 (14:53 -0400)
committerNick Alcock <nick.alcock@oracle.com>
Mon, 29 Jun 2015 21:39:51 +0000 (22:39 +0100)
Adding debug code to track probe processing through BEGIN probe enabling.
Adding minimal implementation of cyclic functionality (based on hrtimer) as an
additional to the core kernel, linked in when dtrace is enabled (be it as
module, or compiled in).  Exports cyclic_add() and cyclic_remove().
Removed former cyclic stub implementation (cyclic.c).

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
kernel/dtrace/Makefile
kernel/dtrace/cyclic.c [deleted file]
kernel/dtrace/dtrace_os.c [new file with mode: 0644]

index b200a7fb7a66cf20762671f1187c2f69581bc3a6..99feb0606718feb7ec794fa25d05f25ab59e9abb 100644 (file)
@@ -10,6 +10,10 @@ obj-$(CONFIG_DT_PROFILE)     += profile.o
 obj-$(CONFIG_DT_SDT)           += sdt.o sdt_register.o
 obj-$(CONFIG_DT_SYSTRACE)      += systrace.o
 
+ifdef CONFIG_DT_CORE
+obj-y                          += dtrace_os.o
+endif
+
 dtrace-y                       := dtrace_mod.o dtrace_dev.o \
                                   dtrace_asm.o dtrace_isa.o \
                                   dtrace_actdesc.o dtrace_anon.o \
@@ -19,8 +23,7 @@ dtrace-y                      := dtrace_mod.o dtrace_dev.o \
                                   dtrace_match.o dtrace_priv.o \
                                   dtrace_probe.o dtrace_probe_ctx.o \
                                   dtrace_ptofapi.o dtrace_predicate.o \
-                                  dtrace_spec.o dtrace_state.o dtrace_util.o \
-                                  cyclic.o
+                                  dtrace_spec.o dtrace_state.o dtrace_util.o
 fasttrap-y                     := fasttrap_mod.o fasttrap_dev.o
 fbt-y                          := fbt_mod.o fbt_dev.o
 lockstat-y                     := lockstat_mod.o lockstat_dev.o
diff --git a/kernel/dtrace/cyclic.c b/kernel/dtrace/cyclic.c
deleted file mode 100644 (file)
index 881b30a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * FILE:       cyclic.c
- * DESCRIPTION:        Cyclic implementation
- *
- * Copyright (C) 2010 Oracle Corporation
- */
-
-#include "cyclic.h"
-
-/*
- * Add a new cyclic to the system.
- */
-cyclic_id_t cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
-{
-       return 0;
-}
-
-/*
- * Remove the specific cyclic from the system.
- */
-void cyclic_remove(cyclic_id_t id)
-{
-}
diff --git a/kernel/dtrace/dtrace_os.c b/kernel/dtrace/dtrace_os.c
new file mode 100644 (file)
index 0000000..fb2de09
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * FILE:       dtrace_os.c
+ * DESCRIPTION:        Dynamic Tracing: OS support functions - part of kernel core
+ *
+ * Copyright (C) 2010 Oracle Corporation
+ */
+
+#include <linux/hrtimer.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+
+#include "cyclic.h"
+
+/*
+ * Very basic implementation of cyclics, merely enough to support dtrace.
+ */
+typedef union cyclic   cyclic_t;
+union cyclic {
+       struct {
+               cyc_time_t      when;
+               cyc_handler_t   hdlr;
+               struct hrtimer  timr;
+       } cyc;
+       cyclic_t                *nxt;
+};
+
+static cyclic_t                *cyc_arr = NULL;
+static cyclic_t                *cyc_flst = NULL;
+static unsigned long   cyc_size = 0;
+
+#define CHUNKSIZE      12
+
+DEFINE_MUTEX(cyclic_lock);
+
+/*
+ * Find a free cyclic slot.  Returns NULL in out-of-memory conditions.
+ */
+static cyclic_t *cyc_alloc(void)
+{
+       cyclic_t        *np;
+
+       mutex_lock(&cyclic_lock);
+
+printk(KERN_INFO "cyc_alloc: flst [O] %p\n", cyc_flst);
+       if (cyc_flst == NULL) {
+               unsigned long   nsize = cyc_size + CHUNKSIZE;
+               unsigned long   idx = nsize;
+               cyclic_t        *narr;
+
+               if (!(narr = (cyclic_t *)vmalloc(nsize * sizeof(cyclic_t)))) {
+                       mutex_unlock(&cyclic_lock);
+                       return NULL;
+               }
+
+               memcpy(narr, cyc_arr, cyc_size * sizeof(cyclic_t));
+               vfree(cyc_arr);
+               cyc_arr = narr;
+
+               idx = nsize;
+               cyc_flst = &cyc_arr[cyc_size];
+printk(KERN_INFO "cyc_alloc: flst [N] %p, size [N] %lu\n", cyc_flst, nsize);
+               cyc_arr[--idx].nxt = NULL;
+printk(KERN_INFO "cyc_alloc: cyc_arr[%lu] NULL\n", idx);
+               while (idx-- > cyc_size)
+{
+                       cyc_arr[idx].nxt = &cyc_arr[idx + 1];
+printk(KERN_INFO "cyc_alloc: cyc_arr[%lu] %p\n", idx, cyc_arr[idx].nxt);
+}
+
+               cyc_size = nsize;
+       }
+
+       np = cyc_flst;
+       cyc_flst = cyc_flst->nxt;
+printk(KERN_INFO "cyc_alloc: cyc %p, flst [N] %p\n", np, cyc_flst);
+
+       mutex_unlock(&cyclic_lock);
+
+       np->cyc.hdlr.cyh_func = NULL;
+       return np;
+}
+
+static enum hrtimer_restart cyclic_fire_fn(struct hrtimer *timr)
+{
+       cyclic_t        *cyc = container_of(timr, cyclic_t, cyc.timr);
+
+       if (cyc->cyc.hdlr.cyh_func)
+               cyc->cyc.hdlr.cyh_func(cyc->cyc.hdlr.cyh_arg);
+
+       hrtimer_forward_now(&cyc->cyc.timr, cyc->cyc.when.cyt_interval);
+printk(KERN_INFO "cyclic_fire_fn: Cyclic %p, hrtimer %p\n", cyc, timr);
+printk(KERN_INFO "cyclic_fire_fn:   Next expiry in %lld ns (interval %lld)\n", hrtimer_expires_remaining(&cyc->cyc.timr).tv64, cyc->cyc.when.cyt_interval.tv64);
+
+       return HRTIMER_RESTART;
+}
+
+/*
+ * Add a new cyclic to the system.
+ */
+cyclic_id_t cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
+{
+       cyclic_t        *cyc;
+
+       if (hdlr == NULL || when == NULL)
+               return CYCLIC_NONE;
+
+       if ((cyc = cyc_alloc()) == NULL)
+               return CYCLIC_NONE;
+
+       cyc->cyc.when = *when;
+       cyc->cyc.hdlr = *hdlr;
+
+       hrtimer_init(&cyc->cyc.timr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       cyc->cyc.timr.function = cyclic_fire_fn;
+printk(KERN_INFO "cyclic_add: Adding %p, hrtimer %p\n", cyc, &cyc->cyc.timr);
+
+       if (cyc->cyc.when.cyt_when.tv64 == 0)
+{
+printk(KERN_INFO "cyclic_add:   Starting at relative %lld\n", cyc->cyc.when.cyt_interval.tv64);
+               hrtimer_start(&cyc->cyc.timr, cyc->cyc.when.cyt_interval,
+                             HRTIMER_MODE_REL_PINNED);
+}
+       else
+{
+printk(KERN_INFO "cyclic_add:   Starting at absolute %lld\n", cyc->cyc.when.cyt_when.tv64);
+               hrtimer_start(&cyc->cyc.timr, cyc->cyc.when.cyt_when,
+                             HRTIMER_MODE_ABS_PINNED);
+}
+
+       return (cyclic_id_t)cyc;
+}
+EXPORT_SYMBOL(cyclic_add);
+
+/*
+ * Remove a specific cyclic from the system.
+ */
+void cyclic_remove(cyclic_id_t id)
+{
+       cyclic_t        *cyc = (cyclic_t *)id;
+
+printk(KERN_INFO "cyclic_add: Removing %p, hrtimer %p\n", cyc, &cyc->cyc.timr);
+       hrtimer_cancel(&cyc->cyc.timr);
+
+       mutex_lock(&cyclic_lock);
+
+       cyc->nxt = cyc_flst;
+       cyc_flst = cyc;
+
+       mutex_unlock(&cyclic_lock);
+}
+EXPORT_SYMBOL(cyclic_remove);