From 1fa3d04dbe3254fa0abc12da1474c33058074544 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Mon, 13 Jun 2011 14:53:27 -0400 Subject: [PATCH] dtrace: minimal cyclic implementation and debug code. 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 --- kernel/dtrace/Makefile | 7 +- kernel/dtrace/cyclic.c | 23 ------ kernel/dtrace/dtrace_os.c | 151 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 25 deletions(-) delete mode 100644 kernel/dtrace/cyclic.c create mode 100644 kernel/dtrace/dtrace_os.c diff --git a/kernel/dtrace/Makefile b/kernel/dtrace/Makefile index b200a7fb7a66..99feb0606718 100644 --- a/kernel/dtrace/Makefile +++ b/kernel/dtrace/Makefile @@ -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 index 881b30a4e6a3..000000000000 --- a/kernel/dtrace/cyclic.c +++ /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 index 000000000000..fb2de0906800 --- /dev/null +++ b/kernel/dtrace/dtrace_os.c @@ -0,0 +1,151 @@ +/* + * FILE: dtrace_os.c + * DESCRIPTION: Dynamic Tracing: OS support functions - part of kernel core + * + * Copyright (C) 2010 Oracle Corporation + */ + +#include +#include +#include + +#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); -- 2.50.1