From: Mathieu Desnoyers Date: Sun, 22 Jan 2012 21:13:41 +0000 (-0500) Subject: Mass rename: ltt_*/ltt-* to LTTNG_*/LTTNG-* X-Git-Tag: v2.0-pre12~15 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=a90917c3f8c4ed79117f1caa333b29a2108084ec;p=lttng-modules.git Mass rename: ltt_*/ltt-* to LTTNG_*/LTTNG-* For files, defines and symbols. Signed-off-by: Mathieu Desnoyers --- diff --git a/Makefile b/Makefile index 0d16bcbb..ad2ff5a7 100644 --- a/Makefile +++ b/Makefile @@ -5,16 +5,16 @@ ifneq ($(KERNELRELEASE),) ifneq ($(CONFIG_TRACEPOINTS),) -obj-m += ltt-ring-buffer-client-discard.o -obj-m += ltt-ring-buffer-client-overwrite.o -obj-m += ltt-ring-buffer-metadata-client.o -obj-m += ltt-ring-buffer-client-mmap-discard.o -obj-m += ltt-ring-buffer-client-mmap-overwrite.o -obj-m += ltt-ring-buffer-metadata-mmap-client.o - -obj-m += ltt-relay.o -ltt-relay-objs := ltt-events.o lttng-abi.o \ - ltt-probes.o ltt-context.o \ +obj-m += lttng-ring-buffer-client-discard.o +obj-m += lttng-ring-buffer-client-overwrite.o +obj-m += lttng-ring-buffer-metadata-client.o +obj-m += lttng-ring-buffer-client-mmap-discard.o +obj-m += lttng-ring-buffer-client-mmap-overwrite.o +obj-m += lttng-ring-buffer-metadata-mmap-client.o + +obj-m += lttng-tracer.o +lttng-tracer-objs := lttng-events.o lttng-abi.o \ + lttng-probes.o lttng-context.o \ lttng-context-pid.o lttng-context-procname.o \ lttng-context-prio.o lttng-context-nice.o \ lttng-context-vpid.o lttng-context-tid.o \ @@ -22,11 +22,11 @@ ltt-relay-objs := ltt-events.o lttng-abi.o \ lttng-context-vppid.o lttng-calibrate.o ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),) -ltt-relay-objs += lttng-syscalls.o +lttng-tracer-objs += lttng-syscalls.o endif ifneq ($(CONFIG_PERF_EVENTS),) -ltt-relay-objs += $(shell \ +lttng-tracer-objs += $(shell \ if [ $(VERSION) -ge 3 \ -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 33 \) ] ; then \ echo "lttng-context-perf-counters.o" ; fi;) diff --git a/TODO b/TODO index 44200741..090b923e 100644 --- a/TODO +++ b/TODO @@ -93,7 +93,7 @@ B) Features allow integration between NOHZ and LTTng would be to add support for such notifiers into NOHZ kernel infrastructure. - 10) Turn drivers/staging/lttng/ltt-probes.c probe_list into a + 10) Turn lttng-probes.c probe_list into a hash table. Turns O(n^2) trace systems registration (cost for n systems) into O(n). (O(1) per system) diff --git a/lib/bitfield.h b/lib/bitfield.h index 861e6dcd..8c2b1a20 100644 --- a/lib/bitfield.h +++ b/lib/bitfield.h @@ -19,7 +19,7 @@ * all copies or substantial portions of the Software. */ -#include "../ltt-endian.h" +#include "../lttng-endian.h" #ifndef CHAR_BIT #define CHAR_BIT 8 diff --git a/ltt-context.c b/ltt-context.c deleted file mode 100644 index 60ea525b..00000000 --- a/ltt-context.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * ltt-context.c - * - * Copyright 2011 (c) - Mathieu Desnoyers - * - * LTTng trace/channel/event context management. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include -#include -#include -#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ -#include "ltt-events.h" -#include "ltt-tracer.h" - -int lttng_find_context(struct lttng_ctx *ctx, const char *name) -{ - unsigned int i; - - for (i = 0; i < ctx->nr_fields; i++) { - /* Skip allocated (but non-initialized) contexts */ - if (!ctx->fields[i].event_field.name) - continue; - if (!strcmp(ctx->fields[i].event_field.name, name)) - return 1; - } - return 0; -} -EXPORT_SYMBOL_GPL(lttng_find_context); - -/* - * Note: as we append context information, the pointer location may change. - */ -struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx_p) -{ - struct lttng_ctx_field *field; - struct lttng_ctx *ctx; - - if (!*ctx_p) { - *ctx_p = kzalloc(sizeof(struct lttng_ctx), GFP_KERNEL); - if (!*ctx_p) - return NULL; - } - ctx = *ctx_p; - if (ctx->nr_fields + 1 > ctx->allocated_fields) { - struct lttng_ctx_field *new_fields; - - ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields); - new_fields = kzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL); - if (!new_fields) - return NULL; - if (ctx->fields) - memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields); - kfree(ctx->fields); - ctx->fields = new_fields; - } - field = &ctx->fields[ctx->nr_fields]; - ctx->nr_fields++; - return field; -} -EXPORT_SYMBOL_GPL(lttng_append_context); - -/* - * Remove last context field. - */ -void lttng_remove_context_field(struct lttng_ctx **ctx_p, - struct lttng_ctx_field *field) -{ - struct lttng_ctx *ctx; - - ctx = *ctx_p; - ctx->nr_fields--; - WARN_ON_ONCE(&ctx->fields[ctx->nr_fields] != field); - memset(&ctx->fields[ctx->nr_fields], 0, sizeof(struct lttng_ctx_field)); -} -EXPORT_SYMBOL_GPL(lttng_remove_context_field); - -void lttng_destroy_context(struct lttng_ctx *ctx) -{ - int i; - - if (!ctx) - return; - for (i = 0; i < ctx->nr_fields; i++) { - if (ctx->fields[i].destroy) - ctx->fields[i].destroy(&ctx->fields[i]); - } - kfree(ctx->fields); - kfree(ctx); -} diff --git a/ltt-endian.h b/ltt-endian.h deleted file mode 100644 index 9a0512d2..00000000 --- a/ltt-endian.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _LTT_ENDIAN_H -#define _LTT_ENDIAN_H - -/* - * ltt-endian.h - * - * Copyright 2010 (c) - Mathieu Desnoyers - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#ifdef __KERNEL__ -# include -# ifdef __BIG_ENDIAN -# define __BYTE_ORDER __BIG_ENDIAN -# elif defined(__LITTLE_ENDIAN) -# define __BYTE_ORDER __LITTLE_ENDIAN -# else -# error "unknown endianness" -# endif -#ifndef __BIG_ENDIAN -# define __BIG_ENDIAN 4321 -#endif -#ifndef __LITTLE_ENDIAN -# define __LITTLE_ENDIAN 1234 -#endif -#else -# include -#endif - -#endif /* _LTT_ENDIAN_H */ diff --git a/ltt-events.c b/ltt-events.c deleted file mode 100644 index 03dbb203..00000000 --- a/ltt-events.c +++ /dev/null @@ -1,1009 +0,0 @@ -/* - * ltt-events.c - * - * Copyright 2010 (c) - Mathieu Desnoyers - * - * Holds LTTng per-session event registry. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include -#include -#include -#include -#include -#include "wrapper/uuid.h" -#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ -#include "ltt-events.h" -#include "ltt-tracer.h" - -static LIST_HEAD(sessions); -static LIST_HEAD(ltt_transport_list); -static DEFINE_MUTEX(sessions_mutex); -static struct kmem_cache *event_cache; - -static void _ltt_event_destroy(struct ltt_event *event); -static void _ltt_channel_destroy(struct ltt_channel *chan); -static int _ltt_event_unregister(struct ltt_event *event); -static -int _ltt_event_metadata_statedump(struct ltt_session *session, - struct ltt_channel *chan, - struct ltt_event *event); -static -int _ltt_session_metadata_statedump(struct ltt_session *session); - -void synchronize_trace(void) -{ - synchronize_sched(); -#ifdef CONFIG_PREEMPT_RT - synchronize_rcu(); -#endif -} - -struct ltt_session *ltt_session_create(void) -{ - struct ltt_session *session; - - mutex_lock(&sessions_mutex); - session = kzalloc(sizeof(struct ltt_session), GFP_KERNEL); - if (!session) - return NULL; - INIT_LIST_HEAD(&session->chan); - INIT_LIST_HEAD(&session->events); - uuid_le_gen(&session->uuid); - list_add(&session->list, &sessions); - mutex_unlock(&sessions_mutex); - return session; -} - -void ltt_session_destroy(struct ltt_session *session) -{ - struct ltt_channel *chan, *tmpchan; - struct ltt_event *event, *tmpevent; - int ret; - - mutex_lock(&sessions_mutex); - ACCESS_ONCE(session->active) = 0; - list_for_each_entry(chan, &session->chan, list) { - ret = lttng_syscalls_unregister(chan); - WARN_ON(ret); - } - list_for_each_entry(event, &session->events, list) { - ret = _ltt_event_unregister(event); - WARN_ON(ret); - } - synchronize_trace(); /* Wait for in-flight events to complete */ - list_for_each_entry_safe(event, tmpevent, &session->events, list) - _ltt_event_destroy(event); - list_for_each_entry_safe(chan, tmpchan, &session->chan, list) - _ltt_channel_destroy(chan); - list_del(&session->list); - mutex_unlock(&sessions_mutex); - kfree(session); -} - -int ltt_session_enable(struct ltt_session *session) -{ - int ret = 0; - struct ltt_channel *chan; - - mutex_lock(&sessions_mutex); - if (session->active) { - ret = -EBUSY; - goto end; - } - - /* - * Snapshot the number of events per channel to know the type of header - * we need to use. - */ - list_for_each_entry(chan, &session->chan, list) { - if (chan->header_type) - continue; /* don't change it if session stop/restart */ - if (chan->free_event_id < 31) - chan->header_type = 1; /* compact */ - else - chan->header_type = 2; /* large */ - } - - ACCESS_ONCE(session->active) = 1; - ACCESS_ONCE(session->been_active) = 1; - ret = _ltt_session_metadata_statedump(session); - if (ret) - ACCESS_ONCE(session->active) = 0; -end: - mutex_unlock(&sessions_mutex); - return ret; -} - -int ltt_session_disable(struct ltt_session *session) -{ - int ret = 0; - - mutex_lock(&sessions_mutex); - if (!session->active) { - ret = -EBUSY; - goto end; - } - ACCESS_ONCE(session->active) = 0; -end: - mutex_unlock(&sessions_mutex); - return ret; -} - -int ltt_channel_enable(struct ltt_channel *channel) -{ - int old; - - if (channel == channel->session->metadata) - return -EPERM; - old = xchg(&channel->enabled, 1); - if (old) - return -EEXIST; - return 0; -} - -int ltt_channel_disable(struct ltt_channel *channel) -{ - int old; - - if (channel == channel->session->metadata) - return -EPERM; - old = xchg(&channel->enabled, 0); - if (!old) - return -EEXIST; - return 0; -} - -int ltt_event_enable(struct ltt_event *event) -{ - int old; - - if (event->chan == event->chan->session->metadata) - return -EPERM; - old = xchg(&event->enabled, 1); - if (old) - return -EEXIST; - return 0; -} - -int ltt_event_disable(struct ltt_event *event) -{ - int old; - - if (event->chan == event->chan->session->metadata) - return -EPERM; - old = xchg(&event->enabled, 0); - if (!old) - return -EEXIST; - return 0; -} - -static struct ltt_transport *ltt_transport_find(const char *name) -{ - struct ltt_transport *transport; - - list_for_each_entry(transport, <t_transport_list, node) { - if (!strcmp(transport->name, name)) - return transport; - } - return NULL; -} - -struct ltt_channel *ltt_channel_create(struct ltt_session *session, - const char *transport_name, - void *buf_addr, - size_t subbuf_size, size_t num_subbuf, - unsigned int switch_timer_interval, - unsigned int read_timer_interval) -{ - struct ltt_channel *chan; - struct ltt_transport *transport = NULL; - - mutex_lock(&sessions_mutex); - if (session->been_active) - goto active; /* Refuse to add channel to active session */ - transport = ltt_transport_find(transport_name); - if (!transport) { - printk(KERN_WARNING "LTTng transport %s not found\n", - transport_name); - goto notransport; - } - if (!try_module_get(transport->owner)) { - printk(KERN_WARNING "LTT : Can't lock transport module.\n"); - goto notransport; - } - chan = kzalloc(sizeof(struct ltt_channel), GFP_KERNEL); - if (!chan) - goto nomem; - chan->session = session; - chan->id = session->free_chan_id++; - /* - * Note: the channel creation op already writes into the packet - * headers. Therefore the "chan" information used as input - * should be already accessible. - */ - chan->chan = transport->ops.channel_create("[lttng]", chan, buf_addr, - subbuf_size, num_subbuf, switch_timer_interval, - read_timer_interval); - if (!chan->chan) - goto create_error; - chan->enabled = 1; - chan->ops = &transport->ops; - chan->transport = transport; - list_add(&chan->list, &session->chan); - mutex_unlock(&sessions_mutex); - return chan; - -create_error: - kfree(chan); -nomem: - if (transport) - module_put(transport->owner); -notransport: -active: - mutex_unlock(&sessions_mutex); - return NULL; -} - -/* - * Only used internally at session destruction. - */ -static -void _ltt_channel_destroy(struct ltt_channel *chan) -{ - chan->ops->channel_destroy(chan->chan); - module_put(chan->transport->owner); - list_del(&chan->list); - lttng_destroy_context(chan->ctx); - kfree(chan); -} - -/* - * Supports event creation while tracing session is active. - */ -struct ltt_event *ltt_event_create(struct ltt_channel *chan, - struct lttng_kernel_event *event_param, - void *filter, - const struct lttng_event_desc *internal_desc) -{ - struct ltt_event *event; - int ret; - - mutex_lock(&sessions_mutex); - if (chan->free_event_id == -1UL) - goto full; - /* - * This is O(n^2) (for each event, the loop is called at event - * creation). Might require a hash if we have lots of events. - */ - list_for_each_entry(event, &chan->session->events, list) - if (!strcmp(event->desc->name, event_param->name)) - goto exist; - event = kmem_cache_zalloc(event_cache, GFP_KERNEL); - if (!event) - goto cache_error; - event->chan = chan; - event->filter = filter; - event->id = chan->free_event_id++; - event->enabled = 1; - event->instrumentation = event_param->instrumentation; - /* Populate ltt_event structure before tracepoint registration. */ - smp_wmb(); - switch (event_param->instrumentation) { - case LTTNG_KERNEL_TRACEPOINT: - event->desc = ltt_event_get(event_param->name); - if (!event->desc) - goto register_error; - ret = tracepoint_probe_register(event_param->name, - event->desc->probe_callback, - event); - if (ret) - goto register_error; - break; - case LTTNG_KERNEL_KPROBE: - ret = lttng_kprobes_register(event_param->name, - event_param->u.kprobe.symbol_name, - event_param->u.kprobe.offset, - event_param->u.kprobe.addr, - event); - if (ret) - goto register_error; - ret = try_module_get(event->desc->owner); - WARN_ON_ONCE(!ret); - break; - case LTTNG_KERNEL_KRETPROBE: - { - struct ltt_event *event_return; - - /* kretprobe defines 2 events */ - event_return = - kmem_cache_zalloc(event_cache, GFP_KERNEL); - if (!event_return) - goto register_error; - event_return->chan = chan; - event_return->filter = filter; - event_return->id = chan->free_event_id++; - event_return->enabled = 1; - event_return->instrumentation = event_param->instrumentation; - /* - * Populate ltt_event structure before kretprobe registration. - */ - smp_wmb(); - ret = lttng_kretprobes_register(event_param->name, - event_param->u.kretprobe.symbol_name, - event_param->u.kretprobe.offset, - event_param->u.kretprobe.addr, - event, event_return); - if (ret) { - kmem_cache_free(event_cache, event_return); - goto register_error; - } - /* Take 2 refs on the module: one per event. */ - ret = try_module_get(event->desc->owner); - WARN_ON_ONCE(!ret); - ret = try_module_get(event->desc->owner); - WARN_ON_ONCE(!ret); - ret = _ltt_event_metadata_statedump(chan->session, chan, - event_return); - if (ret) { - kmem_cache_free(event_cache, event_return); - module_put(event->desc->owner); - module_put(event->desc->owner); - goto statedump_error; - } - list_add(&event_return->list, &chan->session->events); - break; - } - case LTTNG_KERNEL_FUNCTION: - ret = lttng_ftrace_register(event_param->name, - event_param->u.ftrace.symbol_name, - event); - if (ret) - goto register_error; - ret = try_module_get(event->desc->owner); - WARN_ON_ONCE(!ret); - break; - case LTTNG_KERNEL_NOOP: - event->desc = internal_desc; - if (!event->desc) - goto register_error; - break; - default: - WARN_ON_ONCE(1); - } - ret = _ltt_event_metadata_statedump(chan->session, chan, event); - if (ret) - goto statedump_error; - list_add(&event->list, &chan->session->events); - mutex_unlock(&sessions_mutex); - return event; - -statedump_error: - /* If a statedump error occurs, events will not be readable. */ -register_error: - kmem_cache_free(event_cache, event); -cache_error: -exist: -full: - mutex_unlock(&sessions_mutex); - return NULL; -} - -/* - * Only used internally at session destruction. - */ -int _ltt_event_unregister(struct ltt_event *event) -{ - int ret = -EINVAL; - - switch (event->instrumentation) { - case LTTNG_KERNEL_TRACEPOINT: - ret = tracepoint_probe_unregister(event->desc->name, - event->desc->probe_callback, - event); - if (ret) - return ret; - break; - case LTTNG_KERNEL_KPROBE: - lttng_kprobes_unregister(event); - ret = 0; - break; - case LTTNG_KERNEL_KRETPROBE: - lttng_kretprobes_unregister(event); - ret = 0; - break; - case LTTNG_KERNEL_FUNCTION: - lttng_ftrace_unregister(event); - ret = 0; - break; - case LTTNG_KERNEL_NOOP: - ret = 0; - break; - default: - WARN_ON_ONCE(1); - } - return ret; -} - -/* - * Only used internally at session destruction. - */ -static -void _ltt_event_destroy(struct ltt_event *event) -{ - switch (event->instrumentation) { - case LTTNG_KERNEL_TRACEPOINT: - ltt_event_put(event->desc); - break; - case LTTNG_KERNEL_KPROBE: - module_put(event->desc->owner); - lttng_kprobes_destroy_private(event); - break; - case LTTNG_KERNEL_KRETPROBE: - module_put(event->desc->owner); - lttng_kretprobes_destroy_private(event); - break; - case LTTNG_KERNEL_FUNCTION: - module_put(event->desc->owner); - lttng_ftrace_destroy_private(event); - break; - case LTTNG_KERNEL_NOOP: - break; - default: - WARN_ON_ONCE(1); - } - list_del(&event->list); - lttng_destroy_context(event->ctx); - kmem_cache_free(event_cache, event); -} - -/* - * We have exclusive access to our metadata buffer (protected by the - * sessions_mutex), so we can do racy operations such as looking for - * remaining space left in packet and write, since mutual exclusion - * protects us from concurrent writes. - */ -int lttng_metadata_printf(struct ltt_session *session, - const char *fmt, ...) -{ - struct lib_ring_buffer_ctx ctx; - struct ltt_channel *chan = session->metadata; - char *str; - int ret = 0, waitret; - size_t len, reserve_len, pos; - va_list ap; - - WARN_ON_ONCE(!ACCESS_ONCE(session->active)); - - va_start(ap, fmt); - str = kvasprintf(GFP_KERNEL, fmt, ap); - va_end(ap); - if (!str) - return -ENOMEM; - - len = strlen(str); - pos = 0; - - for (pos = 0; pos < len; pos += reserve_len) { - reserve_len = min_t(size_t, - chan->ops->packet_avail_size(chan->chan), - len - pos); - lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len, - sizeof(char), -1); - /* - * We don't care about metadata buffer's records lost - * count, because we always retry here. Report error if - * we need to bail out after timeout or being - * interrupted. - */ - waitret = wait_event_interruptible_timeout(*chan->ops->get_writer_buf_wait_queue(chan->chan, -1), - ({ - ret = chan->ops->event_reserve(&ctx, 0); - ret != -ENOBUFS || !ret; - }), - msecs_to_jiffies(LTTNG_METADATA_TIMEOUT_MSEC)); - if (!waitret || waitret == -ERESTARTSYS || ret) { - printk(KERN_WARNING "LTTng: Failure to write metadata to buffers (%s)\n", - waitret == -ERESTARTSYS ? "interrupted" : - (ret == -ENOBUFS ? "timeout" : "I/O error")); - if (waitret == -ERESTARTSYS) - ret = waitret; - goto end; - } - chan->ops->event_write(&ctx, &str[pos], reserve_len); - chan->ops->event_commit(&ctx); - } -end: - kfree(str); - return ret; -} - -static -int _ltt_field_statedump(struct ltt_session *session, - const struct lttng_event_field *field) -{ - int ret = 0; - - switch (field->type.atype) { - case atype_integer: - ret = lttng_metadata_printf(session, - " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n", - field->type.u.basic.integer.size, - field->type.u.basic.integer.alignment, - field->type.u.basic.integer.signedness, - (field->type.u.basic.integer.encoding == lttng_encode_none) - ? "none" - : (field->type.u.basic.integer.encoding == lttng_encode_UTF8) - ? "UTF8" - : "ASCII", - field->type.u.basic.integer.base, -#ifdef __BIG_ENDIAN - field->type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", -#else - field->type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", -#endif - field->name); - break; - case atype_enum: - ret = lttng_metadata_printf(session, - " %s _%s;\n", - field->type.u.basic.enumeration.name, - field->name); - break; - case atype_array: - { - const struct lttng_basic_type *elem_type; - - elem_type = &field->type.u.array.elem_type; - ret = lttng_metadata_printf(session, - " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n", - elem_type->u.basic.integer.size, - elem_type->u.basic.integer.alignment, - elem_type->u.basic.integer.signedness, - (elem_type->u.basic.integer.encoding == lttng_encode_none) - ? "none" - : (elem_type->u.basic.integer.encoding == lttng_encode_UTF8) - ? "UTF8" - : "ASCII", - elem_type->u.basic.integer.base, -#ifdef __BIG_ENDIAN - elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", -#else - elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", -#endif - field->name, field->type.u.array.length); - break; - } - case atype_sequence: - { - const struct lttng_basic_type *elem_type; - const struct lttng_basic_type *length_type; - - elem_type = &field->type.u.sequence.elem_type; - length_type = &field->type.u.sequence.length_type; - ret = lttng_metadata_printf(session, - " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n", - length_type->u.basic.integer.size, - (unsigned int) length_type->u.basic.integer.alignment, - length_type->u.basic.integer.signedness, - (length_type->u.basic.integer.encoding == lttng_encode_none) - ? "none" - : ((length_type->u.basic.integer.encoding == lttng_encode_UTF8) - ? "UTF8" - : "ASCII"), - length_type->u.basic.integer.base, -#ifdef __BIG_ENDIAN - length_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", -#else - length_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", -#endif - field->name); - if (ret) - return ret; - - ret = lttng_metadata_printf(session, - " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n", - elem_type->u.basic.integer.size, - (unsigned int) elem_type->u.basic.integer.alignment, - elem_type->u.basic.integer.signedness, - (elem_type->u.basic.integer.encoding == lttng_encode_none) - ? "none" - : ((elem_type->u.basic.integer.encoding == lttng_encode_UTF8) - ? "UTF8" - : "ASCII"), - elem_type->u.basic.integer.base, -#ifdef __BIG_ENDIAN - elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", -#else - elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", -#endif - field->name, - field->name); - break; - } - - case atype_string: - /* Default encoding is UTF8 */ - ret = lttng_metadata_printf(session, - " string%s _%s;\n", - field->type.u.basic.string.encoding == lttng_encode_ASCII ? - " { encoding = ASCII; }" : "", - field->name); - break; - default: - WARN_ON_ONCE(1); - return -EINVAL; - } - return ret; -} - -static -int _ltt_context_metadata_statedump(struct ltt_session *session, - struct lttng_ctx *ctx) -{ - int ret = 0; - int i; - - if (!ctx) - return 0; - for (i = 0; i < ctx->nr_fields; i++) { - const struct lttng_ctx_field *field = &ctx->fields[i]; - - ret = _ltt_field_statedump(session, &field->event_field); - if (ret) - return ret; - } - return ret; -} - -static -int _ltt_fields_metadata_statedump(struct ltt_session *session, - struct ltt_event *event) -{ - const struct lttng_event_desc *desc = event->desc; - int ret = 0; - int i; - - for (i = 0; i < desc->nr_fields; i++) { - const struct lttng_event_field *field = &desc->fields[i]; - - ret = _ltt_field_statedump(session, field); - if (ret) - return ret; - } - return ret; -} - -static -int _ltt_event_metadata_statedump(struct ltt_session *session, - struct ltt_channel *chan, - struct ltt_event *event) -{ - int ret = 0; - - if (event->metadata_dumped || !ACCESS_ONCE(session->active)) - return 0; - if (chan == session->metadata) - return 0; - - ret = lttng_metadata_printf(session, - "event {\n" - " name = %s;\n" - " id = %u;\n" - " stream_id = %u;\n", - event->desc->name, - event->id, - event->chan->id); - if (ret) - goto end; - - if (event->ctx) { - ret = lttng_metadata_printf(session, - " context := struct {\n"); - if (ret) - goto end; - } - ret = _ltt_context_metadata_statedump(session, event->ctx); - if (ret) - goto end; - if (event->ctx) { - ret = lttng_metadata_printf(session, - " };\n"); - if (ret) - goto end; - } - - ret = lttng_metadata_printf(session, - " fields := struct {\n" - ); - if (ret) - goto end; - - ret = _ltt_fields_metadata_statedump(session, event); - if (ret) - goto end; - - /* - * LTTng space reservation can only reserve multiples of the - * byte size. - */ - ret = lttng_metadata_printf(session, - " };\n" - "};\n\n"); - if (ret) - goto end; - - event->metadata_dumped = 1; -end: - return ret; - -} - -static -int _ltt_channel_metadata_statedump(struct ltt_session *session, - struct ltt_channel *chan) -{ - int ret = 0; - - if (chan->metadata_dumped || !ACCESS_ONCE(session->active)) - return 0; - if (chan == session->metadata) - return 0; - - WARN_ON_ONCE(!chan->header_type); - ret = lttng_metadata_printf(session, - "stream {\n" - " id = %u;\n" - " event.header := %s;\n" - " packet.context := struct packet_context;\n", - chan->id, - chan->header_type == 1 ? "struct event_header_compact" : - "struct event_header_large"); - if (ret) - goto end; - - if (chan->ctx) { - ret = lttng_metadata_printf(session, - " event.context := struct {\n"); - if (ret) - goto end; - } - ret = _ltt_context_metadata_statedump(session, chan->ctx); - if (ret) - goto end; - if (chan->ctx) { - ret = lttng_metadata_printf(session, - " };\n"); - if (ret) - goto end; - } - - ret = lttng_metadata_printf(session, - "};\n\n"); - - chan->metadata_dumped = 1; -end: - return ret; -} - -static -int _ltt_stream_packet_context_declare(struct ltt_session *session) -{ - return lttng_metadata_printf(session, - "struct packet_context {\n" - " uint64_t timestamp_begin;\n" - " uint64_t timestamp_end;\n" - " uint32_t events_discarded;\n" - " uint32_t content_size;\n" - " uint32_t packet_size;\n" - " uint32_t cpu_id;\n" - "};\n\n" - ); -} - -/* - * Compact header: - * id: range: 0 - 30. - * id 31 is reserved to indicate an extended header. - * - * Large header: - * id: range: 0 - 65534. - * id 65535 is reserved to indicate an extended header. - */ -static -int _ltt_event_header_declare(struct ltt_session *session) -{ - return lttng_metadata_printf(session, - "struct event_header_compact {\n" - " enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n" - " variant {\n" - " struct {\n" - " uint27_t timestamp;\n" - " } compact;\n" - " struct {\n" - " uint32_t id;\n" - " uint64_t timestamp;\n" - " } extended;\n" - " } v;\n" - "} align(%u);\n" - "\n" - "struct event_header_large {\n" - " enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n" - " variant {\n" - " struct {\n" - " uint32_t timestamp;\n" - " } compact;\n" - " struct {\n" - " uint32_t id;\n" - " uint64_t timestamp;\n" - " } extended;\n" - " } v;\n" - "} align(%u);\n\n", - ltt_alignof(uint32_t) * CHAR_BIT, - ltt_alignof(uint16_t) * CHAR_BIT - ); -} - -/* - * Output metadata into this session's metadata buffers. - */ -static -int _ltt_session_metadata_statedump(struct ltt_session *session) -{ - unsigned char *uuid_c = session->uuid.b; - unsigned char uuid_s[37]; - struct ltt_channel *chan; - struct ltt_event *event; - int ret = 0; - - if (!ACCESS_ONCE(session->active)) - return 0; - if (session->metadata_dumped) - goto skip_session; - if (!session->metadata) { - printk(KERN_WARNING "LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n"); - return -EPERM; - } - - snprintf(uuid_s, sizeof(uuid_s), - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid_c[0], uuid_c[1], uuid_c[2], uuid_c[3], - uuid_c[4], uuid_c[5], uuid_c[6], uuid_c[7], - uuid_c[8], uuid_c[9], uuid_c[10], uuid_c[11], - uuid_c[12], uuid_c[13], uuid_c[14], uuid_c[15]); - - ret = lttng_metadata_printf(session, - "typealias integer { size = 8; align = %u; signed = false; } := uint8_t;\n" - "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n" - "typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n" - "typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n" - "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n" - "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n" - "\n" - "trace {\n" - " major = %u;\n" - " minor = %u;\n" - " uuid = \"%s\";\n" - " byte_order = %s;\n" - " packet.header := struct {\n" - " uint32_t magic;\n" - " uint8_t uuid[16];\n" - " uint32_t stream_id;\n" - " };\n" - "};\n\n", - ltt_alignof(uint8_t) * CHAR_BIT, - ltt_alignof(uint16_t) * CHAR_BIT, - ltt_alignof(uint32_t) * CHAR_BIT, - ltt_alignof(uint64_t) * CHAR_BIT, - CTF_VERSION_MAJOR, - CTF_VERSION_MINOR, - uuid_s, -#ifdef __BIG_ENDIAN - "be" -#else - "le" -#endif - ); - if (ret) - goto end; - - ret = _ltt_stream_packet_context_declare(session); - if (ret) - goto end; - - ret = _ltt_event_header_declare(session); - if (ret) - goto end; - -skip_session: - list_for_each_entry(chan, &session->chan, list) { - ret = _ltt_channel_metadata_statedump(session, chan); - if (ret) - goto end; - } - - list_for_each_entry(event, &session->events, list) { - ret = _ltt_event_metadata_statedump(session, event->chan, event); - if (ret) - goto end; - } - session->metadata_dumped = 1; -end: - return ret; -} - -/** - * ltt_transport_register - LTT transport registration - * @transport: transport structure - * - * Registers a transport which can be used as output to extract the data out of - * LTTng. The module calling this registration function must ensure that no - * trap-inducing code will be executed by the transport functions. E.g. - * vmalloc_sync_all() must be called between a vmalloc and the moment the memory - * is made visible to the transport function. This registration acts as a - * vmalloc_sync_all. Therefore, only if the module allocates virtual memory - * after its registration must it synchronize the TLBs. - */ -void ltt_transport_register(struct ltt_transport *transport) -{ - /* - * Make sure no page fault can be triggered by the module about to be - * registered. We deal with this here so we don't have to call - * vmalloc_sync_all() in each module's init. - */ - wrapper_vmalloc_sync_all(); - - mutex_lock(&sessions_mutex); - list_add_tail(&transport->node, <t_transport_list); - mutex_unlock(&sessions_mutex); -} -EXPORT_SYMBOL_GPL(ltt_transport_register); - -/** - * ltt_transport_unregister - LTT transport unregistration - * @transport: transport structure - */ -void ltt_transport_unregister(struct ltt_transport *transport) -{ - mutex_lock(&sessions_mutex); - list_del(&transport->node); - mutex_unlock(&sessions_mutex); -} -EXPORT_SYMBOL_GPL(ltt_transport_unregister); - -static int __init ltt_events_init(void) -{ - int ret; - - event_cache = KMEM_CACHE(ltt_event, 0); - if (!event_cache) - return -ENOMEM; - ret = lttng_abi_init(); - if (ret) - goto error_abi; - return 0; -error_abi: - kmem_cache_destroy(event_cache); - return ret; -} - -module_init(ltt_events_init); - -static void __exit ltt_events_exit(void) -{ - struct ltt_session *session, *tmpsession; - - lttng_abi_exit(); - list_for_each_entry_safe(session, tmpsession, &sessions, list) - ltt_session_destroy(session); - kmem_cache_destroy(event_cache); -} - -module_exit(ltt_events_exit); - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers "); -MODULE_DESCRIPTION("LTTng Events"); diff --git a/ltt-events.h b/ltt-events.h deleted file mode 100644 index 3aed0e21..00000000 --- a/ltt-events.h +++ /dev/null @@ -1,452 +0,0 @@ -#ifndef _LTT_EVENTS_H -#define _LTT_EVENTS_H - -/* - * ltt-events.h - * - * Copyright 2010 (c) - Mathieu Desnoyers - * - * Holds LTTng per-session event registry. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include -#include "wrapper/uuid.h" -#include "lttng-abi.h" - -#undef is_signed_type -#define is_signed_type(type) (((type)(-1)) < 0) - -struct ltt_channel; -struct ltt_session; -struct lib_ring_buffer_ctx; -struct perf_event; -struct perf_event_attr; - -/* Type description */ - -/* Update the astract_types name table in lttng-types.c along with this enum */ -enum abstract_types { - atype_integer, - atype_enum, - atype_array, - atype_sequence, - atype_string, - NR_ABSTRACT_TYPES, -}; - -/* Update the string_encodings name table in lttng-types.c along with this enum */ -enum lttng_string_encodings { - lttng_encode_none = 0, - lttng_encode_UTF8 = 1, - lttng_encode_ASCII = 2, - NR_STRING_ENCODINGS, -}; - -struct lttng_enum_entry { - unsigned long long start, end; /* start and end are inclusive */ - const char *string; -}; - -#define __type_integer(_type, _byte_order, _base, _encoding) \ - { \ - .atype = atype_integer, \ - .u.basic.integer = \ - { \ - .size = sizeof(_type) * CHAR_BIT, \ - .alignment = ltt_alignof(_type) * CHAR_BIT, \ - .signedness = is_signed_type(_type), \ - .reverse_byte_order = _byte_order != __BYTE_ORDER, \ - .base = _base, \ - .encoding = lttng_encode_##_encoding, \ - }, \ - } \ - -struct lttng_integer_type { - unsigned int size; /* in bits */ - unsigned short alignment; /* in bits */ - unsigned int signedness:1, - reverse_byte_order:1; - unsigned int base; /* 2, 8, 10, 16, for pretty print */ - enum lttng_string_encodings encoding; -}; - -union _lttng_basic_type { - struct lttng_integer_type integer; - struct { - const char *name; - } enumeration; - struct { - enum lttng_string_encodings encoding; - } string; -}; - -struct lttng_basic_type { - enum abstract_types atype; - union { - union _lttng_basic_type basic; - } u; -}; - -struct lttng_type { - enum abstract_types atype; - union { - union _lttng_basic_type basic; - struct { - struct lttng_basic_type elem_type; - unsigned int length; /* num. elems. */ - } array; - struct { - struct lttng_basic_type length_type; - struct lttng_basic_type elem_type; - } sequence; - } u; -}; - -struct lttng_enum { - const char *name; - struct lttng_type container_type; - const struct lttng_enum_entry *entries; - unsigned int len; -}; - -/* Event field description */ - -struct lttng_event_field { - const char *name; - struct lttng_type type; -}; - -/* - * We need to keep this perf counter field separately from struct - * lttng_ctx_field because cpu hotplug needs fixed-location addresses. - */ -struct lttng_perf_counter_field { - struct notifier_block nb; - int hp_enable; - struct perf_event_attr *attr; - struct perf_event **e; /* per-cpu array */ -}; - -struct lttng_ctx_field { - struct lttng_event_field event_field; - size_t (*get_size)(size_t offset); - void (*record)(struct lttng_ctx_field *field, - struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan); - union { - struct lttng_perf_counter_field *perf_counter; - } u; - void (*destroy)(struct lttng_ctx_field *field); -}; - -struct lttng_ctx { - struct lttng_ctx_field *fields; - unsigned int nr_fields; - unsigned int allocated_fields; -}; - -struct lttng_event_desc { - const char *name; - void *probe_callback; - const struct lttng_event_ctx *ctx; /* context */ - const struct lttng_event_field *fields; /* event payload */ - unsigned int nr_fields; - struct module *owner; -}; - -struct lttng_probe_desc { - const struct lttng_event_desc **event_desc; - unsigned int nr_events; - struct list_head head; /* chain registered probes */ -}; - -struct lttng_krp; /* Kretprobe handling */ - -/* - * ltt_event structure is referred to by the tracing fast path. It must be - * kept small. - */ -struct ltt_event { - unsigned int id; - struct ltt_channel *chan; - int enabled; - const struct lttng_event_desc *desc; - void *filter; - struct lttng_ctx *ctx; - enum lttng_kernel_instrumentation instrumentation; - union { - struct { - struct kprobe kp; - char *symbol_name; - } kprobe; - struct { - struct lttng_krp *lttng_krp; - char *symbol_name; - } kretprobe; - struct { - char *symbol_name; - } ftrace; - } u; - struct list_head list; /* Event list */ - unsigned int metadata_dumped:1; -}; - -struct ltt_channel_ops { - struct channel *(*channel_create)(const char *name, - struct ltt_channel *ltt_chan, - void *buf_addr, - size_t subbuf_size, size_t num_subbuf, - unsigned int switch_timer_interval, - unsigned int read_timer_interval); - void (*channel_destroy)(struct channel *chan); - struct lib_ring_buffer *(*buffer_read_open)(struct channel *chan); - int (*buffer_has_read_closed_stream)(struct channel *chan); - void (*buffer_read_close)(struct lib_ring_buffer *buf); - int (*event_reserve)(struct lib_ring_buffer_ctx *ctx, - uint32_t event_id); - void (*event_commit)(struct lib_ring_buffer_ctx *ctx); - void (*event_write)(struct lib_ring_buffer_ctx *ctx, const void *src, - size_t len); - void (*event_write_from_user)(struct lib_ring_buffer_ctx *ctx, - const void *src, size_t len); - void (*event_memset)(struct lib_ring_buffer_ctx *ctx, - int c, size_t len); - /* - * packet_avail_size returns the available size in the current - * packet. Note that the size returned is only a hint, since it - * may change due to concurrent writes. - */ - size_t (*packet_avail_size)(struct channel *chan); - wait_queue_head_t *(*get_writer_buf_wait_queue)(struct channel *chan, int cpu); - wait_queue_head_t *(*get_hp_wait_queue)(struct channel *chan); - int (*is_finalized)(struct channel *chan); - int (*is_disabled)(struct channel *chan); -}; - -struct ltt_transport { - char *name; - struct module *owner; - struct list_head node; - struct ltt_channel_ops ops; -}; - -struct ltt_channel { - unsigned int id; - struct channel *chan; /* Channel buffers */ - int enabled; - struct lttng_ctx *ctx; - /* Event ID management */ - struct ltt_session *session; - struct file *file; /* File associated to channel */ - unsigned int free_event_id; /* Next event ID to allocate */ - struct list_head list; /* Channel list */ - struct ltt_channel_ops *ops; - struct ltt_transport *transport; - struct ltt_event **sc_table; /* for syscall tracing */ - struct ltt_event **compat_sc_table; - struct ltt_event *sc_unknown; /* for unknown syscalls */ - struct ltt_event *sc_compat_unknown; - struct ltt_event *sc_exit; /* for syscall exit */ - int header_type; /* 0: unset, 1: compact, 2: large */ - unsigned int metadata_dumped:1; -}; - -struct ltt_session { - int active; /* Is trace session active ? */ - int been_active; /* Has trace session been active ? */ - struct file *file; /* File associated to session */ - struct ltt_channel *metadata; /* Metadata channel */ - struct list_head chan; /* Channel list head */ - struct list_head events; /* Event list head */ - struct list_head list; /* Session list */ - unsigned int free_chan_id; /* Next chan ID to allocate */ - uuid_le uuid; /* Trace session unique ID */ - unsigned int metadata_dumped:1; -}; - -struct ltt_session *ltt_session_create(void); -int ltt_session_enable(struct ltt_session *session); -int ltt_session_disable(struct ltt_session *session); -void ltt_session_destroy(struct ltt_session *session); - -struct ltt_channel *ltt_channel_create(struct ltt_session *session, - const char *transport_name, - void *buf_addr, - size_t subbuf_size, size_t num_subbuf, - unsigned int switch_timer_interval, - unsigned int read_timer_interval); -struct ltt_channel *ltt_global_channel_create(struct ltt_session *session, - int overwrite, void *buf_addr, - size_t subbuf_size, size_t num_subbuf, - unsigned int switch_timer_interval, - unsigned int read_timer_interval); - -struct ltt_event *ltt_event_create(struct ltt_channel *chan, - struct lttng_kernel_event *event_param, - void *filter, - const struct lttng_event_desc *internal_desc); - -int ltt_channel_enable(struct ltt_channel *channel); -int ltt_channel_disable(struct ltt_channel *channel); -int ltt_event_enable(struct ltt_event *event); -int ltt_event_disable(struct ltt_event *event); - -void ltt_transport_register(struct ltt_transport *transport); -void ltt_transport_unregister(struct ltt_transport *transport); - -void synchronize_trace(void); -int lttng_abi_init(void); -void lttng_abi_exit(void); - -int ltt_probe_register(struct lttng_probe_desc *desc); -void ltt_probe_unregister(struct lttng_probe_desc *desc); -const struct lttng_event_desc *ltt_event_get(const char *name); -void ltt_event_put(const struct lttng_event_desc *desc); -int ltt_probes_init(void); -void ltt_probes_exit(void); - -#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS -int lttng_syscalls_register(struct ltt_channel *chan, void *filter); -int lttng_syscalls_unregister(struct ltt_channel *chan); -#else -static inline int lttng_syscalls_register(struct ltt_channel *chan, void *filter) -{ - return -ENOSYS; -} - -static inline int lttng_syscalls_unregister(struct ltt_channel *chan) -{ - return 0; -} -#endif - -struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx); -int lttng_find_context(struct lttng_ctx *ctx, const char *name); -void lttng_remove_context_field(struct lttng_ctx **ctx, - struct lttng_ctx_field *field); -void lttng_destroy_context(struct lttng_ctx *ctx); -int lttng_add_pid_to_ctx(struct lttng_ctx **ctx); -int lttng_add_procname_to_ctx(struct lttng_ctx **ctx); -int lttng_add_prio_to_ctx(struct lttng_ctx **ctx); -int lttng_add_nice_to_ctx(struct lttng_ctx **ctx); -int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx); -int lttng_add_tid_to_ctx(struct lttng_ctx **ctx); -int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx); -int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx); -int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx); -#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) -int lttng_add_perf_counter_to_ctx(uint32_t type, - uint64_t config, - const char *name, - struct lttng_ctx **ctx); -#else -static inline -int lttng_add_perf_counter_to_ctx(uint32_t type, - uint64_t config, - const char *name, - struct lttng_ctx **ctx) -{ - return -ENOSYS; -} -#endif - -#ifdef CONFIG_KPROBES -int lttng_kprobes_register(const char *name, - const char *symbol_name, - uint64_t offset, - uint64_t addr, - struct ltt_event *event); -void lttng_kprobes_unregister(struct ltt_event *event); -void lttng_kprobes_destroy_private(struct ltt_event *event); -#else -static inline -int lttng_kprobes_register(const char *name, - const char *symbol_name, - uint64_t offset, - uint64_t addr, - struct ltt_event *event) -{ - return -ENOSYS; -} - -static inline -void lttng_kprobes_unregister(struct ltt_event *event) -{ -} - -static inline -void lttng_kprobes_destroy_private(struct ltt_event *event) -{ -} -#endif - -#ifdef CONFIG_KRETPROBES -int lttng_kretprobes_register(const char *name, - const char *symbol_name, - uint64_t offset, - uint64_t addr, - struct ltt_event *event_entry, - struct ltt_event *event_exit); -void lttng_kretprobes_unregister(struct ltt_event *event); -void lttng_kretprobes_destroy_private(struct ltt_event *event); -#else -static inline -int lttng_kretprobes_register(const char *name, - const char *symbol_name, - uint64_t offset, - uint64_t addr, - struct ltt_event *event_entry, - struct ltt_event *event_exit) -{ - return -ENOSYS; -} - -static inline -void lttng_kretprobes_unregister(struct ltt_event *event) -{ -} - -static inline -void lttng_kretprobes_destroy_private(struct ltt_event *event) -{ -} -#endif - -#ifdef CONFIG_DYNAMIC_FTRACE -int lttng_ftrace_register(const char *name, - const char *symbol_name, - struct ltt_event *event); -void lttng_ftrace_unregister(struct ltt_event *event); -void lttng_ftrace_destroy_private(struct ltt_event *event); -#else -static inline -int lttng_ftrace_register(const char *name, - const char *symbol_name, - struct ltt_event *event) -{ - return -ENOSYS; -} - -static inline -void lttng_ftrace_unregister(struct ltt_event *event) -{ -} - -static inline -void lttng_ftrace_destroy_private(struct ltt_event *event) -{ -} -#endif - -int lttng_calibrate(struct lttng_kernel_calibrate *calibrate); - -extern const struct file_operations lttng_tracepoint_list_fops; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -#define TRACEPOINT_HAS_DATA_ARG -#endif - -#endif /* _LTT_EVENTS_H */ diff --git a/ltt-probes.c b/ltt-probes.c deleted file mode 100644 index 81dcbd71..00000000 --- a/ltt-probes.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ltt-probes.c - * - * Copyright 2010 (c) - Mathieu Desnoyers - * - * Holds LTTng probes registry. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include -#include -#include - -#include "ltt-events.h" - -static LIST_HEAD(probe_list); -static DEFINE_MUTEX(probe_mutex); - -static -const struct lttng_event_desc *find_event(const char *name) -{ - struct lttng_probe_desc *probe_desc; - int i; - - list_for_each_entry(probe_desc, &probe_list, head) { - for (i = 0; i < probe_desc->nr_events; i++) { - if (!strcmp(probe_desc->event_desc[i]->name, name)) - return probe_desc->event_desc[i]; - } - } - return NULL; -} - -int ltt_probe_register(struct lttng_probe_desc *desc) -{ - int ret = 0; - int i; - - mutex_lock(&probe_mutex); - /* - * TODO: This is O(N^2). Turn into a hash table when probe registration - * overhead becomes an issue. - */ - for (i = 0; i < desc->nr_events; i++) { - if (find_event(desc->event_desc[i]->name)) { - ret = -EEXIST; - goto end; - } - } - list_add(&desc->head, &probe_list); -end: - mutex_unlock(&probe_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(ltt_probe_register); - -void ltt_probe_unregister(struct lttng_probe_desc *desc) -{ - mutex_lock(&probe_mutex); - list_del(&desc->head); - mutex_unlock(&probe_mutex); -} -EXPORT_SYMBOL_GPL(ltt_probe_unregister); - -const struct lttng_event_desc *ltt_event_get(const char *name) -{ - const struct lttng_event_desc *event; - int ret; - - mutex_lock(&probe_mutex); - event = find_event(name); - mutex_unlock(&probe_mutex); - if (!event) - return NULL; - ret = try_module_get(event->owner); - WARN_ON_ONCE(!ret); - return event; -} -EXPORT_SYMBOL_GPL(ltt_event_get); - -void ltt_event_put(const struct lttng_event_desc *event) -{ - module_put(event->owner); -} -EXPORT_SYMBOL_GPL(ltt_event_put); - -static -void *tp_list_start(struct seq_file *m, loff_t *pos) -{ - struct lttng_probe_desc *probe_desc; - int iter = 0, i; - - mutex_lock(&probe_mutex); - list_for_each_entry(probe_desc, &probe_list, head) { - for (i = 0; i < probe_desc->nr_events; i++) { - if (iter++ >= *pos) - return (void *) probe_desc->event_desc[i]; - } - } - /* End of list */ - return NULL; -} - -static -void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos) -{ - struct lttng_probe_desc *probe_desc; - int iter = 0, i; - - (*ppos)++; - list_for_each_entry(probe_desc, &probe_list, head) { - for (i = 0; i < probe_desc->nr_events; i++) { - if (iter++ >= *ppos) - return (void *) probe_desc->event_desc[i]; - } - } - /* End of list */ - return NULL; -} - -static -void tp_list_stop(struct seq_file *m, void *p) -{ - mutex_unlock(&probe_mutex); -} - -static -int tp_list_show(struct seq_file *m, void *p) -{ - const struct lttng_event_desc *probe_desc = p; - - /* - * Don't export lttng internal events (metadata). - */ - if (!strncmp(probe_desc->name, "lttng_", sizeof("lttng_") - 1)) - return 0; - seq_printf(m, "event { name = %s; };\n", - probe_desc->name); - return 0; -} - -static -const struct seq_operations lttng_tracepoint_list_seq_ops = { - .start = tp_list_start, - .next = tp_list_next, - .stop = tp_list_stop, - .show = tp_list_show, -}; - -static -int lttng_tracepoint_list_open(struct inode *inode, struct file *file) -{ - return seq_open(file, <tng_tracepoint_list_seq_ops); -} - -const struct file_operations lttng_tracepoint_list_fops = { - .owner = THIS_MODULE, - .open = lttng_tracepoint_list_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; diff --git a/ltt-ring-buffer-client-discard.c b/ltt-ring-buffer-client-discard.c deleted file mode 100644 index eafcf45a..00000000 --- a/ltt-ring-buffer-client-discard.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * ltt-ring-buffer-client-discard.c - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer client (discard mode). - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include "ltt-tracer.h" - -#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD -#define RING_BUFFER_MODE_TEMPLATE_STRING "discard" -#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE -#include "ltt-ring-buffer-client.h" - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode"); diff --git a/ltt-ring-buffer-client-mmap-discard.c b/ltt-ring-buffer-client-mmap-discard.c deleted file mode 100644 index 29819a73..00000000 --- a/ltt-ring-buffer-client-mmap-discard.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * ltt-ring-buffer-client-discard.c - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer client (discard mode). - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include "ltt-tracer.h" - -#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD -#define RING_BUFFER_MODE_TEMPLATE_STRING "discard-mmap" -#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP -#include "ltt-ring-buffer-client.h" - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode"); diff --git a/ltt-ring-buffer-client-mmap-overwrite.c b/ltt-ring-buffer-client-mmap-overwrite.c deleted file mode 100644 index 741aa7b4..00000000 --- a/ltt-ring-buffer-client-mmap-overwrite.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * ltt-ring-buffer-client-overwrite.c - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer client (overwrite mode). - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include "ltt-tracer.h" - -#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_OVERWRITE -#define RING_BUFFER_MODE_TEMPLATE_STRING "overwrite-mmap" -#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP -#include "ltt-ring-buffer-client.h" - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode"); diff --git a/ltt-ring-buffer-client-overwrite.c b/ltt-ring-buffer-client-overwrite.c deleted file mode 100644 index 9811941a..00000000 --- a/ltt-ring-buffer-client-overwrite.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * ltt-ring-buffer-client-overwrite.c - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer client (overwrite mode). - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include "ltt-tracer.h" - -#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_OVERWRITE -#define RING_BUFFER_MODE_TEMPLATE_STRING "overwrite" -#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE -#include "ltt-ring-buffer-client.h" - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode"); diff --git a/ltt-ring-buffer-client.h b/ltt-ring-buffer-client.h deleted file mode 100644 index 8df37901..00000000 --- a/ltt-ring-buffer-client.h +++ /dev/null @@ -1,569 +0,0 @@ -/* - * ltt-ring-buffer-client.h - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer client template. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include -#include "lib/bitfield.h" -#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ -#include "wrapper/trace-clock.h" -#include "ltt-events.h" -#include "ltt-tracer.h" -#include "wrapper/ringbuffer/frontend_types.h" - -/* - * Keep the natural field alignment for _each field_ within this structure if - * you ever add/remove a field from this header. Packed attribute is not used - * because gcc generates poor code on at least powerpc and mips. Don't ever - * let gcc add padding between the structure elements. - * - * The guarantee we have with timestamps is that all the events in a - * packet are included (inclusive) within the begin/end timestamps of - * the packet. Another guarantee we have is that the "timestamp begin", - * as well as the event timestamps, are monotonically increasing (never - * decrease) when moving forward in a stream (physically). But this - * guarantee does not apply to "timestamp end", because it is sampled at - * commit time, which is not ordered with respect to space reservation. - */ - -struct packet_header { - /* Trace packet header */ - uint32_t magic; /* - * Trace magic number. - * contains endianness information. - */ - uint8_t uuid[16]; - uint32_t stream_id; - - struct { - /* Stream packet context */ - uint64_t timestamp_begin; /* Cycle count at subbuffer start */ - uint64_t timestamp_end; /* Cycle count at subbuffer end */ - uint32_t events_discarded; /* - * Events lost in this subbuffer since - * the beginning of the trace. - * (may overflow) - */ - uint32_t content_size; /* Size of data in subbuffer */ - uint32_t packet_size; /* Subbuffer size (include padding) */ - uint32_t cpu_id; /* CPU id associated with stream */ - uint8_t header_end; /* End of header */ - } ctx; -}; - - -static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan) -{ - return trace_clock_read64(); -} - -static inline -size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx) -{ - int i; - size_t orig_offset = offset; - - if (likely(!ctx)) - return 0; - for (i = 0; i < ctx->nr_fields; i++) - offset += ctx->fields[i].get_size(offset); - return offset - orig_offset; -} - -static inline -void ctx_record(struct lib_ring_buffer_ctx *bufctx, - struct ltt_channel *chan, - struct lttng_ctx *ctx) -{ - int i; - - if (likely(!ctx)) - return; - for (i = 0; i < ctx->nr_fields; i++) - ctx->fields[i].record(&ctx->fields[i], bufctx, chan); -} - -/* - * record_header_size - Calculate the header size and padding necessary. - * @config: ring buffer instance configuration - * @chan: channel - * @offset: offset in the write buffer - * @pre_header_padding: padding to add before the header (output) - * @ctx: reservation context - * - * Returns the event header size (including padding). - * - * The payload must itself determine its own alignment from the biggest type it - * contains. - */ -static __inline__ -unsigned char record_header_size(const struct lib_ring_buffer_config *config, - struct channel *chan, size_t offset, - size_t *pre_header_padding, - struct lib_ring_buffer_ctx *ctx) -{ - struct ltt_channel *ltt_chan = channel_get_private(chan); - struct ltt_event *event = ctx->priv; - size_t orig_offset = offset; - size_t padding; - - switch (ltt_chan->header_type) { - case 1: /* compact */ - padding = lib_ring_buffer_align(offset, ltt_alignof(uint32_t)); - offset += padding; - if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) { - offset += sizeof(uint32_t); /* id and timestamp */ - } else { - /* Minimum space taken by 5-bit id */ - offset += sizeof(uint8_t); - /* Align extended struct on largest member */ - offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); - offset += sizeof(uint32_t); /* id */ - offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); - offset += sizeof(uint64_t); /* timestamp */ - } - break; - case 2: /* large */ - padding = lib_ring_buffer_align(offset, ltt_alignof(uint16_t)); - offset += padding; - offset += sizeof(uint16_t); - if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) { - offset += lib_ring_buffer_align(offset, ltt_alignof(uint32_t)); - offset += sizeof(uint32_t); /* timestamp */ - } else { - /* Align extended struct on largest member */ - offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); - offset += sizeof(uint32_t); /* id */ - offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); - offset += sizeof(uint64_t); /* timestamp */ - } - break; - default: - padding = 0; - WARN_ON_ONCE(1); - } - offset += ctx_get_size(offset, event->ctx); - offset += ctx_get_size(offset, ltt_chan->ctx); - - *pre_header_padding = padding; - return offset - orig_offset; -} - -#include "wrapper/ringbuffer/api.h" - -static -void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config, - struct lib_ring_buffer_ctx *ctx, - uint32_t event_id); - -/* - * ltt_write_event_header - * - * Writes the event header to the offset (already aligned on 32-bits). - * - * @config: ring buffer instance configuration - * @ctx: reservation context - * @event_id: event ID - */ -static __inline__ -void ltt_write_event_header(const struct lib_ring_buffer_config *config, - struct lib_ring_buffer_ctx *ctx, - uint32_t event_id) -{ - struct ltt_channel *ltt_chan = channel_get_private(ctx->chan); - struct ltt_event *event = ctx->priv; - - if (unlikely(ctx->rflags)) - goto slow_path; - - switch (ltt_chan->header_type) { - case 1: /* compact */ - { - uint32_t id_time = 0; - - bt_bitfield_write(&id_time, uint32_t, 0, 5, event_id); - bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc); - lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time)); - break; - } - case 2: /* large */ - { - uint32_t timestamp = (uint32_t) ctx->tsc; - uint16_t id = event_id; - - lib_ring_buffer_write(config, ctx, &id, sizeof(id)); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint32_t)); - lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); - break; - } - default: - WARN_ON_ONCE(1); - } - - ctx_record(ctx, ltt_chan, ltt_chan->ctx); - ctx_record(ctx, ltt_chan, event->ctx); - lib_ring_buffer_align_ctx(ctx, ctx->largest_align); - - return; - -slow_path: - ltt_write_event_header_slow(config, ctx, event_id); -} - -static -void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config, - struct lib_ring_buffer_ctx *ctx, - uint32_t event_id) -{ - struct ltt_channel *ltt_chan = channel_get_private(ctx->chan); - struct ltt_event *event = ctx->priv; - - switch (ltt_chan->header_type) { - case 1: /* compact */ - if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) { - uint32_t id_time = 0; - - bt_bitfield_write(&id_time, uint32_t, 0, 5, event_id); - bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc); - lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time)); - } else { - uint8_t id = 0; - uint64_t timestamp = ctx->tsc; - - bt_bitfield_write(&id, uint8_t, 0, 5, 31); - lib_ring_buffer_write(config, ctx, &id, sizeof(id)); - /* Align extended struct on largest member */ - lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t)); - lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id)); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t)); - lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); - } - break; - case 2: /* large */ - { - if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) { - uint32_t timestamp = (uint32_t) ctx->tsc; - uint16_t id = event_id; - - lib_ring_buffer_write(config, ctx, &id, sizeof(id)); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint32_t)); - lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); - } else { - uint16_t id = 65535; - uint64_t timestamp = ctx->tsc; - - lib_ring_buffer_write(config, ctx, &id, sizeof(id)); - /* Align extended struct on largest member */ - lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t)); - lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id)); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t)); - lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); - } - break; - } - default: - WARN_ON_ONCE(1); - } - ctx_record(ctx, ltt_chan, ltt_chan->ctx); - ctx_record(ctx, ltt_chan, event->ctx); - lib_ring_buffer_align_ctx(ctx, ctx->largest_align); -} - -static const struct lib_ring_buffer_config client_config; - -static u64 client_ring_buffer_clock_read(struct channel *chan) -{ - return lib_ring_buffer_clock_read(chan); -} - -static -size_t client_record_header_size(const struct lib_ring_buffer_config *config, - struct channel *chan, size_t offset, - size_t *pre_header_padding, - struct lib_ring_buffer_ctx *ctx) -{ - return record_header_size(config, chan, offset, - pre_header_padding, ctx); -} - -/** - * client_packet_header_size - called on buffer-switch to a new sub-buffer - * - * Return header size without padding after the structure. Don't use packed - * structure because gcc generates inefficient code on some architectures - * (powerpc, mips..) - */ -static size_t client_packet_header_size(void) -{ - return offsetof(struct packet_header, ctx.header_end); -} - -static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc, - unsigned int subbuf_idx) -{ - struct channel *chan = buf->backend.chan; - struct packet_header *header = - (struct packet_header *) - lib_ring_buffer_offset_address(&buf->backend, - subbuf_idx * chan->backend.subbuf_size); - struct ltt_channel *ltt_chan = channel_get_private(chan); - struct ltt_session *session = ltt_chan->session; - - header->magic = CTF_MAGIC_NUMBER; - memcpy(header->uuid, session->uuid.b, sizeof(session->uuid)); - header->stream_id = ltt_chan->id; - header->ctx.timestamp_begin = tsc; - header->ctx.timestamp_end = 0; - header->ctx.events_discarded = 0; - header->ctx.content_size = 0xFFFFFFFF; /* for debugging */ - header->ctx.packet_size = 0xFFFFFFFF; - header->ctx.cpu_id = buf->backend.cpu; -} - -/* - * offset is assumed to never be 0 here : never deliver a completely empty - * subbuffer. data_size is between 1 and subbuf_size. - */ -static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc, - unsigned int subbuf_idx, unsigned long data_size) -{ - struct channel *chan = buf->backend.chan; - struct packet_header *header = - (struct packet_header *) - lib_ring_buffer_offset_address(&buf->backend, - subbuf_idx * chan->backend.subbuf_size); - unsigned long records_lost = 0; - - header->ctx.timestamp_end = tsc; - header->ctx.content_size = data_size * CHAR_BIT; /* in bits */ - header->ctx.packet_size = PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */ - records_lost += lib_ring_buffer_get_records_lost_full(&client_config, buf); - records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf); - records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf); - header->ctx.events_discarded = records_lost; -} - -static int client_buffer_create(struct lib_ring_buffer *buf, void *priv, - int cpu, const char *name) -{ - return 0; -} - -static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu) -{ -} - -static const struct lib_ring_buffer_config client_config = { - .cb.ring_buffer_clock_read = client_ring_buffer_clock_read, - .cb.record_header_size = client_record_header_size, - .cb.subbuffer_header_size = client_packet_header_size, - .cb.buffer_begin = client_buffer_begin, - .cb.buffer_end = client_buffer_end, - .cb.buffer_create = client_buffer_create, - .cb.buffer_finalize = client_buffer_finalize, - - .tsc_bits = 32, - .alloc = RING_BUFFER_ALLOC_PER_CPU, - .sync = RING_BUFFER_SYNC_PER_CPU, - .mode = RING_BUFFER_MODE_TEMPLATE, - .backend = RING_BUFFER_PAGE, - .output = RING_BUFFER_OUTPUT_TEMPLATE, - .oops = RING_BUFFER_OOPS_CONSISTENCY, - .ipi = RING_BUFFER_IPI_BARRIER, - .wakeup = RING_BUFFER_WAKEUP_BY_TIMER, -}; - -static -struct channel *_channel_create(const char *name, - struct ltt_channel *ltt_chan, void *buf_addr, - size_t subbuf_size, size_t num_subbuf, - unsigned int switch_timer_interval, - unsigned int read_timer_interval) -{ - return channel_create(&client_config, name, ltt_chan, buf_addr, - subbuf_size, num_subbuf, switch_timer_interval, - read_timer_interval); -} - -static -void ltt_channel_destroy(struct channel *chan) -{ - channel_destroy(chan); -} - -static -struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan) -{ - struct lib_ring_buffer *buf; - int cpu; - - for_each_channel_cpu(cpu, chan) { - buf = channel_get_ring_buffer(&client_config, chan, cpu); - if (!lib_ring_buffer_open_read(buf)) - return buf; - } - return NULL; -} - -static -int ltt_buffer_has_read_closed_stream(struct channel *chan) -{ - struct lib_ring_buffer *buf; - int cpu; - - for_each_channel_cpu(cpu, chan) { - buf = channel_get_ring_buffer(&client_config, chan, cpu); - if (!atomic_long_read(&buf->active_readers)) - return 1; - } - return 0; -} - -static -void ltt_buffer_read_close(struct lib_ring_buffer *buf) -{ - lib_ring_buffer_release_read(buf); -} - -static -int ltt_event_reserve(struct lib_ring_buffer_ctx *ctx, - uint32_t event_id) -{ - struct ltt_channel *ltt_chan = channel_get_private(ctx->chan); - int ret, cpu; - - cpu = lib_ring_buffer_get_cpu(&client_config); - if (cpu < 0) - return -EPERM; - ctx->cpu = cpu; - - switch (ltt_chan->header_type) { - case 1: /* compact */ - if (event_id > 30) - ctx->rflags |= LTT_RFLAG_EXTENDED; - break; - case 2: /* large */ - if (event_id > 65534) - ctx->rflags |= LTT_RFLAG_EXTENDED; - break; - default: - WARN_ON_ONCE(1); - } - - ret = lib_ring_buffer_reserve(&client_config, ctx); - if (ret) - goto put; - ltt_write_event_header(&client_config, ctx, event_id); - return 0; -put: - lib_ring_buffer_put_cpu(&client_config); - return ret; -} - -static -void ltt_event_commit(struct lib_ring_buffer_ctx *ctx) -{ - lib_ring_buffer_commit(&client_config, ctx); - lib_ring_buffer_put_cpu(&client_config); -} - -static -void ltt_event_write(struct lib_ring_buffer_ctx *ctx, const void *src, - size_t len) -{ - lib_ring_buffer_write(&client_config, ctx, src, len); -} - -static -void ltt_event_write_from_user(struct lib_ring_buffer_ctx *ctx, - const void __user *src, size_t len) -{ - lib_ring_buffer_copy_from_user(&client_config, ctx, src, len); -} - -static -void ltt_event_memset(struct lib_ring_buffer_ctx *ctx, - int c, size_t len) -{ - lib_ring_buffer_memset(&client_config, ctx, c, len); -} - -static -wait_queue_head_t *ltt_get_writer_buf_wait_queue(struct channel *chan, int cpu) -{ - struct lib_ring_buffer *buf = channel_get_ring_buffer(&client_config, - chan, cpu); - return &buf->write_wait; -} - -static -wait_queue_head_t *ltt_get_hp_wait_queue(struct channel *chan) -{ - return &chan->hp_wait; -} - -static -int ltt_is_finalized(struct channel *chan) -{ - return lib_ring_buffer_channel_is_finalized(chan); -} - -static -int ltt_is_disabled(struct channel *chan) -{ - return lib_ring_buffer_channel_is_disabled(chan); -} - -static struct ltt_transport ltt_relay_transport = { - .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING, - .owner = THIS_MODULE, - .ops = { - .channel_create = _channel_create, - .channel_destroy = ltt_channel_destroy, - .buffer_read_open = ltt_buffer_read_open, - .buffer_has_read_closed_stream = - ltt_buffer_has_read_closed_stream, - .buffer_read_close = ltt_buffer_read_close, - .event_reserve = ltt_event_reserve, - .event_commit = ltt_event_commit, - .event_write = ltt_event_write, - .event_write_from_user = ltt_event_write_from_user, - .event_memset = ltt_event_memset, - .packet_avail_size = NULL, /* Would be racy anyway */ - .get_writer_buf_wait_queue = ltt_get_writer_buf_wait_queue, - .get_hp_wait_queue = ltt_get_hp_wait_queue, - .is_finalized = ltt_is_finalized, - .is_disabled = ltt_is_disabled, - }, -}; - -static int __init ltt_ring_buffer_client_init(void) -{ - /* - * This vmalloc sync all also takes care of the lib ring buffer - * vmalloc'd module pages when it is built as a module into LTTng. - */ - wrapper_vmalloc_sync_all(); - ltt_transport_register(<t_relay_transport); - return 0; -} - -module_init(ltt_ring_buffer_client_init); - -static void __exit ltt_ring_buffer_client_exit(void) -{ - ltt_transport_unregister(<t_relay_transport); -} - -module_exit(ltt_ring_buffer_client_exit); - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING - " client"); diff --git a/ltt-ring-buffer-metadata-client.c b/ltt-ring-buffer-metadata-client.c deleted file mode 100644 index ac6fe78c..00000000 --- a/ltt-ring-buffer-metadata-client.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * ltt-ring-buffer-metadata-client.c - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer metadta client. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include "ltt-tracer.h" - -#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD -#define RING_BUFFER_MODE_TEMPLATE_STRING "metadata" -#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE -#include "ltt-ring-buffer-metadata-client.h" - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client"); diff --git a/ltt-ring-buffer-metadata-client.h b/ltt-ring-buffer-metadata-client.h deleted file mode 100644 index 529bbb19..00000000 --- a/ltt-ring-buffer-metadata-client.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * ltt-ring-buffer-client.h - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer client template. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include -#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ -#include "ltt-events.h" -#include "ltt-tracer.h" - -struct metadata_packet_header { - uint32_t magic; /* 0x75D11D57 */ - uint8_t uuid[16]; /* Unique Universal Identifier */ - uint32_t checksum; /* 0 if unused */ - uint32_t content_size; /* in bits */ - uint32_t packet_size; /* in bits */ - uint8_t compression_scheme; /* 0 if unused */ - uint8_t encryption_scheme; /* 0 if unused */ - uint8_t checksum_scheme; /* 0 if unused */ - uint8_t major; /* CTF spec major version number */ - uint8_t minor; /* CTF spec minor version number */ - uint8_t header_end[0]; -}; - -struct metadata_record_header { - uint8_t header_end[0]; /* End of header */ -}; - -static const struct lib_ring_buffer_config client_config; - -static inline -u64 lib_ring_buffer_clock_read(struct channel *chan) -{ - return 0; -} - -static inline -unsigned char record_header_size(const struct lib_ring_buffer_config *config, - struct channel *chan, size_t offset, - size_t *pre_header_padding, - struct lib_ring_buffer_ctx *ctx) -{ - return 0; -} - -#include "wrapper/ringbuffer/api.h" - -static u64 client_ring_buffer_clock_read(struct channel *chan) -{ - return 0; -} - -static -size_t client_record_header_size(const struct lib_ring_buffer_config *config, - struct channel *chan, size_t offset, - size_t *pre_header_padding, - struct lib_ring_buffer_ctx *ctx) -{ - return 0; -} - -/** - * client_packet_header_size - called on buffer-switch to a new sub-buffer - * - * Return header size without padding after the structure. Don't use packed - * structure because gcc generates inefficient code on some architectures - * (powerpc, mips..) - */ -static size_t client_packet_header_size(void) -{ - return offsetof(struct metadata_packet_header, header_end); -} - -static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc, - unsigned int subbuf_idx) -{ - struct channel *chan = buf->backend.chan; - struct metadata_packet_header *header = - (struct metadata_packet_header *) - lib_ring_buffer_offset_address(&buf->backend, - subbuf_idx * chan->backend.subbuf_size); - struct ltt_channel *ltt_chan = channel_get_private(chan); - struct ltt_session *session = ltt_chan->session; - - header->magic = TSDL_MAGIC_NUMBER; - memcpy(header->uuid, session->uuid.b, sizeof(session->uuid)); - header->checksum = 0; /* 0 if unused */ - header->content_size = 0xFFFFFFFF; /* in bits, for debugging */ - header->packet_size = 0xFFFFFFFF; /* in bits, for debugging */ - header->compression_scheme = 0; /* 0 if unused */ - header->encryption_scheme = 0; /* 0 if unused */ - header->checksum_scheme = 0; /* 0 if unused */ - header->major = CTF_SPEC_MAJOR; - header->minor = CTF_SPEC_MINOR; -} - -/* - * offset is assumed to never be 0 here : never deliver a completely empty - * subbuffer. data_size is between 1 and subbuf_size. - */ -static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc, - unsigned int subbuf_idx, unsigned long data_size) -{ - struct channel *chan = buf->backend.chan; - struct metadata_packet_header *header = - (struct metadata_packet_header *) - lib_ring_buffer_offset_address(&buf->backend, - subbuf_idx * chan->backend.subbuf_size); - unsigned long records_lost = 0; - - header->content_size = data_size * CHAR_BIT; /* in bits */ - header->packet_size = PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */ - /* - * We do not care about the records lost count, because the metadata - * channel waits and retry. - */ - (void) lib_ring_buffer_get_records_lost_full(&client_config, buf); - records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf); - records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf); - WARN_ON_ONCE(records_lost != 0); -} - -static int client_buffer_create(struct lib_ring_buffer *buf, void *priv, - int cpu, const char *name) -{ - return 0; -} - -static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu) -{ -} - -static const struct lib_ring_buffer_config client_config = { - .cb.ring_buffer_clock_read = client_ring_buffer_clock_read, - .cb.record_header_size = client_record_header_size, - .cb.subbuffer_header_size = client_packet_header_size, - .cb.buffer_begin = client_buffer_begin, - .cb.buffer_end = client_buffer_end, - .cb.buffer_create = client_buffer_create, - .cb.buffer_finalize = client_buffer_finalize, - - .tsc_bits = 0, - .alloc = RING_BUFFER_ALLOC_GLOBAL, - .sync = RING_BUFFER_SYNC_GLOBAL, - .mode = RING_BUFFER_MODE_TEMPLATE, - .backend = RING_BUFFER_PAGE, - .output = RING_BUFFER_OUTPUT_TEMPLATE, - .oops = RING_BUFFER_OOPS_CONSISTENCY, - .ipi = RING_BUFFER_IPI_BARRIER, - .wakeup = RING_BUFFER_WAKEUP_BY_TIMER, -}; - -static -struct channel *_channel_create(const char *name, - struct ltt_channel *ltt_chan, void *buf_addr, - size_t subbuf_size, size_t num_subbuf, - unsigned int switch_timer_interval, - unsigned int read_timer_interval) -{ - return channel_create(&client_config, name, ltt_chan, buf_addr, - subbuf_size, num_subbuf, switch_timer_interval, - read_timer_interval); -} - -static -void ltt_channel_destroy(struct channel *chan) -{ - channel_destroy(chan); -} - -static -struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan) -{ - struct lib_ring_buffer *buf; - - buf = channel_get_ring_buffer(&client_config, chan, 0); - if (!lib_ring_buffer_open_read(buf)) - return buf; - return NULL; -} - -static -int ltt_buffer_has_read_closed_stream(struct channel *chan) -{ - struct lib_ring_buffer *buf; - int cpu; - - for_each_channel_cpu(cpu, chan) { - buf = channel_get_ring_buffer(&client_config, chan, cpu); - if (!atomic_long_read(&buf->active_readers)) - return 1; - } - return 0; -} - -static -void ltt_buffer_read_close(struct lib_ring_buffer *buf) -{ - lib_ring_buffer_release_read(buf); -} - -static -int ltt_event_reserve(struct lib_ring_buffer_ctx *ctx, uint32_t event_id) -{ - return lib_ring_buffer_reserve(&client_config, ctx); -} - -static -void ltt_event_commit(struct lib_ring_buffer_ctx *ctx) -{ - lib_ring_buffer_commit(&client_config, ctx); -} - -static -void ltt_event_write(struct lib_ring_buffer_ctx *ctx, const void *src, - size_t len) -{ - lib_ring_buffer_write(&client_config, ctx, src, len); -} - -static -void ltt_event_write_from_user(struct lib_ring_buffer_ctx *ctx, - const void __user *src, size_t len) -{ - lib_ring_buffer_copy_from_user(&client_config, ctx, src, len); -} - -static -void ltt_event_memset(struct lib_ring_buffer_ctx *ctx, - int c, size_t len) -{ - lib_ring_buffer_memset(&client_config, ctx, c, len); -} - -static -size_t ltt_packet_avail_size(struct channel *chan) - -{ - unsigned long o_begin; - struct lib_ring_buffer *buf; - - buf = chan->backend.buf; /* Only for global buffer ! */ - o_begin = v_read(&client_config, &buf->offset); - if (subbuf_offset(o_begin, chan) != 0) { - return chan->backend.subbuf_size - subbuf_offset(o_begin, chan); - } else { - return chan->backend.subbuf_size - subbuf_offset(o_begin, chan) - - sizeof(struct metadata_packet_header); - } -} - -static -wait_queue_head_t *ltt_get_writer_buf_wait_queue(struct channel *chan, int cpu) -{ - struct lib_ring_buffer *buf = channel_get_ring_buffer(&client_config, - chan, cpu); - return &buf->write_wait; -} - -static -wait_queue_head_t *ltt_get_hp_wait_queue(struct channel *chan) -{ - return &chan->hp_wait; -} - -static -int ltt_is_finalized(struct channel *chan) -{ - return lib_ring_buffer_channel_is_finalized(chan); -} - -static -int ltt_is_disabled(struct channel *chan) -{ - return lib_ring_buffer_channel_is_disabled(chan); -} - -static struct ltt_transport ltt_relay_transport = { - .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING, - .owner = THIS_MODULE, - .ops = { - .channel_create = _channel_create, - .channel_destroy = ltt_channel_destroy, - .buffer_read_open = ltt_buffer_read_open, - .buffer_has_read_closed_stream = - ltt_buffer_has_read_closed_stream, - .buffer_read_close = ltt_buffer_read_close, - .event_reserve = ltt_event_reserve, - .event_commit = ltt_event_commit, - .event_write_from_user = ltt_event_write_from_user, - .event_memset = ltt_event_memset, - .event_write = ltt_event_write, - .packet_avail_size = ltt_packet_avail_size, - .get_writer_buf_wait_queue = ltt_get_writer_buf_wait_queue, - .get_hp_wait_queue = ltt_get_hp_wait_queue, - .is_finalized = ltt_is_finalized, - .is_disabled = ltt_is_disabled, - }, -}; - -static int __init ltt_ring_buffer_client_init(void) -{ - /* - * This vmalloc sync all also takes care of the lib ring buffer - * vmalloc'd module pages when it is built as a module into LTTng. - */ - wrapper_vmalloc_sync_all(); - ltt_transport_register(<t_relay_transport); - return 0; -} - -module_init(ltt_ring_buffer_client_init); - -static void __exit ltt_ring_buffer_client_exit(void) -{ - ltt_transport_unregister(<t_relay_transport); -} - -module_exit(ltt_ring_buffer_client_exit); - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING - " client"); diff --git a/ltt-ring-buffer-metadata-mmap-client.c b/ltt-ring-buffer-metadata-mmap-client.c deleted file mode 100644 index 5cad3f92..00000000 --- a/ltt-ring-buffer-metadata-mmap-client.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * ltt-ring-buffer-metadata-client.c - * - * Copyright (C) 2010 - Mathieu Desnoyers - * - * LTTng lib ring buffer metadta client. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include "ltt-tracer.h" - -#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD -#define RING_BUFFER_MODE_TEMPLATE_STRING "metadata-mmap" -#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP -#include "ltt-ring-buffer-metadata-client.h" - -MODULE_LICENSE("GPL and additional rights"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client"); diff --git a/ltt-tracer-core.h b/ltt-tracer-core.h deleted file mode 100644 index 5abc432d..00000000 --- a/ltt-tracer-core.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LTT_TRACER_CORE_H -#define LTT_TRACER_CORE_H - -/* - * ltt-tracer-core.h - * - * Copyright (C) 2005-2011 Mathieu Desnoyers - * - * This contains the core definitions for the Linux Trace Toolkit. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include - -#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS -/* Align data on its natural alignment */ -#define RING_BUFFER_ALIGN -#endif - -#include "wrapper/ringbuffer/config.h" - -struct ltt_session; -struct ltt_channel; -struct ltt_event; - -#endif /* LTT_TRACER_CORE_H */ diff --git a/ltt-tracer.h b/ltt-tracer.h deleted file mode 100644 index a21c38ca..00000000 --- a/ltt-tracer.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _LTT_TRACER_H -#define _LTT_TRACER_H - -/* - * ltt-tracer.h - * - * Copyright (C) 2005-2011 Mathieu Desnoyers - * - * This contains the definitions for the Linux Trace Toolkit tracer. - * - * Dual LGPL v2.1/GPL v2 license. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wrapper/trace-clock.h" -#include "ltt-tracer-core.h" -#include "ltt-events.h" - -#define LTTNG_VERSION 0 -#define LTTNG_PATCHLEVEL 9 -#define LTTNG_SUBLEVEL 1 - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -/* Number of bytes to log with a read/write event */ -#define LTT_LOG_RW_SIZE 32L -#define LTT_MAX_SMALL_SIZE 0xFFFFU - -#ifdef RING_BUFFER_ALIGN -#define ltt_alignof(type) __alignof__(type) -#else -#define ltt_alignof(type) 1 -#endif - -/* Tracer properties */ -#define CTF_MAGIC_NUMBER 0xC1FC1FC1 -#define TSDL_MAGIC_NUMBER 0x75D11D57 - -/* CTF specification version followed */ -#define CTF_SPEC_MAJOR 1 -#define CTF_SPEC_MINOR 8 - -/* Tracer major/minor versions */ -#define CTF_VERSION_MAJOR 0 -#define CTF_VERSION_MINOR 1 - -/* - * Number of milliseconds to retry before failing metadata writes on buffer full - * condition. (10 seconds) - */ -#define LTTNG_METADATA_TIMEOUT_MSEC 10000 - -#define LTT_RFLAG_EXTENDED RING_BUFFER_RFLAG_END -#define LTT_RFLAG_END (LTT_RFLAG_EXTENDED << 1) - -#endif /* _LTT_TRACER_H */ diff --git a/lttng-abi.c b/lttng-abi.c index ec16b7fc..d15e3f83 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -34,8 +34,8 @@ #include "wrapper/ringbuffer/vfs.h" #include "wrapper/poll.h" #include "lttng-abi.h" -#include "ltt-events.h" -#include "ltt-tracer.h" +#include "lttng-events.h" +#include "lttng-tracer.h" /* * This is LTTng's own personal way to create a system call as an external @@ -62,11 +62,11 @@ enum channel_type { static int lttng_abi_create_session(void) { - struct ltt_session *session; + struct lttng_session *session; struct file *session_file; int session_fd, ret; - session = ltt_session_create(); + session = lttng_session_create(); if (!session) return -ENOMEM; session_fd = get_unused_fd(); @@ -88,7 +88,7 @@ int lttng_abi_create_session(void) file_error: put_unused_fd(session_fd); fd_error: - ltt_session_destroy(session); + lttng_session_destroy(session); return ret; } @@ -147,7 +147,7 @@ long lttng_abi_tracer_version(struct file *file, static long lttng_abi_add_context(struct file *file, struct lttng_kernel_context __user *ucontext_param, - struct lttng_ctx **ctx, struct ltt_session *session) + struct lttng_ctx **ctx, struct lttng_session *session) { struct lttng_kernel_context context_param; @@ -255,18 +255,18 @@ static const struct file_operations lttng_fops = { static void lttng_metadata_create_events(struct file *channel_file) { - struct ltt_channel *channel = channel_file->private_data; + struct lttng_channel *channel = channel_file->private_data; static struct lttng_kernel_event metadata_params = { .instrumentation = LTTNG_KERNEL_TRACEPOINT, .name = "lttng_metadata", }; - struct ltt_event *event; + struct lttng_event *event; /* * We tolerate no failure path after event creation. It will stay * invariant for the rest of the session. */ - event = ltt_event_create(channel, &metadata_params, NULL, NULL); + event = lttng_event_create(channel, &metadata_params, NULL, NULL); if (!event) { goto create_error; } @@ -282,10 +282,10 @@ int lttng_abi_create_channel(struct file *session_file, struct lttng_kernel_channel __user *uchan_param, enum channel_type channel_type) { - struct ltt_session *session = session_file->private_data; + struct lttng_session *session = session_file->private_data; const struct file_operations *fops = NULL; const char *transport_name; - struct ltt_channel *chan; + struct lttng_channel *chan; struct file *chan_file; struct lttng_kernel_channel chan_param; int chan_fd; @@ -342,7 +342,7 @@ int lttng_abi_create_channel(struct file *session_file, * We tolerate no failure path after channel creation. It will stay * invariant for the rest of the session. */ - chan = ltt_channel_create(session, transport_name, NULL, + chan = lttng_channel_create(session, transport_name, NULL, chan_param.subbuf_size, chan_param.num_subbuf, chan_param.switch_timer_interval, @@ -394,7 +394,7 @@ fd_error: static long lttng_session_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct ltt_session *session = file->private_data; + struct lttng_session *session = file->private_data; switch (cmd) { case LTTNG_KERNEL_CHANNEL: @@ -403,10 +403,10 @@ long lttng_session_ioctl(struct file *file, unsigned int cmd, unsigned long arg) PER_CPU_CHANNEL); case LTTNG_KERNEL_SESSION_START: case LTTNG_KERNEL_ENABLE: - return ltt_session_enable(session); + return lttng_session_enable(session); case LTTNG_KERNEL_SESSION_STOP: case LTTNG_KERNEL_DISABLE: - return ltt_session_disable(session); + return lttng_session_disable(session); case LTTNG_KERNEL_METADATA: return lttng_abi_create_channel(file, (struct lttng_kernel_channel __user *) arg, @@ -427,10 +427,10 @@ long lttng_session_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static int lttng_session_release(struct inode *inode, struct file *file) { - struct ltt_session *session = file->private_data; + struct lttng_session *session = file->private_data; if (session) - ltt_session_destroy(session); + lttng_session_destroy(session); return 0; } @@ -446,7 +446,7 @@ static const struct file_operations lttng_session_fops = { static int lttng_abi_open_stream(struct file *channel_file) { - struct ltt_channel *channel = channel_file->private_data; + struct lttng_channel *channel = channel_file->private_data; struct lib_ring_buffer *buf; int stream_fd, ret; struct file *stream_file; @@ -492,8 +492,8 @@ static int lttng_abi_create_event(struct file *channel_file, struct lttng_kernel_event __user *uevent_param) { - struct ltt_channel *channel = channel_file->private_data; - struct ltt_event *event; + struct lttng_channel *channel = channel_file->private_data; + struct lttng_event *event; struct lttng_kernel_event event_param; int event_fd, ret; struct file *event_file; @@ -532,7 +532,7 @@ int lttng_abi_create_event(struct file *channel_file, * We tolerate no failure path after event creation. It * will stay invariant for the rest of the session. */ - event = ltt_event_create(channel, &event_param, NULL, NULL); + event = lttng_event_create(channel, &event_param, NULL, NULL); if (!event) { ret = -EINVAL; goto event_error; @@ -589,7 +589,7 @@ fd_error: static long lttng_channel_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct ltt_channel *channel = file->private_data; + struct lttng_channel *channel = file->private_data; switch (cmd) { case LTTNG_KERNEL_STREAM: @@ -601,9 +601,9 @@ long lttng_channel_ioctl(struct file *file, unsigned int cmd, unsigned long arg) (struct lttng_kernel_context __user *) arg, &channel->ctx, channel->session); case LTTNG_KERNEL_ENABLE: - return ltt_channel_enable(channel); + return lttng_channel_enable(channel); case LTTNG_KERNEL_DISABLE: - return ltt_channel_disable(channel); + return lttng_channel_disable(channel); default: return -ENOIOCTLCMD; } @@ -641,7 +641,7 @@ long lttng_metadata_ioctl(struct file *file, unsigned int cmd, unsigned long arg */ unsigned int lttng_channel_poll(struct file *file, poll_table *wait) { - struct ltt_channel *channel = file->private_data; + struct lttng_channel *channel = file->private_data; unsigned int mask = 0; if (file->f_mode & FMODE_READ) { @@ -664,7 +664,7 @@ unsigned int lttng_channel_poll(struct file *file, poll_table *wait) static int lttng_channel_release(struct inode *inode, struct file *file) { - struct ltt_channel *channel = file->private_data; + struct lttng_channel *channel = file->private_data; if (channel) fput(channel->session->file); @@ -708,7 +708,7 @@ static const struct file_operations lttng_metadata_fops = { static long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct ltt_event *event = file->private_data; + struct lttng_event *event = file->private_data; switch (cmd) { case LTTNG_KERNEL_CONTEXT: @@ -716,9 +716,9 @@ long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg) (struct lttng_kernel_context __user *) arg, &event->ctx, event->chan->session); case LTTNG_KERNEL_ENABLE: - return ltt_event_enable(event); + return lttng_event_enable(event); case LTTNG_KERNEL_DISABLE: - return ltt_event_disable(event); + return lttng_event_disable(event); default: return -ENOIOCTLCMD; } @@ -727,7 +727,7 @@ long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static int lttng_event_release(struct inode *inode, struct file *file) { - struct ltt_event *event = file->private_data; + struct lttng_event *event = file->private_data; if (event) fput(event->chan->file); diff --git a/lttng-calibrate.c b/lttng-calibrate.c index 1fe3a690..f2362fb2 100644 --- a/lttng-calibrate.c +++ b/lttng-calibrate.c @@ -9,7 +9,7 @@ */ #include "lttng-abi.h" -#include "ltt-events.h" +#include "lttng-events.h" noinline void lttng_calibrate_kretprobe(void) diff --git a/lttng-context-nice.c b/lttng-context-nice.c index 9b99b549..ca391e31 100644 --- a/lttng-context-nice.c +++ b/lttng-context-nice.c @@ -10,17 +10,17 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t nice_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(int)); + size += lib_ring_buffer_align(offset, lttng_alignof(int)); size += sizeof(int); return size; } @@ -28,12 +28,12 @@ size_t nice_get_size(size_t offset) static void nice_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { int nice; nice = task_nice(current); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(nice)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(nice)); chan->ops->event_write(ctx, &nice, sizeof(nice)); } @@ -51,7 +51,7 @@ int lttng_add_nice_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "nice"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(int) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(int) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(int); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-perf-counters.c b/lttng-context-perf-counters.c index 3ae2266f..444c2f92 100644 --- a/lttng-context-perf-counters.c +++ b/lttng-context-perf-counters.c @@ -12,18 +12,18 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" #include "wrapper/perf.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t perf_counter_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); + size += lib_ring_buffer_align(offset, lttng_alignof(uint64_t)); size += sizeof(uint64_t); return size; } @@ -31,7 +31,7 @@ size_t perf_counter_get_size(size_t offset) static void perf_counter_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { struct perf_event *event; uint64_t value; @@ -54,7 +54,7 @@ void perf_counter_record(struct lttng_ctx_field *field, */ value = 0; } - lib_ring_buffer_align_ctx(ctx, ltt_alignof(value)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(value)); chan->ops->event_write(ctx, &value, sizeof(value)); } @@ -230,7 +230,7 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, field->event_field.name = name_alloc; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(uint64_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(uint64_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(uint64_t) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(uint64_t); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-pid.c b/lttng-context-pid.c index 698b2422..f548e3c6 100644 --- a/lttng-context-pid.c +++ b/lttng-context-pid.c @@ -10,17 +10,17 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t pid_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += lib_ring_buffer_align(offset, lttng_alignof(pid_t)); size += sizeof(pid_t); return size; } @@ -28,12 +28,12 @@ size_t pid_get_size(size_t offset) static void pid_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { pid_t pid; pid = task_tgid_nr(current); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(pid)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(pid)); chan->ops->event_write(ctx, &pid, sizeof(pid)); } @@ -51,7 +51,7 @@ int lttng_add_pid_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "pid"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-ppid.c b/lttng-context-ppid.c index 738f7e68..aaa334bc 100644 --- a/lttng-context-ppid.c +++ b/lttng-context-ppid.c @@ -11,17 +11,17 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t ppid_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += lib_ring_buffer_align(offset, lttng_alignof(pid_t)); size += sizeof(pid_t); return size; } @@ -29,14 +29,14 @@ size_t ppid_get_size(size_t offset) static void ppid_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { pid_t ppid; rcu_read_lock(); ppid = task_tgid_nr(current->real_parent); rcu_read_unlock(); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(ppid)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(ppid)); chan->ops->event_write(ctx, &ppid, sizeof(ppid)); } @@ -54,7 +54,7 @@ int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "ppid"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-prio.c b/lttng-context-prio.c index 1ee3a54d..fee0dc14 100644 --- a/lttng-context-prio.c +++ b/lttng-context-prio.c @@ -10,11 +10,11 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" #include "wrapper/kallsyms.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static int (*wrapper_task_prio_sym)(struct task_struct *t); @@ -34,7 +34,7 @@ size_t prio_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(int)); + size += lib_ring_buffer_align(offset, lttng_alignof(int)); size += sizeof(int); return size; } @@ -42,12 +42,12 @@ size_t prio_get_size(size_t offset) static void prio_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { int prio; prio = wrapper_task_prio_sym(current); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(prio)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(prio)); chan->ops->event_write(ctx, &prio, sizeof(prio)); } @@ -72,7 +72,7 @@ int lttng_add_prio_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "prio"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(int) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(int) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(int); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-procname.c b/lttng-context-procname.c index c6bc6468..e214bff7 100644 --- a/lttng-context-procname.c +++ b/lttng-context-procname.c @@ -10,10 +10,10 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t procname_get_size(size_t offset) @@ -33,7 +33,7 @@ size_t procname_get_size(size_t offset) static void procname_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { chan->ops->event_write(ctx, current->comm, sizeof(current->comm)); } @@ -53,7 +53,7 @@ int lttng_add_procname_to_ctx(struct lttng_ctx **ctx) field->event_field.type.atype = atype_array; field->event_field.type.u.array.elem_type.atype = atype_integer; field->event_field.type.u.array.elem_type.u.basic.integer.size = sizeof(char) * CHAR_BIT; - field->event_field.type.u.array.elem_type.u.basic.integer.alignment = ltt_alignof(char) * CHAR_BIT; + field->event_field.type.u.array.elem_type.u.basic.integer.alignment = lttng_alignof(char) * CHAR_BIT; field->event_field.type.u.array.elem_type.u.basic.integer.signedness = is_signed_type(char); field->event_field.type.u.array.elem_type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.array.elem_type.u.basic.integer.base = 10; diff --git a/lttng-context-tid.c b/lttng-context-tid.c index d5ccdb63..af59d7b8 100644 --- a/lttng-context-tid.c +++ b/lttng-context-tid.c @@ -10,17 +10,17 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t tid_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += lib_ring_buffer_align(offset, lttng_alignof(pid_t)); size += sizeof(pid_t); return size; } @@ -28,12 +28,12 @@ size_t tid_get_size(size_t offset) static void tid_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { pid_t tid; tid = task_pid_nr(current); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(tid)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(tid)); chan->ops->event_write(ctx, &tid, sizeof(tid)); } @@ -51,7 +51,7 @@ int lttng_add_tid_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "tid"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-vpid.c b/lttng-context-vpid.c index 3f16e03a..4f3c8a6a 100644 --- a/lttng-context-vpid.c +++ b/lttng-context-vpid.c @@ -10,17 +10,17 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t vpid_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += lib_ring_buffer_align(offset, lttng_alignof(pid_t)); size += sizeof(pid_t); return size; } @@ -28,7 +28,7 @@ size_t vpid_get_size(size_t offset) static void vpid_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { pid_t vpid; @@ -39,7 +39,7 @@ void vpid_record(struct lttng_ctx_field *field, vpid = 0; else vpid = task_tgid_vnr(current); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(vpid)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(vpid)); chan->ops->event_write(ctx, &vpid, sizeof(vpid)); } @@ -57,7 +57,7 @@ int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "vpid"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-vppid.c b/lttng-context-vppid.c index f01b0206..2fe2ffd1 100644 --- a/lttng-context-vppid.c +++ b/lttng-context-vppid.c @@ -11,17 +11,17 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t vppid_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += lib_ring_buffer_align(offset, lttng_alignof(pid_t)); size += sizeof(pid_t); return size; } @@ -29,7 +29,7 @@ size_t vppid_get_size(size_t offset) static void vppid_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { struct task_struct *parent; pid_t vppid; @@ -44,7 +44,7 @@ void vppid_record(struct lttng_ctx_field *field, else vppid = task_tgid_vnr(parent); rcu_read_unlock(); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(vppid)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(vppid)); chan->ops->event_write(ctx, &vppid, sizeof(vppid)); } @@ -62,7 +62,7 @@ int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "vppid"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context-vtid.c b/lttng-context-vtid.c index 264bbb30..3dd34ae3 100644 --- a/lttng-context-vtid.c +++ b/lttng-context-vtid.c @@ -10,17 +10,17 @@ #include #include #include -#include "ltt-events.h" +#include "lttng-events.h" #include "wrapper/ringbuffer/frontend_types.h" #include "wrapper/vmalloc.h" -#include "ltt-tracer.h" +#include "lttng-tracer.h" static size_t vtid_get_size(size_t offset) { size_t size = 0; - size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += lib_ring_buffer_align(offset, lttng_alignof(pid_t)); size += sizeof(pid_t); return size; } @@ -28,7 +28,7 @@ size_t vtid_get_size(size_t offset) static void vtid_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, - struct ltt_channel *chan) + struct lttng_channel *chan) { pid_t vtid; @@ -39,7 +39,7 @@ void vtid_record(struct lttng_ctx_field *field, vtid = 0; else vtid = task_pid_vnr(current); - lib_ring_buffer_align_ctx(ctx, ltt_alignof(vtid)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(vtid)); chan->ops->event_write(ctx, &vtid, sizeof(vtid)); } @@ -57,7 +57,7 @@ int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx) field->event_field.name = "vtid"; field->event_field.type.atype = atype_integer; field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); field->event_field.type.u.basic.integer.reverse_byte_order = 0; field->event_field.type.u.basic.integer.base = 10; diff --git a/lttng-context.c b/lttng-context.c new file mode 100644 index 00000000..a28a9d23 --- /dev/null +++ b/lttng-context.c @@ -0,0 +1,93 @@ +/* + * lttng-context.c + * + * Copyright 2011 (c) - Mathieu Desnoyers + * + * LTTng trace/channel/event context management. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include +#include +#include +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "lttng-events.h" +#include "lttng-tracer.h" + +int lttng_find_context(struct lttng_ctx *ctx, const char *name) +{ + unsigned int i; + + for (i = 0; i < ctx->nr_fields; i++) { + /* Skip allocated (but non-initialized) contexts */ + if (!ctx->fields[i].event_field.name) + continue; + if (!strcmp(ctx->fields[i].event_field.name, name)) + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(lttng_find_context); + +/* + * Note: as we append context information, the pointer location may change. + */ +struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx_p) +{ + struct lttng_ctx_field *field; + struct lttng_ctx *ctx; + + if (!*ctx_p) { + *ctx_p = kzalloc(sizeof(struct lttng_ctx), GFP_KERNEL); + if (!*ctx_p) + return NULL; + } + ctx = *ctx_p; + if (ctx->nr_fields + 1 > ctx->allocated_fields) { + struct lttng_ctx_field *new_fields; + + ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields); + new_fields = kzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL); + if (!new_fields) + return NULL; + if (ctx->fields) + memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields); + kfree(ctx->fields); + ctx->fields = new_fields; + } + field = &ctx->fields[ctx->nr_fields]; + ctx->nr_fields++; + return field; +} +EXPORT_SYMBOL_GPL(lttng_append_context); + +/* + * Remove last context field. + */ +void lttng_remove_context_field(struct lttng_ctx **ctx_p, + struct lttng_ctx_field *field) +{ + struct lttng_ctx *ctx; + + ctx = *ctx_p; + ctx->nr_fields--; + WARN_ON_ONCE(&ctx->fields[ctx->nr_fields] != field); + memset(&ctx->fields[ctx->nr_fields], 0, sizeof(struct lttng_ctx_field)); +} +EXPORT_SYMBOL_GPL(lttng_remove_context_field); + +void lttng_destroy_context(struct lttng_ctx *ctx) +{ + int i; + + if (!ctx) + return; + for (i = 0; i < ctx->nr_fields; i++) { + if (ctx->fields[i].destroy) + ctx->fields[i].destroy(&ctx->fields[i]); + } + kfree(ctx->fields); + kfree(ctx); +} diff --git a/lttng-endian.h b/lttng-endian.h new file mode 100644 index 00000000..e86dab7f --- /dev/null +++ b/lttng-endian.h @@ -0,0 +1,31 @@ +#ifndef _LTTNG_ENDIAN_H +#define _LTTNG_ENDIAN_H + +/* + * lttng-endian.h + * + * Copyright 2010-2011 (c) - Mathieu Desnoyers + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#ifdef __KERNEL__ +# include +# ifdef __BIG_ENDIAN +# define __BYTE_ORDER __BIG_ENDIAN +# elif defined(__LITTLE_ENDIAN) +# define __BYTE_ORDER __LITTLE_ENDIAN +# else +# error "unknown endianness" +# endif +#ifndef __BIG_ENDIAN +# define __BIG_ENDIAN 4321 +#endif +#ifndef __LITTLE_ENDIAN +# define __LITTLE_ENDIAN 1234 +#endif +#else +# include +#endif + +#endif /* _LTTNG_ENDIAN_H */ diff --git a/lttng-events.c b/lttng-events.c new file mode 100644 index 00000000..0ef87a8c --- /dev/null +++ b/lttng-events.c @@ -0,0 +1,1009 @@ +/* + * lttng-events.c + * + * Copyright 2010-2011 (c) - Mathieu Desnoyers + * + * Holds LTTng per-session event registry. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include +#include +#include +#include +#include +#include "wrapper/uuid.h" +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "lttng-events.h" +#include "lttng-tracer.h" + +static LIST_HEAD(sessions); +static LIST_HEAD(lttng_transport_list); +static DEFINE_MUTEX(sessions_mutex); +static struct kmem_cache *event_cache; + +static void _lttng_event_destroy(struct lttng_event *event); +static void _lttng_channel_destroy(struct lttng_channel *chan); +static int _lttng_event_unregister(struct lttng_event *event); +static +int _lttng_event_metadata_statedump(struct lttng_session *session, + struct lttng_channel *chan, + struct lttng_event *event); +static +int _lttng_session_metadata_statedump(struct lttng_session *session); + +void synchronize_trace(void) +{ + synchronize_sched(); +#ifdef CONFIG_PREEMPT_RT + synchronize_rcu(); +#endif +} + +struct lttng_session *lttng_session_create(void) +{ + struct lttng_session *session; + + mutex_lock(&sessions_mutex); + session = kzalloc(sizeof(struct lttng_session), GFP_KERNEL); + if (!session) + return NULL; + INIT_LIST_HEAD(&session->chan); + INIT_LIST_HEAD(&session->events); + uuid_le_gen(&session->uuid); + list_add(&session->list, &sessions); + mutex_unlock(&sessions_mutex); + return session; +} + +void lttng_session_destroy(struct lttng_session *session) +{ + struct lttng_channel *chan, *tmpchan; + struct lttng_event *event, *tmpevent; + int ret; + + mutex_lock(&sessions_mutex); + ACCESS_ONCE(session->active) = 0; + list_for_each_entry(chan, &session->chan, list) { + ret = lttng_syscalls_unregister(chan); + WARN_ON(ret); + } + list_for_each_entry(event, &session->events, list) { + ret = _lttng_event_unregister(event); + WARN_ON(ret); + } + synchronize_trace(); /* Wait for in-flight events to complete */ + list_for_each_entry_safe(event, tmpevent, &session->events, list) + _lttng_event_destroy(event); + list_for_each_entry_safe(chan, tmpchan, &session->chan, list) + _lttng_channel_destroy(chan); + list_del(&session->list); + mutex_unlock(&sessions_mutex); + kfree(session); +} + +int lttng_session_enable(struct lttng_session *session) +{ + int ret = 0; + struct lttng_channel *chan; + + mutex_lock(&sessions_mutex); + if (session->active) { + ret = -EBUSY; + goto end; + } + + /* + * Snapshot the number of events per channel to know the type of header + * we need to use. + */ + list_for_each_entry(chan, &session->chan, list) { + if (chan->header_type) + continue; /* don't change it if session stop/restart */ + if (chan->free_event_id < 31) + chan->header_type = 1; /* compact */ + else + chan->header_type = 2; /* large */ + } + + ACCESS_ONCE(session->active) = 1; + ACCESS_ONCE(session->been_active) = 1; + ret = _lttng_session_metadata_statedump(session); + if (ret) + ACCESS_ONCE(session->active) = 0; +end: + mutex_unlock(&sessions_mutex); + return ret; +} + +int lttng_session_disable(struct lttng_session *session) +{ + int ret = 0; + + mutex_lock(&sessions_mutex); + if (!session->active) { + ret = -EBUSY; + goto end; + } + ACCESS_ONCE(session->active) = 0; +end: + mutex_unlock(&sessions_mutex); + return ret; +} + +int lttng_channel_enable(struct lttng_channel *channel) +{ + int old; + + if (channel == channel->session->metadata) + return -EPERM; + old = xchg(&channel->enabled, 1); + if (old) + return -EEXIST; + return 0; +} + +int lttng_channel_disable(struct lttng_channel *channel) +{ + int old; + + if (channel == channel->session->metadata) + return -EPERM; + old = xchg(&channel->enabled, 0); + if (!old) + return -EEXIST; + return 0; +} + +int lttng_event_enable(struct lttng_event *event) +{ + int old; + + if (event->chan == event->chan->session->metadata) + return -EPERM; + old = xchg(&event->enabled, 1); + if (old) + return -EEXIST; + return 0; +} + +int lttng_event_disable(struct lttng_event *event) +{ + int old; + + if (event->chan == event->chan->session->metadata) + return -EPERM; + old = xchg(&event->enabled, 0); + if (!old) + return -EEXIST; + return 0; +} + +static struct lttng_transport *lttng_transport_find(const char *name) +{ + struct lttng_transport *transport; + + list_for_each_entry(transport, <tng_transport_list, node) { + if (!strcmp(transport->name, name)) + return transport; + } + return NULL; +} + +struct lttng_channel *lttng_channel_create(struct lttng_session *session, + const char *transport_name, + void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval) +{ + struct lttng_channel *chan; + struct lttng_transport *transport = NULL; + + mutex_lock(&sessions_mutex); + if (session->been_active) + goto active; /* Refuse to add channel to active session */ + transport = lttng_transport_find(transport_name); + if (!transport) { + printk(KERN_WARNING "LTTng transport %s not found\n", + transport_name); + goto notransport; + } + if (!try_module_get(transport->owner)) { + printk(KERN_WARNING "LTT : Can't lock transport module.\n"); + goto notransport; + } + chan = kzalloc(sizeof(struct lttng_channel), GFP_KERNEL); + if (!chan) + goto nomem; + chan->session = session; + chan->id = session->free_chan_id++; + /* + * Note: the channel creation op already writes into the packet + * headers. Therefore the "chan" information used as input + * should be already accessible. + */ + chan->chan = transport->ops.channel_create("[lttng]", chan, buf_addr, + subbuf_size, num_subbuf, switch_timer_interval, + read_timer_interval); + if (!chan->chan) + goto create_error; + chan->enabled = 1; + chan->ops = &transport->ops; + chan->transport = transport; + list_add(&chan->list, &session->chan); + mutex_unlock(&sessions_mutex); + return chan; + +create_error: + kfree(chan); +nomem: + if (transport) + module_put(transport->owner); +notransport: +active: + mutex_unlock(&sessions_mutex); + return NULL; +} + +/* + * Only used internally at session destruction. + */ +static +void _lttng_channel_destroy(struct lttng_channel *chan) +{ + chan->ops->channel_destroy(chan->chan); + module_put(chan->transport->owner); + list_del(&chan->list); + lttng_destroy_context(chan->ctx); + kfree(chan); +} + +/* + * Supports event creation while tracing session is active. + */ +struct lttng_event *lttng_event_create(struct lttng_channel *chan, + struct lttng_kernel_event *event_param, + void *filter, + const struct lttng_event_desc *internal_desc) +{ + struct lttng_event *event; + int ret; + + mutex_lock(&sessions_mutex); + if (chan->free_event_id == -1UL) + goto full; + /* + * This is O(n^2) (for each event, the loop is called at event + * creation). Might require a hash if we have lots of events. + */ + list_for_each_entry(event, &chan->session->events, list) + if (!strcmp(event->desc->name, event_param->name)) + goto exist; + event = kmem_cache_zalloc(event_cache, GFP_KERNEL); + if (!event) + goto cache_error; + event->chan = chan; + event->filter = filter; + event->id = chan->free_event_id++; + event->enabled = 1; + event->instrumentation = event_param->instrumentation; + /* Populate lttng_event structure before tracepoint registration. */ + smp_wmb(); + switch (event_param->instrumentation) { + case LTTNG_KERNEL_TRACEPOINT: + event->desc = lttng_event_get(event_param->name); + if (!event->desc) + goto register_error; + ret = tracepoint_probe_register(event_param->name, + event->desc->probe_callback, + event); + if (ret) + goto register_error; + break; + case LTTNG_KERNEL_KPROBE: + ret = lttng_kprobes_register(event_param->name, + event_param->u.kprobe.symbol_name, + event_param->u.kprobe.offset, + event_param->u.kprobe.addr, + event); + if (ret) + goto register_error; + ret = try_module_get(event->desc->owner); + WARN_ON_ONCE(!ret); + break; + case LTTNG_KERNEL_KRETPROBE: + { + struct lttng_event *event_return; + + /* kretprobe defines 2 events */ + event_return = + kmem_cache_zalloc(event_cache, GFP_KERNEL); + if (!event_return) + goto register_error; + event_return->chan = chan; + event_return->filter = filter; + event_return->id = chan->free_event_id++; + event_return->enabled = 1; + event_return->instrumentation = event_param->instrumentation; + /* + * Populate lttng_event structure before kretprobe registration. + */ + smp_wmb(); + ret = lttng_kretprobes_register(event_param->name, + event_param->u.kretprobe.symbol_name, + event_param->u.kretprobe.offset, + event_param->u.kretprobe.addr, + event, event_return); + if (ret) { + kmem_cache_free(event_cache, event_return); + goto register_error; + } + /* Take 2 refs on the module: one per event. */ + ret = try_module_get(event->desc->owner); + WARN_ON_ONCE(!ret); + ret = try_module_get(event->desc->owner); + WARN_ON_ONCE(!ret); + ret = _lttng_event_metadata_statedump(chan->session, chan, + event_return); + if (ret) { + kmem_cache_free(event_cache, event_return); + module_put(event->desc->owner); + module_put(event->desc->owner); + goto statedump_error; + } + list_add(&event_return->list, &chan->session->events); + break; + } + case LTTNG_KERNEL_FUNCTION: + ret = lttng_ftrace_register(event_param->name, + event_param->u.ftrace.symbol_name, + event); + if (ret) + goto register_error; + ret = try_module_get(event->desc->owner); + WARN_ON_ONCE(!ret); + break; + case LTTNG_KERNEL_NOOP: + event->desc = internal_desc; + if (!event->desc) + goto register_error; + break; + default: + WARN_ON_ONCE(1); + } + ret = _lttng_event_metadata_statedump(chan->session, chan, event); + if (ret) + goto statedump_error; + list_add(&event->list, &chan->session->events); + mutex_unlock(&sessions_mutex); + return event; + +statedump_error: + /* If a statedump error occurs, events will not be readable. */ +register_error: + kmem_cache_free(event_cache, event); +cache_error: +exist: +full: + mutex_unlock(&sessions_mutex); + return NULL; +} + +/* + * Only used internally at session destruction. + */ +int _lttng_event_unregister(struct lttng_event *event) +{ + int ret = -EINVAL; + + switch (event->instrumentation) { + case LTTNG_KERNEL_TRACEPOINT: + ret = tracepoint_probe_unregister(event->desc->name, + event->desc->probe_callback, + event); + if (ret) + return ret; + break; + case LTTNG_KERNEL_KPROBE: + lttng_kprobes_unregister(event); + ret = 0; + break; + case LTTNG_KERNEL_KRETPROBE: + lttng_kretprobes_unregister(event); + ret = 0; + break; + case LTTNG_KERNEL_FUNCTION: + lttng_ftrace_unregister(event); + ret = 0; + break; + case LTTNG_KERNEL_NOOP: + ret = 0; + break; + default: + WARN_ON_ONCE(1); + } + return ret; +} + +/* + * Only used internally at session destruction. + */ +static +void _lttng_event_destroy(struct lttng_event *event) +{ + switch (event->instrumentation) { + case LTTNG_KERNEL_TRACEPOINT: + lttng_event_put(event->desc); + break; + case LTTNG_KERNEL_KPROBE: + module_put(event->desc->owner); + lttng_kprobes_destroy_private(event); + break; + case LTTNG_KERNEL_KRETPROBE: + module_put(event->desc->owner); + lttng_kretprobes_destroy_private(event); + break; + case LTTNG_KERNEL_FUNCTION: + module_put(event->desc->owner); + lttng_ftrace_destroy_private(event); + break; + case LTTNG_KERNEL_NOOP: + break; + default: + WARN_ON_ONCE(1); + } + list_del(&event->list); + lttng_destroy_context(event->ctx); + kmem_cache_free(event_cache, event); +} + +/* + * We have exclusive access to our metadata buffer (protected by the + * sessions_mutex), so we can do racy operations such as looking for + * remaining space left in packet and write, since mutual exclusion + * protects us from concurrent writes. + */ +int lttng_metadata_printf(struct lttng_session *session, + const char *fmt, ...) +{ + struct lib_ring_buffer_ctx ctx; + struct lttng_channel *chan = session->metadata; + char *str; + int ret = 0, waitret; + size_t len, reserve_len, pos; + va_list ap; + + WARN_ON_ONCE(!ACCESS_ONCE(session->active)); + + va_start(ap, fmt); + str = kvasprintf(GFP_KERNEL, fmt, ap); + va_end(ap); + if (!str) + return -ENOMEM; + + len = strlen(str); + pos = 0; + + for (pos = 0; pos < len; pos += reserve_len) { + reserve_len = min_t(size_t, + chan->ops->packet_avail_size(chan->chan), + len - pos); + lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len, + sizeof(char), -1); + /* + * We don't care about metadata buffer's records lost + * count, because we always retry here. Report error if + * we need to bail out after timeout or being + * interrupted. + */ + waitret = wait_event_interruptible_timeout(*chan->ops->get_writer_buf_wait_queue(chan->chan, -1), + ({ + ret = chan->ops->event_reserve(&ctx, 0); + ret != -ENOBUFS || !ret; + }), + msecs_to_jiffies(LTTNG_METADATA_TIMEOUT_MSEC)); + if (!waitret || waitret == -ERESTARTSYS || ret) { + printk(KERN_WARNING "LTTng: Failure to write metadata to buffers (%s)\n", + waitret == -ERESTARTSYS ? "interrupted" : + (ret == -ENOBUFS ? "timeout" : "I/O error")); + if (waitret == -ERESTARTSYS) + ret = waitret; + goto end; + } + chan->ops->event_write(&ctx, &str[pos], reserve_len); + chan->ops->event_commit(&ctx); + } +end: + kfree(str); + return ret; +} + +static +int _lttng_field_statedump(struct lttng_session *session, + const struct lttng_event_field *field) +{ + int ret = 0; + + switch (field->type.atype) { + case atype_integer: + ret = lttng_metadata_printf(session, + " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n", + field->type.u.basic.integer.size, + field->type.u.basic.integer.alignment, + field->type.u.basic.integer.signedness, + (field->type.u.basic.integer.encoding == lttng_encode_none) + ? "none" + : (field->type.u.basic.integer.encoding == lttng_encode_UTF8) + ? "UTF8" + : "ASCII", + field->type.u.basic.integer.base, +#ifdef __BIG_ENDIAN + field->type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", +#else + field->type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", +#endif + field->name); + break; + case atype_enum: + ret = lttng_metadata_printf(session, + " %s _%s;\n", + field->type.u.basic.enumeration.name, + field->name); + break; + case atype_array: + { + const struct lttng_basic_type *elem_type; + + elem_type = &field->type.u.array.elem_type; + ret = lttng_metadata_printf(session, + " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n", + elem_type->u.basic.integer.size, + elem_type->u.basic.integer.alignment, + elem_type->u.basic.integer.signedness, + (elem_type->u.basic.integer.encoding == lttng_encode_none) + ? "none" + : (elem_type->u.basic.integer.encoding == lttng_encode_UTF8) + ? "UTF8" + : "ASCII", + elem_type->u.basic.integer.base, +#ifdef __BIG_ENDIAN + elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", +#else + elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", +#endif + field->name, field->type.u.array.length); + break; + } + case atype_sequence: + { + const struct lttng_basic_type *elem_type; + const struct lttng_basic_type *length_type; + + elem_type = &field->type.u.sequence.elem_type; + length_type = &field->type.u.sequence.length_type; + ret = lttng_metadata_printf(session, + " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n", + length_type->u.basic.integer.size, + (unsigned int) length_type->u.basic.integer.alignment, + length_type->u.basic.integer.signedness, + (length_type->u.basic.integer.encoding == lttng_encode_none) + ? "none" + : ((length_type->u.basic.integer.encoding == lttng_encode_UTF8) + ? "UTF8" + : "ASCII"), + length_type->u.basic.integer.base, +#ifdef __BIG_ENDIAN + length_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", +#else + length_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", +#endif + field->name); + if (ret) + return ret; + + ret = lttng_metadata_printf(session, + " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n", + elem_type->u.basic.integer.size, + (unsigned int) elem_type->u.basic.integer.alignment, + elem_type->u.basic.integer.signedness, + (elem_type->u.basic.integer.encoding == lttng_encode_none) + ? "none" + : ((elem_type->u.basic.integer.encoding == lttng_encode_UTF8) + ? "UTF8" + : "ASCII"), + elem_type->u.basic.integer.base, +#ifdef __BIG_ENDIAN + elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "", +#else + elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "", +#endif + field->name, + field->name); + break; + } + + case atype_string: + /* Default encoding is UTF8 */ + ret = lttng_metadata_printf(session, + " string%s _%s;\n", + field->type.u.basic.string.encoding == lttng_encode_ASCII ? + " { encoding = ASCII; }" : "", + field->name); + break; + default: + WARN_ON_ONCE(1); + return -EINVAL; + } + return ret; +} + +static +int _lttng_context_metadata_statedump(struct lttng_session *session, + struct lttng_ctx *ctx) +{ + int ret = 0; + int i; + + if (!ctx) + return 0; + for (i = 0; i < ctx->nr_fields; i++) { + const struct lttng_ctx_field *field = &ctx->fields[i]; + + ret = _lttng_field_statedump(session, &field->event_field); + if (ret) + return ret; + } + return ret; +} + +static +int _lttng_fields_metadata_statedump(struct lttng_session *session, + struct lttng_event *event) +{ + const struct lttng_event_desc *desc = event->desc; + int ret = 0; + int i; + + for (i = 0; i < desc->nr_fields; i++) { + const struct lttng_event_field *field = &desc->fields[i]; + + ret = _lttng_field_statedump(session, field); + if (ret) + return ret; + } + return ret; +} + +static +int _lttng_event_metadata_statedump(struct lttng_session *session, + struct lttng_channel *chan, + struct lttng_event *event) +{ + int ret = 0; + + if (event->metadata_dumped || !ACCESS_ONCE(session->active)) + return 0; + if (chan == session->metadata) + return 0; + + ret = lttng_metadata_printf(session, + "event {\n" + " name = %s;\n" + " id = %u;\n" + " stream_id = %u;\n", + event->desc->name, + event->id, + event->chan->id); + if (ret) + goto end; + + if (event->ctx) { + ret = lttng_metadata_printf(session, + " context := struct {\n"); + if (ret) + goto end; + } + ret = _lttng_context_metadata_statedump(session, event->ctx); + if (ret) + goto end; + if (event->ctx) { + ret = lttng_metadata_printf(session, + " };\n"); + if (ret) + goto end; + } + + ret = lttng_metadata_printf(session, + " fields := struct {\n" + ); + if (ret) + goto end; + + ret = _lttng_fields_metadata_statedump(session, event); + if (ret) + goto end; + + /* + * LTTng space reservation can only reserve multiples of the + * byte size. + */ + ret = lttng_metadata_printf(session, + " };\n" + "};\n\n"); + if (ret) + goto end; + + event->metadata_dumped = 1; +end: + return ret; + +} + +static +int _lttng_channel_metadata_statedump(struct lttng_session *session, + struct lttng_channel *chan) +{ + int ret = 0; + + if (chan->metadata_dumped || !ACCESS_ONCE(session->active)) + return 0; + if (chan == session->metadata) + return 0; + + WARN_ON_ONCE(!chan->header_type); + ret = lttng_metadata_printf(session, + "stream {\n" + " id = %u;\n" + " event.header := %s;\n" + " packet.context := struct packet_context;\n", + chan->id, + chan->header_type == 1 ? "struct event_header_compact" : + "struct event_header_large"); + if (ret) + goto end; + + if (chan->ctx) { + ret = lttng_metadata_printf(session, + " event.context := struct {\n"); + if (ret) + goto end; + } + ret = _lttng_context_metadata_statedump(session, chan->ctx); + if (ret) + goto end; + if (chan->ctx) { + ret = lttng_metadata_printf(session, + " };\n"); + if (ret) + goto end; + } + + ret = lttng_metadata_printf(session, + "};\n\n"); + + chan->metadata_dumped = 1; +end: + return ret; +} + +static +int _lttng_stream_packet_context_declare(struct lttng_session *session) +{ + return lttng_metadata_printf(session, + "struct packet_context {\n" + " uint64_t timestamp_begin;\n" + " uint64_t timestamp_end;\n" + " uint32_t events_discarded;\n" + " uint32_t content_size;\n" + " uint32_t packet_size;\n" + " uint32_t cpu_id;\n" + "};\n\n" + ); +} + +/* + * Compact header: + * id: range: 0 - 30. + * id 31 is reserved to indicate an extended header. + * + * Large header: + * id: range: 0 - 65534. + * id 65535 is reserved to indicate an extended header. + */ +static +int _lttng_event_header_declare(struct lttng_session *session) +{ + return lttng_metadata_printf(session, + "struct event_header_compact {\n" + " enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n" + " variant {\n" + " struct {\n" + " uint27_t timestamp;\n" + " } compact;\n" + " struct {\n" + " uint32_t id;\n" + " uint64_t timestamp;\n" + " } extended;\n" + " } v;\n" + "} align(%u);\n" + "\n" + "struct event_header_large {\n" + " enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n" + " variant {\n" + " struct {\n" + " uint32_t timestamp;\n" + " } compact;\n" + " struct {\n" + " uint32_t id;\n" + " uint64_t timestamp;\n" + " } extended;\n" + " } v;\n" + "} align(%u);\n\n", + lttng_alignof(uint32_t) * CHAR_BIT, + lttng_alignof(uint16_t) * CHAR_BIT + ); +} + +/* + * Output metadata into this session's metadata buffers. + */ +static +int _lttng_session_metadata_statedump(struct lttng_session *session) +{ + unsigned char *uuid_c = session->uuid.b; + unsigned char uuid_s[37]; + struct lttng_channel *chan; + struct lttng_event *event; + int ret = 0; + + if (!ACCESS_ONCE(session->active)) + return 0; + if (session->metadata_dumped) + goto skip_session; + if (!session->metadata) { + printk(KERN_WARNING "LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n"); + return -EPERM; + } + + snprintf(uuid_s, sizeof(uuid_s), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid_c[0], uuid_c[1], uuid_c[2], uuid_c[3], + uuid_c[4], uuid_c[5], uuid_c[6], uuid_c[7], + uuid_c[8], uuid_c[9], uuid_c[10], uuid_c[11], + uuid_c[12], uuid_c[13], uuid_c[14], uuid_c[15]); + + ret = lttng_metadata_printf(session, + "typealias integer { size = 8; align = %u; signed = false; } := uint8_t;\n" + "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n" + "typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n" + "typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n" + "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n" + "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n" + "\n" + "trace {\n" + " major = %u;\n" + " minor = %u;\n" + " uuid = \"%s\";\n" + " byte_order = %s;\n" + " packet.header := struct {\n" + " uint32_t magic;\n" + " uint8_t uuid[16];\n" + " uint32_t stream_id;\n" + " };\n" + "};\n\n", + lttng_alignof(uint8_t) * CHAR_BIT, + lttng_alignof(uint16_t) * CHAR_BIT, + lttng_alignof(uint32_t) * CHAR_BIT, + lttng_alignof(uint64_t) * CHAR_BIT, + CTF_VERSION_MAJOR, + CTF_VERSION_MINOR, + uuid_s, +#ifdef __BIG_ENDIAN + "be" +#else + "le" +#endif + ); + if (ret) + goto end; + + ret = _lttng_stream_packet_context_declare(session); + if (ret) + goto end; + + ret = _lttng_event_header_declare(session); + if (ret) + goto end; + +skip_session: + list_for_each_entry(chan, &session->chan, list) { + ret = _lttng_channel_metadata_statedump(session, chan); + if (ret) + goto end; + } + + list_for_each_entry(event, &session->events, list) { + ret = _lttng_event_metadata_statedump(session, event->chan, event); + if (ret) + goto end; + } + session->metadata_dumped = 1; +end: + return ret; +} + +/** + * lttng_transport_register - LTT transport registration + * @transport: transport structure + * + * Registers a transport which can be used as output to extract the data out of + * LTTng. The module calling this registration function must ensure that no + * trap-inducing code will be executed by the transport functions. E.g. + * vmalloc_sync_all() must be called between a vmalloc and the moment the memory + * is made visible to the transport function. This registration acts as a + * vmalloc_sync_all. Therefore, only if the module allocates virtual memory + * after its registration must it synchronize the TLBs. + */ +void lttng_transport_register(struct lttng_transport *transport) +{ + /* + * Make sure no page fault can be triggered by the module about to be + * registered. We deal with this here so we don't have to call + * vmalloc_sync_all() in each module's init. + */ + wrapper_vmalloc_sync_all(); + + mutex_lock(&sessions_mutex); + list_add_tail(&transport->node, <tng_transport_list); + mutex_unlock(&sessions_mutex); +} +EXPORT_SYMBOL_GPL(lttng_transport_register); + +/** + * lttng_transport_unregister - LTT transport unregistration + * @transport: transport structure + */ +void lttng_transport_unregister(struct lttng_transport *transport) +{ + mutex_lock(&sessions_mutex); + list_del(&transport->node); + mutex_unlock(&sessions_mutex); +} +EXPORT_SYMBOL_GPL(lttng_transport_unregister); + +static int __init lttng_events_init(void) +{ + int ret; + + event_cache = KMEM_CACHE(lttng_event, 0); + if (!event_cache) + return -ENOMEM; + ret = lttng_abi_init(); + if (ret) + goto error_abi; + return 0; +error_abi: + kmem_cache_destroy(event_cache); + return ret; +} + +module_init(lttng_events_init); + +static void __exit lttng_events_exit(void) +{ + struct lttng_session *session, *tmpsession; + + lttng_abi_exit(); + list_for_each_entry_safe(session, tmpsession, &sessions, list) + lttng_session_destroy(session); + kmem_cache_destroy(event_cache); +} + +module_exit(lttng_events_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers "); +MODULE_DESCRIPTION("LTTng Events"); diff --git a/lttng-events.h b/lttng-events.h new file mode 100644 index 00000000..9c652c88 --- /dev/null +++ b/lttng-events.h @@ -0,0 +1,452 @@ +#ifndef _LTTNG_EVENTS_H +#define _LTTNG_EVENTS_H + +/* + * lttng-events.h + * + * Copyright 2010-2011 (c) - Mathieu Desnoyers + * + * Holds LTTng per-session event registry. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include +#include "wrapper/uuid.h" +#include "lttng-abi.h" + +#undef is_signed_type +#define is_signed_type(type) (((type)(-1)) < 0) + +struct lttng_channel; +struct lttng_session; +struct lib_ring_buffer_ctx; +struct perf_event; +struct perf_event_attr; + +/* Type description */ + +/* Update the astract_types name table in lttng-types.c along with this enum */ +enum abstract_types { + atype_integer, + atype_enum, + atype_array, + atype_sequence, + atype_string, + NR_ABSTRACT_TYPES, +}; + +/* Update the string_encodings name table in lttng-types.c along with this enum */ +enum lttng_string_encodings { + lttng_encode_none = 0, + lttng_encode_UTF8 = 1, + lttng_encode_ASCII = 2, + NR_STRING_ENCODINGS, +}; + +struct lttng_enum_entry { + unsigned long long start, end; /* start and end are inclusive */ + const char *string; +}; + +#define __type_integer(_type, _byte_order, _base, _encoding) \ + { \ + .atype = atype_integer, \ + .u.basic.integer = \ + { \ + .size = sizeof(_type) * CHAR_BIT, \ + .alignment = lttng_alignof(_type) * CHAR_BIT, \ + .signedness = is_signed_type(_type), \ + .reverse_byte_order = _byte_order != __BYTE_ORDER, \ + .base = _base, \ + .encoding = lttng_encode_##_encoding, \ + }, \ + } \ + +struct lttng_integer_type { + unsigned int size; /* in bits */ + unsigned short alignment; /* in bits */ + unsigned int signedness:1, + reverse_byte_order:1; + unsigned int base; /* 2, 8, 10, 16, for pretty print */ + enum lttng_string_encodings encoding; +}; + +union _lttng_basic_type { + struct lttng_integer_type integer; + struct { + const char *name; + } enumeration; + struct { + enum lttng_string_encodings encoding; + } string; +}; + +struct lttng_basic_type { + enum abstract_types atype; + union { + union _lttng_basic_type basic; + } u; +}; + +struct lttng_type { + enum abstract_types atype; + union { + union _lttng_basic_type basic; + struct { + struct lttng_basic_type elem_type; + unsigned int length; /* num. elems. */ + } array; + struct { + struct lttng_basic_type length_type; + struct lttng_basic_type elem_type; + } sequence; + } u; +}; + +struct lttng_enum { + const char *name; + struct lttng_type container_type; + const struct lttng_enum_entry *entries; + unsigned int len; +}; + +/* Event field description */ + +struct lttng_event_field { + const char *name; + struct lttng_type type; +}; + +/* + * We need to keep this perf counter field separately from struct + * lttng_ctx_field because cpu hotplug needs fixed-location addresses. + */ +struct lttng_perf_counter_field { + struct notifier_block nb; + int hp_enable; + struct perf_event_attr *attr; + struct perf_event **e; /* per-cpu array */ +}; + +struct lttng_ctx_field { + struct lttng_event_field event_field; + size_t (*get_size)(size_t offset); + void (*record)(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct lttng_channel *chan); + union { + struct lttng_perf_counter_field *perf_counter; + } u; + void (*destroy)(struct lttng_ctx_field *field); +}; + +struct lttng_ctx { + struct lttng_ctx_field *fields; + unsigned int nr_fields; + unsigned int allocated_fields; +}; + +struct lttng_event_desc { + const char *name; + void *probe_callback; + const struct lttng_event_ctx *ctx; /* context */ + const struct lttng_event_field *fields; /* event payload */ + unsigned int nr_fields; + struct module *owner; +}; + +struct lttng_probe_desc { + const struct lttng_event_desc **event_desc; + unsigned int nr_events; + struct list_head head; /* chain registered probes */ +}; + +struct lttng_krp; /* Kretprobe handling */ + +/* + * lttng_event structure is referred to by the tracing fast path. It must be + * kept small. + */ +struct lttng_event { + unsigned int id; + struct lttng_channel *chan; + int enabled; + const struct lttng_event_desc *desc; + void *filter; + struct lttng_ctx *ctx; + enum lttng_kernel_instrumentation instrumentation; + union { + struct { + struct kprobe kp; + char *symbol_name; + } kprobe; + struct { + struct lttng_krp *lttng_krp; + char *symbol_name; + } kretprobe; + struct { + char *symbol_name; + } ftrace; + } u; + struct list_head list; /* Event list */ + unsigned int metadata_dumped:1; +}; + +struct lttng_channel_ops { + struct channel *(*channel_create)(const char *name, + struct lttng_channel *lttng_chan, + void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); + void (*channel_destroy)(struct channel *chan); + struct lib_ring_buffer *(*buffer_read_open)(struct channel *chan); + int (*buffer_has_read_closed_stream)(struct channel *chan); + void (*buffer_read_close)(struct lib_ring_buffer *buf); + int (*event_reserve)(struct lib_ring_buffer_ctx *ctx, + uint32_t event_id); + void (*event_commit)(struct lib_ring_buffer_ctx *ctx); + void (*event_write)(struct lib_ring_buffer_ctx *ctx, const void *src, + size_t len); + void (*event_write_from_user)(struct lib_ring_buffer_ctx *ctx, + const void *src, size_t len); + void (*event_memset)(struct lib_ring_buffer_ctx *ctx, + int c, size_t len); + /* + * packet_avail_size returns the available size in the current + * packet. Note that the size returned is only a hint, since it + * may change due to concurrent writes. + */ + size_t (*packet_avail_size)(struct channel *chan); + wait_queue_head_t *(*get_writer_buf_wait_queue)(struct channel *chan, int cpu); + wait_queue_head_t *(*get_hp_wait_queue)(struct channel *chan); + int (*is_finalized)(struct channel *chan); + int (*is_disabled)(struct channel *chan); +}; + +struct lttng_transport { + char *name; + struct module *owner; + struct list_head node; + struct lttng_channel_ops ops; +}; + +struct lttng_channel { + unsigned int id; + struct channel *chan; /* Channel buffers */ + int enabled; + struct lttng_ctx *ctx; + /* Event ID management */ + struct lttng_session *session; + struct file *file; /* File associated to channel */ + unsigned int free_event_id; /* Next event ID to allocate */ + struct list_head list; /* Channel list */ + struct lttng_channel_ops *ops; + struct lttng_transport *transport; + struct lttng_event **sc_table; /* for syscall tracing */ + struct lttng_event **compat_sc_table; + struct lttng_event *sc_unknown; /* for unknown syscalls */ + struct lttng_event *sc_compat_unknown; + struct lttng_event *sc_exit; /* for syscall exit */ + int header_type; /* 0: unset, 1: compact, 2: large */ + unsigned int metadata_dumped:1; +}; + +struct lttng_session { + int active; /* Is trace session active ? */ + int been_active; /* Has trace session been active ? */ + struct file *file; /* File associated to session */ + struct lttng_channel *metadata; /* Metadata channel */ + struct list_head chan; /* Channel list head */ + struct list_head events; /* Event list head */ + struct list_head list; /* Session list */ + unsigned int free_chan_id; /* Next chan ID to allocate */ + uuid_le uuid; /* Trace session unique ID */ + unsigned int metadata_dumped:1; +}; + +struct lttng_session *lttng_session_create(void); +int lttng_session_enable(struct lttng_session *session); +int lttng_session_disable(struct lttng_session *session); +void lttng_session_destroy(struct lttng_session *session); + +struct lttng_channel *lttng_channel_create(struct lttng_session *session, + const char *transport_name, + void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); +struct lttng_channel *lttng_global_channel_create(struct lttng_session *session, + int overwrite, void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); + +struct lttng_event *lttng_event_create(struct lttng_channel *chan, + struct lttng_kernel_event *event_param, + void *filter, + const struct lttng_event_desc *internal_desc); + +int lttng_channel_enable(struct lttng_channel *channel); +int lttng_channel_disable(struct lttng_channel *channel); +int lttng_event_enable(struct lttng_event *event); +int lttng_event_disable(struct lttng_event *event); + +void lttng_transport_register(struct lttng_transport *transport); +void lttng_transport_unregister(struct lttng_transport *transport); + +void synchronize_trace(void); +int lttng_abi_init(void); +void lttng_abi_exit(void); + +int lttng_probe_register(struct lttng_probe_desc *desc); +void lttng_probe_unregister(struct lttng_probe_desc *desc); +const struct lttng_event_desc *lttng_event_get(const char *name); +void lttng_event_put(const struct lttng_event_desc *desc); +int lttng_probes_init(void); +void lttng_probes_exit(void); + +#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS +int lttng_syscalls_register(struct lttng_channel *chan, void *filter); +int lttng_syscalls_unregister(struct lttng_channel *chan); +#else +static inline int lttng_syscalls_register(struct lttng_channel *chan, void *filter) +{ + return -ENOSYS; +} + +static inline int lttng_syscalls_unregister(struct lttng_channel *chan) +{ + return 0; +} +#endif + +struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx); +int lttng_find_context(struct lttng_ctx *ctx, const char *name); +void lttng_remove_context_field(struct lttng_ctx **ctx, + struct lttng_ctx_field *field); +void lttng_destroy_context(struct lttng_ctx *ctx); +int lttng_add_pid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_procname_to_ctx(struct lttng_ctx **ctx); +int lttng_add_prio_to_ctx(struct lttng_ctx **ctx); +int lttng_add_nice_to_ctx(struct lttng_ctx **ctx); +int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_tid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx); +#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) +int lttng_add_perf_counter_to_ctx(uint32_t type, + uint64_t config, + const char *name, + struct lttng_ctx **ctx); +#else +static inline +int lttng_add_perf_counter_to_ctx(uint32_t type, + uint64_t config, + const char *name, + struct lttng_ctx **ctx) +{ + return -ENOSYS; +} +#endif + +#ifdef CONFIG_KPROBES +int lttng_kprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct lttng_event *event); +void lttng_kprobes_unregister(struct lttng_event *event); +void lttng_kprobes_destroy_private(struct lttng_event *event); +#else +static inline +int lttng_kprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct lttng_event *event) +{ + return -ENOSYS; +} + +static inline +void lttng_kprobes_unregister(struct lttng_event *event) +{ +} + +static inline +void lttng_kprobes_destroy_private(struct lttng_event *event) +{ +} +#endif + +#ifdef CONFIG_KRETPROBES +int lttng_kretprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct lttng_event *event_entry, + struct lttng_event *event_exit); +void lttng_kretprobes_unregister(struct lttng_event *event); +void lttng_kretprobes_destroy_private(struct lttng_event *event); +#else +static inline +int lttng_kretprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct lttng_event *event_entry, + struct lttng_event *event_exit) +{ + return -ENOSYS; +} + +static inline +void lttng_kretprobes_unregister(struct lttng_event *event) +{ +} + +static inline +void lttng_kretprobes_destroy_private(struct lttng_event *event) +{ +} +#endif + +#ifdef CONFIG_DYNAMIC_FTRACE +int lttng_ftrace_register(const char *name, + const char *symbol_name, + struct lttng_event *event); +void lttng_ftrace_unregister(struct lttng_event *event); +void lttng_ftrace_destroy_private(struct lttng_event *event); +#else +static inline +int lttng_ftrace_register(const char *name, + const char *symbol_name, + struct lttng_event *event) +{ + return -ENOSYS; +} + +static inline +void lttng_ftrace_unregister(struct lttng_event *event) +{ +} + +static inline +void lttng_ftrace_destroy_private(struct lttng_event *event) +{ +} +#endif + +int lttng_calibrate(struct lttng_kernel_calibrate *calibrate); + +extern const struct file_operations lttng_tracepoint_list_fops; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) +#define TRACEPOINT_HAS_DATA_ARG +#endif + +#endif /* _LTTNG_EVENTS_H */ diff --git a/lttng-probes.c b/lttng-probes.c new file mode 100644 index 00000000..97dcc359 --- /dev/null +++ b/lttng-probes.c @@ -0,0 +1,164 @@ +/* + * lttng-probes.c + * + * Copyright 2010-2011 (c) - Mathieu Desnoyers + * + * Holds LTTng probes registry. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include +#include +#include + +#include "lttng-events.h" + +static LIST_HEAD(probe_list); +static DEFINE_MUTEX(probe_mutex); + +static +const struct lttng_event_desc *find_event(const char *name) +{ + struct lttng_probe_desc *probe_desc; + int i; + + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (!strcmp(probe_desc->event_desc[i]->name, name)) + return probe_desc->event_desc[i]; + } + } + return NULL; +} + +int lttng_probe_register(struct lttng_probe_desc *desc) +{ + int ret = 0; + int i; + + mutex_lock(&probe_mutex); + /* + * TODO: This is O(N^2). Turn into a hash table when probe registration + * overhead becomes an issue. + */ + for (i = 0; i < desc->nr_events; i++) { + if (find_event(desc->event_desc[i]->name)) { + ret = -EEXIST; + goto end; + } + } + list_add(&desc->head, &probe_list); +end: + mutex_unlock(&probe_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(lttng_probe_register); + +void lttng_probe_unregister(struct lttng_probe_desc *desc) +{ + mutex_lock(&probe_mutex); + list_del(&desc->head); + mutex_unlock(&probe_mutex); +} +EXPORT_SYMBOL_GPL(lttng_probe_unregister); + +const struct lttng_event_desc *lttng_event_get(const char *name) +{ + const struct lttng_event_desc *event; + int ret; + + mutex_lock(&probe_mutex); + event = find_event(name); + mutex_unlock(&probe_mutex); + if (!event) + return NULL; + ret = try_module_get(event->owner); + WARN_ON_ONCE(!ret); + return event; +} +EXPORT_SYMBOL_GPL(lttng_event_get); + +void lttng_event_put(const struct lttng_event_desc *event) +{ + module_put(event->owner); +} +EXPORT_SYMBOL_GPL(lttng_event_put); + +static +void *tp_list_start(struct seq_file *m, loff_t *pos) +{ + struct lttng_probe_desc *probe_desc; + int iter = 0, i; + + mutex_lock(&probe_mutex); + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (iter++ >= *pos) + return (void *) probe_desc->event_desc[i]; + } + } + /* End of list */ + return NULL; +} + +static +void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos) +{ + struct lttng_probe_desc *probe_desc; + int iter = 0, i; + + (*ppos)++; + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (iter++ >= *ppos) + return (void *) probe_desc->event_desc[i]; + } + } + /* End of list */ + return NULL; +} + +static +void tp_list_stop(struct seq_file *m, void *p) +{ + mutex_unlock(&probe_mutex); +} + +static +int tp_list_show(struct seq_file *m, void *p) +{ + const struct lttng_event_desc *probe_desc = p; + + /* + * Don't export lttng internal events (metadata). + */ + if (!strncmp(probe_desc->name, "lttng_", sizeof("lttng_") - 1)) + return 0; + seq_printf(m, "event { name = %s; };\n", + probe_desc->name); + return 0; +} + +static +const struct seq_operations lttng_tracepoint_list_seq_ops = { + .start = tp_list_start, + .next = tp_list_next, + .stop = tp_list_stop, + .show = tp_list_show, +}; + +static +int lttng_tracepoint_list_open(struct inode *inode, struct file *file) +{ + return seq_open(file, <tng_tracepoint_list_seq_ops); +} + +const struct file_operations lttng_tracepoint_list_fops = { + .owner = THIS_MODULE, + .open = lttng_tracepoint_list_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; diff --git a/lttng-ring-buffer-client-discard.c b/lttng-ring-buffer-client-discard.c new file mode 100644 index 00000000..f3aeec31 --- /dev/null +++ b/lttng-ring-buffer-client-discard.c @@ -0,0 +1,21 @@ +/* + * lttng-ring-buffer-client-discard.c + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer client (discard mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include "lttng-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "discard" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE +#include "lttng-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode"); diff --git a/lttng-ring-buffer-client-mmap-discard.c b/lttng-ring-buffer-client-mmap-discard.c new file mode 100644 index 00000000..4ef89535 --- /dev/null +++ b/lttng-ring-buffer-client-mmap-discard.c @@ -0,0 +1,21 @@ +/* + * lttng-ring-buffer-client-discard.c + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer client (discard mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include "lttng-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "discard-mmap" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP +#include "lttng-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode"); diff --git a/lttng-ring-buffer-client-mmap-overwrite.c b/lttng-ring-buffer-client-mmap-overwrite.c new file mode 100644 index 00000000..5e87b1e1 --- /dev/null +++ b/lttng-ring-buffer-client-mmap-overwrite.c @@ -0,0 +1,21 @@ +/* + * lttng-ring-buffer-client-overwrite.c + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer client (overwrite mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include "lttng-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_OVERWRITE +#define RING_BUFFER_MODE_TEMPLATE_STRING "overwrite-mmap" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP +#include "lttng-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode"); diff --git a/lttng-ring-buffer-client-overwrite.c b/lttng-ring-buffer-client-overwrite.c new file mode 100644 index 00000000..bbd32809 --- /dev/null +++ b/lttng-ring-buffer-client-overwrite.c @@ -0,0 +1,21 @@ +/* + * lttng-ring-buffer-client-overwrite.c + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer client (overwrite mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include "lttng-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_OVERWRITE +#define RING_BUFFER_MODE_TEMPLATE_STRING "overwrite" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE +#include "lttng-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode"); diff --git a/lttng-ring-buffer-client.h b/lttng-ring-buffer-client.h new file mode 100644 index 00000000..1a04520c --- /dev/null +++ b/lttng-ring-buffer-client.h @@ -0,0 +1,569 @@ +/* + * lttng-ring-buffer-client.h + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer client template. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include +#include "lib/bitfield.h" +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "wrapper/trace-clock.h" +#include "lttng-events.h" +#include "lttng-tracer.h" +#include "wrapper/ringbuffer/frontend_types.h" + +/* + * Keep the natural field alignment for _each field_ within this structure if + * you ever add/remove a field from this header. Packed attribute is not used + * because gcc generates poor code on at least powerpc and mips. Don't ever + * let gcc add padding between the structure elements. + * + * The guarantee we have with timestamps is that all the events in a + * packet are included (inclusive) within the begin/end timestamps of + * the packet. Another guarantee we have is that the "timestamp begin", + * as well as the event timestamps, are monotonically increasing (never + * decrease) when moving forward in a stream (physically). But this + * guarantee does not apply to "timestamp end", because it is sampled at + * commit time, which is not ordered with respect to space reservation. + */ + +struct packet_header { + /* Trace packet header */ + uint32_t magic; /* + * Trace magic number. + * contains endianness information. + */ + uint8_t uuid[16]; + uint32_t stream_id; + + struct { + /* Stream packet context */ + uint64_t timestamp_begin; /* Cycle count at subbuffer start */ + uint64_t timestamp_end; /* Cycle count at subbuffer end */ + uint32_t events_discarded; /* + * Events lost in this subbuffer since + * the beginning of the trace. + * (may overflow) + */ + uint32_t content_size; /* Size of data in subbuffer */ + uint32_t packet_size; /* Subbuffer size (include padding) */ + uint32_t cpu_id; /* CPU id associated with stream */ + uint8_t header_end; /* End of header */ + } ctx; +}; + + +static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan) +{ + return trace_clock_read64(); +} + +static inline +size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx) +{ + int i; + size_t orig_offset = offset; + + if (likely(!ctx)) + return 0; + for (i = 0; i < ctx->nr_fields; i++) + offset += ctx->fields[i].get_size(offset); + return offset - orig_offset; +} + +static inline +void ctx_record(struct lib_ring_buffer_ctx *bufctx, + struct lttng_channel *chan, + struct lttng_ctx *ctx) +{ + int i; + + if (likely(!ctx)) + return; + for (i = 0; i < ctx->nr_fields; i++) + ctx->fields[i].record(&ctx->fields[i], bufctx, chan); +} + +/* + * record_header_size - Calculate the header size and padding necessary. + * @config: ring buffer instance configuration + * @chan: channel + * @offset: offset in the write buffer + * @pre_header_padding: padding to add before the header (output) + * @ctx: reservation context + * + * Returns the event header size (including padding). + * + * The payload must itself determine its own alignment from the biggest type it + * contains. + */ +static __inline__ +unsigned char record_header_size(const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx) +{ + struct lttng_channel *lttng_chan = channel_get_private(chan); + struct lttng_event *event = ctx->priv; + size_t orig_offset = offset; + size_t padding; + + switch (lttng_chan->header_type) { + case 1: /* compact */ + padding = lib_ring_buffer_align(offset, lttng_alignof(uint32_t)); + offset += padding; + if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) { + offset += sizeof(uint32_t); /* id and timestamp */ + } else { + /* Minimum space taken by 5-bit id */ + offset += sizeof(uint8_t); + /* Align extended struct on largest member */ + offset += lib_ring_buffer_align(offset, lttng_alignof(uint64_t)); + offset += sizeof(uint32_t); /* id */ + offset += lib_ring_buffer_align(offset, lttng_alignof(uint64_t)); + offset += sizeof(uint64_t); /* timestamp */ + } + break; + case 2: /* large */ + padding = lib_ring_buffer_align(offset, lttng_alignof(uint16_t)); + offset += padding; + offset += sizeof(uint16_t); + if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) { + offset += lib_ring_buffer_align(offset, lttng_alignof(uint32_t)); + offset += sizeof(uint32_t); /* timestamp */ + } else { + /* Align extended struct on largest member */ + offset += lib_ring_buffer_align(offset, lttng_alignof(uint64_t)); + offset += sizeof(uint32_t); /* id */ + offset += lib_ring_buffer_align(offset, lttng_alignof(uint64_t)); + offset += sizeof(uint64_t); /* timestamp */ + } + break; + default: + padding = 0; + WARN_ON_ONCE(1); + } + offset += ctx_get_size(offset, event->ctx); + offset += ctx_get_size(offset, lttng_chan->ctx); + + *pre_header_padding = padding; + return offset - orig_offset; +} + +#include "wrapper/ringbuffer/api.h" + +static +void lttng_write_event_header_slow(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + uint32_t event_id); + +/* + * lttng_write_event_header + * + * Writes the event header to the offset (already aligned on 32-bits). + * + * @config: ring buffer instance configuration + * @ctx: reservation context + * @event_id: event ID + */ +static __inline__ +void lttng_write_event_header(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + uint32_t event_id) +{ + struct lttng_channel *lttng_chan = channel_get_private(ctx->chan); + struct lttng_event *event = ctx->priv; + + if (unlikely(ctx->rflags)) + goto slow_path; + + switch (lttng_chan->header_type) { + case 1: /* compact */ + { + uint32_t id_time = 0; + + bt_bitfield_write(&id_time, uint32_t, 0, 5, event_id); + bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc); + lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time)); + break; + } + case 2: /* large */ + { + uint32_t timestamp = (uint32_t) ctx->tsc; + uint16_t id = event_id; + + lib_ring_buffer_write(config, ctx, &id, sizeof(id)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint32_t)); + lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); + break; + } + default: + WARN_ON_ONCE(1); + } + + ctx_record(ctx, lttng_chan, lttng_chan->ctx); + ctx_record(ctx, lttng_chan, event->ctx); + lib_ring_buffer_align_ctx(ctx, ctx->largest_align); + + return; + +slow_path: + lttng_write_event_header_slow(config, ctx, event_id); +} + +static +void lttng_write_event_header_slow(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + uint32_t event_id) +{ + struct lttng_channel *lttng_chan = channel_get_private(ctx->chan); + struct lttng_event *event = ctx->priv; + + switch (lttng_chan->header_type) { + case 1: /* compact */ + if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) { + uint32_t id_time = 0; + + bt_bitfield_write(&id_time, uint32_t, 0, 5, event_id); + bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc); + lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time)); + } else { + uint8_t id = 0; + uint64_t timestamp = ctx->tsc; + + bt_bitfield_write(&id, uint8_t, 0, 5, 31); + lib_ring_buffer_write(config, ctx, &id, sizeof(id)); + /* Align extended struct on largest member */ + lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint64_t)); + lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint64_t)); + lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); + } + break; + case 2: /* large */ + { + if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) { + uint32_t timestamp = (uint32_t) ctx->tsc; + uint16_t id = event_id; + + lib_ring_buffer_write(config, ctx, &id, sizeof(id)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint32_t)); + lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); + } else { + uint16_t id = 65535; + uint64_t timestamp = ctx->tsc; + + lib_ring_buffer_write(config, ctx, &id, sizeof(id)); + /* Align extended struct on largest member */ + lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint64_t)); + lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id)); + lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint64_t)); + lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp)); + } + break; + } + default: + WARN_ON_ONCE(1); + } + ctx_record(ctx, lttng_chan, lttng_chan->ctx); + ctx_record(ctx, lttng_chan, event->ctx); + lib_ring_buffer_align_ctx(ctx, ctx->largest_align); +} + +static const struct lib_ring_buffer_config client_config; + +static u64 client_ring_buffer_clock_read(struct channel *chan) +{ + return lib_ring_buffer_clock_read(chan); +} + +static +size_t client_record_header_size(const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx) +{ + return record_header_size(config, chan, offset, + pre_header_padding, ctx); +} + +/** + * client_packet_header_size - called on buffer-switch to a new sub-buffer + * + * Return header size without padding after the structure. Don't use packed + * structure because gcc generates inefficient code on some architectures + * (powerpc, mips..) + */ +static size_t client_packet_header_size(void) +{ + return offsetof(struct packet_header, ctx.header_end); +} + +static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx) +{ + struct channel *chan = buf->backend.chan; + struct packet_header *header = + (struct packet_header *) + lib_ring_buffer_offset_address(&buf->backend, + subbuf_idx * chan->backend.subbuf_size); + struct lttng_channel *lttng_chan = channel_get_private(chan); + struct lttng_session *session = lttng_chan->session; + + header->magic = CTF_MAGIC_NUMBER; + memcpy(header->uuid, session->uuid.b, sizeof(session->uuid)); + header->stream_id = lttng_chan->id; + header->ctx.timestamp_begin = tsc; + header->ctx.timestamp_end = 0; + header->ctx.events_discarded = 0; + header->ctx.content_size = 0xFFFFFFFF; /* for debugging */ + header->ctx.packet_size = 0xFFFFFFFF; + header->ctx.cpu_id = buf->backend.cpu; +} + +/* + * offset is assumed to never be 0 here : never deliver a completely empty + * subbuffer. data_size is between 1 and subbuf_size. + */ +static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx, unsigned long data_size) +{ + struct channel *chan = buf->backend.chan; + struct packet_header *header = + (struct packet_header *) + lib_ring_buffer_offset_address(&buf->backend, + subbuf_idx * chan->backend.subbuf_size); + unsigned long records_lost = 0; + + header->ctx.timestamp_end = tsc; + header->ctx.content_size = data_size * CHAR_BIT; /* in bits */ + header->ctx.packet_size = PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */ + records_lost += lib_ring_buffer_get_records_lost_full(&client_config, buf); + records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf); + records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf); + header->ctx.events_discarded = records_lost; +} + +static int client_buffer_create(struct lib_ring_buffer *buf, void *priv, + int cpu, const char *name) +{ + return 0; +} + +static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu) +{ +} + +static const struct lib_ring_buffer_config client_config = { + .cb.ring_buffer_clock_read = client_ring_buffer_clock_read, + .cb.record_header_size = client_record_header_size, + .cb.subbuffer_header_size = client_packet_header_size, + .cb.buffer_begin = client_buffer_begin, + .cb.buffer_end = client_buffer_end, + .cb.buffer_create = client_buffer_create, + .cb.buffer_finalize = client_buffer_finalize, + + .tsc_bits = 32, + .alloc = RING_BUFFER_ALLOC_PER_CPU, + .sync = RING_BUFFER_SYNC_PER_CPU, + .mode = RING_BUFFER_MODE_TEMPLATE, + .backend = RING_BUFFER_PAGE, + .output = RING_BUFFER_OUTPUT_TEMPLATE, + .oops = RING_BUFFER_OOPS_CONSISTENCY, + .ipi = RING_BUFFER_IPI_BARRIER, + .wakeup = RING_BUFFER_WAKEUP_BY_TIMER, +}; + +static +struct channel *_channel_create(const char *name, + struct lttng_channel *lttng_chan, void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval) +{ + return channel_create(&client_config, name, lttng_chan, buf_addr, + subbuf_size, num_subbuf, switch_timer_interval, + read_timer_interval); +} + +static +void lttng_channel_destroy(struct channel *chan) +{ + channel_destroy(chan); +} + +static +struct lib_ring_buffer *lttng_buffer_read_open(struct channel *chan) +{ + struct lib_ring_buffer *buf; + int cpu; + + for_each_channel_cpu(cpu, chan) { + buf = channel_get_ring_buffer(&client_config, chan, cpu); + if (!lib_ring_buffer_open_read(buf)) + return buf; + } + return NULL; +} + +static +int lttng_buffer_has_read_closed_stream(struct channel *chan) +{ + struct lib_ring_buffer *buf; + int cpu; + + for_each_channel_cpu(cpu, chan) { + buf = channel_get_ring_buffer(&client_config, chan, cpu); + if (!atomic_long_read(&buf->active_readers)) + return 1; + } + return 0; +} + +static +void lttng_buffer_read_close(struct lib_ring_buffer *buf) +{ + lib_ring_buffer_release_read(buf); +} + +static +int lttng_event_reserve(struct lib_ring_buffer_ctx *ctx, + uint32_t event_id) +{ + struct lttng_channel *lttng_chan = channel_get_private(ctx->chan); + int ret, cpu; + + cpu = lib_ring_buffer_get_cpu(&client_config); + if (cpu < 0) + return -EPERM; + ctx->cpu = cpu; + + switch (lttng_chan->header_type) { + case 1: /* compact */ + if (event_id > 30) + ctx->rflags |= LTTNG_RFLAG_EXTENDED; + break; + case 2: /* large */ + if (event_id > 65534) + ctx->rflags |= LTTNG_RFLAG_EXTENDED; + break; + default: + WARN_ON_ONCE(1); + } + + ret = lib_ring_buffer_reserve(&client_config, ctx); + if (ret) + goto put; + lttng_write_event_header(&client_config, ctx, event_id); + return 0; +put: + lib_ring_buffer_put_cpu(&client_config); + return ret; +} + +static +void lttng_event_commit(struct lib_ring_buffer_ctx *ctx) +{ + lib_ring_buffer_commit(&client_config, ctx); + lib_ring_buffer_put_cpu(&client_config); +} + +static +void lttng_event_write(struct lib_ring_buffer_ctx *ctx, const void *src, + size_t len) +{ + lib_ring_buffer_write(&client_config, ctx, src, len); +} + +static +void lttng_event_write_from_user(struct lib_ring_buffer_ctx *ctx, + const void __user *src, size_t len) +{ + lib_ring_buffer_copy_from_user(&client_config, ctx, src, len); +} + +static +void lttng_event_memset(struct lib_ring_buffer_ctx *ctx, + int c, size_t len) +{ + lib_ring_buffer_memset(&client_config, ctx, c, len); +} + +static +wait_queue_head_t *lttng_get_writer_buf_wait_queue(struct channel *chan, int cpu) +{ + struct lib_ring_buffer *buf = channel_get_ring_buffer(&client_config, + chan, cpu); + return &buf->write_wait; +} + +static +wait_queue_head_t *lttng_get_hp_wait_queue(struct channel *chan) +{ + return &chan->hp_wait; +} + +static +int lttng_is_finalized(struct channel *chan) +{ + return lib_ring_buffer_channel_is_finalized(chan); +} + +static +int lttng_is_disabled(struct channel *chan) +{ + return lib_ring_buffer_channel_is_disabled(chan); +} + +static struct lttng_transport lttng_relay_transport = { + .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING, + .owner = THIS_MODULE, + .ops = { + .channel_create = _channel_create, + .channel_destroy = lttng_channel_destroy, + .buffer_read_open = lttng_buffer_read_open, + .buffer_has_read_closed_stream = + lttng_buffer_has_read_closed_stream, + .buffer_read_close = lttng_buffer_read_close, + .event_reserve = lttng_event_reserve, + .event_commit = lttng_event_commit, + .event_write = lttng_event_write, + .event_write_from_user = lttng_event_write_from_user, + .event_memset = lttng_event_memset, + .packet_avail_size = NULL, /* Would be racy anyway */ + .get_writer_buf_wait_queue = lttng_get_writer_buf_wait_queue, + .get_hp_wait_queue = lttng_get_hp_wait_queue, + .is_finalized = lttng_is_finalized, + .is_disabled = lttng_is_disabled, + }, +}; + +static int __init lttng_ring_buffer_client_init(void) +{ + /* + * This vmalloc sync all also takes care of the lib ring buffer + * vmalloc'd module pages when it is built as a module into LTTng. + */ + wrapper_vmalloc_sync_all(); + lttng_transport_register(<tng_relay_transport); + return 0; +} + +module_init(lttng_ring_buffer_client_init); + +static void __exit lttng_ring_buffer_client_exit(void) +{ + lttng_transport_unregister(<tng_relay_transport); +} + +module_exit(lttng_ring_buffer_client_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING + " client"); diff --git a/lttng-ring-buffer-metadata-client.c b/lttng-ring-buffer-metadata-client.c new file mode 100644 index 00000000..4345dcad --- /dev/null +++ b/lttng-ring-buffer-metadata-client.c @@ -0,0 +1,21 @@ +/* + * lttng-ring-buffer-metadata-client.c + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer metadta client. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include "lttng-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "metadata" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE +#include "lttng-ring-buffer-metadata-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client"); diff --git a/lttng-ring-buffer-metadata-client.h b/lttng-ring-buffer-metadata-client.h new file mode 100644 index 00000000..cb5c1e4c --- /dev/null +++ b/lttng-ring-buffer-metadata-client.h @@ -0,0 +1,330 @@ +/* + * lttng-ring-buffer-client.h + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer client template. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "lttng-events.h" +#include "lttng-tracer.h" + +struct metadata_packet_header { + uint32_t magic; /* 0x75D11D57 */ + uint8_t uuid[16]; /* Unique Universal Identifier */ + uint32_t checksum; /* 0 if unused */ + uint32_t content_size; /* in bits */ + uint32_t packet_size; /* in bits */ + uint8_t compression_scheme; /* 0 if unused */ + uint8_t encryption_scheme; /* 0 if unused */ + uint8_t checksum_scheme; /* 0 if unused */ + uint8_t major; /* CTF spec major version number */ + uint8_t minor; /* CTF spec minor version number */ + uint8_t header_end[0]; +}; + +struct metadata_record_header { + uint8_t header_end[0]; /* End of header */ +}; + +static const struct lib_ring_buffer_config client_config; + +static inline +u64 lib_ring_buffer_clock_read(struct channel *chan) +{ + return 0; +} + +static inline +unsigned char record_header_size(const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx) +{ + return 0; +} + +#include "wrapper/ringbuffer/api.h" + +static u64 client_ring_buffer_clock_read(struct channel *chan) +{ + return 0; +} + +static +size_t client_record_header_size(const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx) +{ + return 0; +} + +/** + * client_packet_header_size - called on buffer-switch to a new sub-buffer + * + * Return header size without padding after the structure. Don't use packed + * structure because gcc generates inefficient code on some architectures + * (powerpc, mips..) + */ +static size_t client_packet_header_size(void) +{ + return offsetof(struct metadata_packet_header, header_end); +} + +static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx) +{ + struct channel *chan = buf->backend.chan; + struct metadata_packet_header *header = + (struct metadata_packet_header *) + lib_ring_buffer_offset_address(&buf->backend, + subbuf_idx * chan->backend.subbuf_size); + struct lttng_channel *lttng_chan = channel_get_private(chan); + struct lttng_session *session = lttng_chan->session; + + header->magic = TSDL_MAGIC_NUMBER; + memcpy(header->uuid, session->uuid.b, sizeof(session->uuid)); + header->checksum = 0; /* 0 if unused */ + header->content_size = 0xFFFFFFFF; /* in bits, for debugging */ + header->packet_size = 0xFFFFFFFF; /* in bits, for debugging */ + header->compression_scheme = 0; /* 0 if unused */ + header->encryption_scheme = 0; /* 0 if unused */ + header->checksum_scheme = 0; /* 0 if unused */ + header->major = CTF_SPEC_MAJOR; + header->minor = CTF_SPEC_MINOR; +} + +/* + * offset is assumed to never be 0 here : never deliver a completely empty + * subbuffer. data_size is between 1 and subbuf_size. + */ +static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx, unsigned long data_size) +{ + struct channel *chan = buf->backend.chan; + struct metadata_packet_header *header = + (struct metadata_packet_header *) + lib_ring_buffer_offset_address(&buf->backend, + subbuf_idx * chan->backend.subbuf_size); + unsigned long records_lost = 0; + + header->content_size = data_size * CHAR_BIT; /* in bits */ + header->packet_size = PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */ + /* + * We do not care about the records lost count, because the metadata + * channel waits and retry. + */ + (void) lib_ring_buffer_get_records_lost_full(&client_config, buf); + records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf); + records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf); + WARN_ON_ONCE(records_lost != 0); +} + +static int client_buffer_create(struct lib_ring_buffer *buf, void *priv, + int cpu, const char *name) +{ + return 0; +} + +static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu) +{ +} + +static const struct lib_ring_buffer_config client_config = { + .cb.ring_buffer_clock_read = client_ring_buffer_clock_read, + .cb.record_header_size = client_record_header_size, + .cb.subbuffer_header_size = client_packet_header_size, + .cb.buffer_begin = client_buffer_begin, + .cb.buffer_end = client_buffer_end, + .cb.buffer_create = client_buffer_create, + .cb.buffer_finalize = client_buffer_finalize, + + .tsc_bits = 0, + .alloc = RING_BUFFER_ALLOC_GLOBAL, + .sync = RING_BUFFER_SYNC_GLOBAL, + .mode = RING_BUFFER_MODE_TEMPLATE, + .backend = RING_BUFFER_PAGE, + .output = RING_BUFFER_OUTPUT_TEMPLATE, + .oops = RING_BUFFER_OOPS_CONSISTENCY, + .ipi = RING_BUFFER_IPI_BARRIER, + .wakeup = RING_BUFFER_WAKEUP_BY_TIMER, +}; + +static +struct channel *_channel_create(const char *name, + struct lttng_channel *lttng_chan, void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval) +{ + return channel_create(&client_config, name, lttng_chan, buf_addr, + subbuf_size, num_subbuf, switch_timer_interval, + read_timer_interval); +} + +static +void lttng_channel_destroy(struct channel *chan) +{ + channel_destroy(chan); +} + +static +struct lib_ring_buffer *lttng_buffer_read_open(struct channel *chan) +{ + struct lib_ring_buffer *buf; + + buf = channel_get_ring_buffer(&client_config, chan, 0); + if (!lib_ring_buffer_open_read(buf)) + return buf; + return NULL; +} + +static +int lttng_buffer_has_read_closed_stream(struct channel *chan) +{ + struct lib_ring_buffer *buf; + int cpu; + + for_each_channel_cpu(cpu, chan) { + buf = channel_get_ring_buffer(&client_config, chan, cpu); + if (!atomic_long_read(&buf->active_readers)) + return 1; + } + return 0; +} + +static +void lttng_buffer_read_close(struct lib_ring_buffer *buf) +{ + lib_ring_buffer_release_read(buf); +} + +static +int lttng_event_reserve(struct lib_ring_buffer_ctx *ctx, uint32_t event_id) +{ + return lib_ring_buffer_reserve(&client_config, ctx); +} + +static +void lttng_event_commit(struct lib_ring_buffer_ctx *ctx) +{ + lib_ring_buffer_commit(&client_config, ctx); +} + +static +void lttng_event_write(struct lib_ring_buffer_ctx *ctx, const void *src, + size_t len) +{ + lib_ring_buffer_write(&client_config, ctx, src, len); +} + +static +void lttng_event_write_from_user(struct lib_ring_buffer_ctx *ctx, + const void __user *src, size_t len) +{ + lib_ring_buffer_copy_from_user(&client_config, ctx, src, len); +} + +static +void lttng_event_memset(struct lib_ring_buffer_ctx *ctx, + int c, size_t len) +{ + lib_ring_buffer_memset(&client_config, ctx, c, len); +} + +static +size_t lttng_packet_avail_size(struct channel *chan) + +{ + unsigned long o_begin; + struct lib_ring_buffer *buf; + + buf = chan->backend.buf; /* Only for global buffer ! */ + o_begin = v_read(&client_config, &buf->offset); + if (subbuf_offset(o_begin, chan) != 0) { + return chan->backend.subbuf_size - subbuf_offset(o_begin, chan); + } else { + return chan->backend.subbuf_size - subbuf_offset(o_begin, chan) + - sizeof(struct metadata_packet_header); + } +} + +static +wait_queue_head_t *lttng_get_writer_buf_wait_queue(struct channel *chan, int cpu) +{ + struct lib_ring_buffer *buf = channel_get_ring_buffer(&client_config, + chan, cpu); + return &buf->write_wait; +} + +static +wait_queue_head_t *lttng_get_hp_wait_queue(struct channel *chan) +{ + return &chan->hp_wait; +} + +static +int lttng_is_finalized(struct channel *chan) +{ + return lib_ring_buffer_channel_is_finalized(chan); +} + +static +int lttng_is_disabled(struct channel *chan) +{ + return lib_ring_buffer_channel_is_disabled(chan); +} + +static struct lttng_transport lttng_relay_transport = { + .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING, + .owner = THIS_MODULE, + .ops = { + .channel_create = _channel_create, + .channel_destroy = lttng_channel_destroy, + .buffer_read_open = lttng_buffer_read_open, + .buffer_has_read_closed_stream = + lttng_buffer_has_read_closed_stream, + .buffer_read_close = lttng_buffer_read_close, + .event_reserve = lttng_event_reserve, + .event_commit = lttng_event_commit, + .event_write_from_user = lttng_event_write_from_user, + .event_memset = lttng_event_memset, + .event_write = lttng_event_write, + .packet_avail_size = lttng_packet_avail_size, + .get_writer_buf_wait_queue = lttng_get_writer_buf_wait_queue, + .get_hp_wait_queue = lttng_get_hp_wait_queue, + .is_finalized = lttng_is_finalized, + .is_disabled = lttng_is_disabled, + }, +}; + +static int __init lttng_ring_buffer_client_init(void) +{ + /* + * This vmalloc sync all also takes care of the lib ring buffer + * vmalloc'd module pages when it is built as a module into LTTng. + */ + wrapper_vmalloc_sync_all(); + lttng_transport_register(<tng_relay_transport); + return 0; +} + +module_init(lttng_ring_buffer_client_init); + +static void __exit lttng_ring_buffer_client_exit(void) +{ + lttng_transport_unregister(<tng_relay_transport); +} + +module_exit(lttng_ring_buffer_client_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING + " client"); diff --git a/lttng-ring-buffer-metadata-mmap-client.c b/lttng-ring-buffer-metadata-mmap-client.c new file mode 100644 index 00000000..7a3947f5 --- /dev/null +++ b/lttng-ring-buffer-metadata-mmap-client.c @@ -0,0 +1,21 @@ +/* + * lttng-ring-buffer-metadata-client.c + * + * Copyright (C) 2010 - Mathieu Desnoyers + * + * LTTng lib ring buffer metadta client. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include "lttng-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "metadata-mmap" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP +#include "lttng-ring-buffer-metadata-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client"); diff --git a/lttng-syscalls.c b/lttng-syscalls.c index 9de3c079..521531c3 100644 --- a/lttng-syscalls.c +++ b/lttng-syscalls.c @@ -14,7 +14,7 @@ #include #include -#include "ltt-events.h" +#include "lttng-events.h" #ifndef CONFIG_COMPAT static inline int is_compat_task(void) @@ -140,7 +140,7 @@ const struct trace_syscall_entry compat_sc_table[] = { #undef CREATE_SYSCALL_TABLE -static void syscall_entry_unknown(struct ltt_event *event, +static void syscall_entry_unknown(struct lttng_event *event, struct pt_regs *regs, unsigned int id) { unsigned long args[UNKNOWN_SYSCALL_NRARGS]; @@ -154,8 +154,8 @@ static void syscall_entry_unknown(struct ltt_event *event, void syscall_entry_probe(void *__data, struct pt_regs *regs, long id) { - struct ltt_channel *chan = __data; - struct ltt_event *event, *unknown_event; + struct lttng_channel *chan = __data; + struct lttng_event *event, *unknown_event; const struct trace_syscall_entry *table, *entry; size_t table_len; @@ -274,7 +274,7 @@ void syscall_entry_probe(void *__data, struct pt_regs *regs, long id) /* noinline to diminish caller stack size */ static int fill_table(const struct trace_syscall_entry *table, size_t table_len, - struct ltt_event **chan_table, struct ltt_channel *chan, void *filter) + struct lttng_event **chan_table, struct lttng_channel *chan, void *filter) { const struct lttng_event_desc *desc; unsigned int i; @@ -298,7 +298,7 @@ int fill_table(const struct trace_syscall_entry *table, size_t table_len, strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; ev.instrumentation = LTTNG_KERNEL_NOOP; - chan_table[i] = ltt_event_create(chan, &ev, filter, + chan_table[i] = lttng_event_create(chan, &ev, filter, desc); if (!chan_table[i]) { /* @@ -313,7 +313,7 @@ int fill_table(const struct trace_syscall_entry *table, size_t table_len, return 0; } -int lttng_syscalls_register(struct ltt_channel *chan, void *filter) +int lttng_syscalls_register(struct lttng_channel *chan, void *filter) { struct lttng_kernel_event ev; int ret; @@ -322,7 +322,7 @@ int lttng_syscalls_register(struct ltt_channel *chan, void *filter) if (!chan->sc_table) { /* create syscall table mapping syscall to events */ - chan->sc_table = kzalloc(sizeof(struct ltt_event *) + chan->sc_table = kzalloc(sizeof(struct lttng_event *) * ARRAY_SIZE(sc_table), GFP_KERNEL); if (!chan->sc_table) return -ENOMEM; @@ -331,7 +331,7 @@ int lttng_syscalls_register(struct ltt_channel *chan, void *filter) #ifdef CONFIG_COMPAT if (!chan->compat_sc_table) { /* create syscall table mapping compat syscall to events */ - chan->compat_sc_table = kzalloc(sizeof(struct ltt_event *) + chan->compat_sc_table = kzalloc(sizeof(struct lttng_event *) * ARRAY_SIZE(compat_sc_table), GFP_KERNEL); if (!chan->compat_sc_table) return -ENOMEM; @@ -345,7 +345,7 @@ int lttng_syscalls_register(struct ltt_channel *chan, void *filter) strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; ev.instrumentation = LTTNG_KERNEL_NOOP; - chan->sc_unknown = ltt_event_create(chan, &ev, filter, + chan->sc_unknown = lttng_event_create(chan, &ev, filter, desc); if (!chan->sc_unknown) { return -EINVAL; @@ -360,7 +360,7 @@ int lttng_syscalls_register(struct ltt_channel *chan, void *filter) strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; ev.instrumentation = LTTNG_KERNEL_NOOP; - chan->sc_compat_unknown = ltt_event_create(chan, &ev, filter, + chan->sc_compat_unknown = lttng_event_create(chan, &ev, filter, desc); if (!chan->sc_compat_unknown) { return -EINVAL; @@ -375,7 +375,7 @@ int lttng_syscalls_register(struct ltt_channel *chan, void *filter) strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; ev.instrumentation = LTTNG_KERNEL_NOOP; - chan->sc_exit = ltt_event_create(chan, &ev, filter, + chan->sc_exit = lttng_event_create(chan, &ev, filter, desc); if (!chan->sc_exit) { return -EINVAL; @@ -413,7 +413,7 @@ int lttng_syscalls_register(struct ltt_channel *chan, void *filter) /* * Only called at session destruction. */ -int lttng_syscalls_unregister(struct ltt_channel *chan) +int lttng_syscalls_unregister(struct lttng_channel *chan) { int ret; @@ -428,7 +428,7 @@ int lttng_syscalls_unregister(struct ltt_channel *chan) (void *) syscall_entry_probe, chan); if (ret) return ret; - /* ltt_event destroy will be performed by ltt_session_destroy() */ + /* lttng_event destroy will be performed by lttng_session_destroy() */ kfree(chan->sc_table); #ifdef CONFIG_COMPAT kfree(chan->compat_sc_table); diff --git a/lttng-tracer-core.h b/lttng-tracer-core.h new file mode 100644 index 00000000..c9e68b82 --- /dev/null +++ b/lttng-tracer-core.h @@ -0,0 +1,28 @@ +#ifndef LTTNG_TRACER_CORE_H +#define LTTNG_TRACER_CORE_H + +/* + * lttng-tracer-core.h + * + * Copyright (C) 2005-2011 Mathieu Desnoyers + * + * This contains the core definitions for the Linux Trace Toolkit. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include + +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +/* Align data on its natural alignment */ +#define RING_BUFFER_ALIGN +#endif + +#include "wrapper/ringbuffer/config.h" + +struct lttng_session; +struct lttng_channel; +struct lttng_event; + +#endif /* LTTNG_TRACER_CORE_H */ diff --git a/lttng-tracer.h b/lttng-tracer.h new file mode 100644 index 00000000..571a715e --- /dev/null +++ b/lttng-tracer.h @@ -0,0 +1,67 @@ +#ifndef _LTTNG_TRACER_H +#define _LTTNG_TRACER_H + +/* + * lttng-tracer.h + * + * Copyright (C) 2005-2011 Mathieu Desnoyers + * + * This contains the definitions for the Linux Trace Toolkit tracer. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wrapper/trace-clock.h" +#include "lttng-tracer-core.h" +#include "lttng-events.h" + +#define LTTNG_VERSION 0 +#define LTTNG_PATCHLEVEL 9 +#define LTTNG_SUBLEVEL 1 + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* Number of bytes to log with a read/write event */ +#define LTTNG_LOG_RW_SIZE 32L +#define LTTNG_MAX_SMALL_SIZE 0xFFFFU + +#ifdef RING_BUFFER_ALIGN +#define lttng_alignof(type) __alignof__(type) +#else +#define lttng_alignof(type) 1 +#endif + +/* Tracer properties */ +#define CTF_MAGIC_NUMBER 0xC1FC1FC1 +#define TSDL_MAGIC_NUMBER 0x75D11D57 + +/* CTF specification version followed */ +#define CTF_SPEC_MAJOR 1 +#define CTF_SPEC_MINOR 8 + +/* Tracer major/minor versions */ +#define CTF_VERSION_MAJOR 0 +#define CTF_VERSION_MINOR 1 + +/* + * Number of milliseconds to retry before failing metadata writes on buffer full + * condition. (10 seconds) + */ +#define LTTNG_METADATA_TIMEOUT_MSEC 10000 + +#define LTTNG_RFLAG_EXTENDED RING_BUFFER_RFLAG_END +#define LTTNG_RFLAG_END (LTTNG_RFLAG_EXTENDED << 1) + +#endif /* _LTTNG_TRACER_H */ diff --git a/probes/lttng-events.h b/probes/lttng-events.h index d486994f..d269490e 100644 --- a/probes/lttng-events.h +++ b/probes/lttng-events.h @@ -12,8 +12,8 @@ #include "lttng-types.h" #include "../wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ #include "../wrapper/ringbuffer/frontend_types.h" -#include "../ltt-events.h" -#include "../ltt-tracer-core.h" +#include "../lttng-events.h" +#include "../lttng-tracer-core.h" /* * Macro declarations used for all stages. @@ -319,19 +319,19 @@ static __used struct lttng_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = { #undef __field_full #define __field_full(_type, _item, _order, _base) \ - __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \ + __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ __event_len += sizeof(_type); #undef __array_enc_ext #define __array_enc_ext(_type, _item, _length, _order, _base, _encoding) \ - __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \ + __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ __event_len += sizeof(_type) * (_length); #undef __dynamic_array_enc_ext #define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ - __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(u32)); \ + __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(u32)); \ __event_len += sizeof(u32); \ - __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \ + __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \ __dynamic_len[__dynamic_len_idx] = (_length); \ __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \ __dynamic_len_idx++; @@ -382,16 +382,16 @@ static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \ #undef __field_full #define __field_full(_type, _item, _order, _base) \ - __event_align = max_t(size_t, __event_align, ltt_alignof(_type)); + __event_align = max_t(size_t, __event_align, lttng_alignof(_type)); #undef __array_enc_ext #define __array_enc_ext(_type, _item, _length, _order, _base, _encoding) \ - __event_align = max_t(size_t, __event_align, ltt_alignof(_type)); + __event_align = max_t(size_t, __event_align, lttng_alignof(_type)); #undef __dynamic_array_enc_ext #define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ - __event_align = max_t(size_t, __event_align, ltt_alignof(u32)); \ - __event_align = max_t(size_t, __event_align, ltt_alignof(_type)); + __event_align = max_t(size_t, __event_align, lttng_alignof(u32)); \ + __event_align = max_t(size_t, __event_align, lttng_alignof(_type)); #undef __string #define __string(_item, _src) @@ -506,7 +506,7 @@ __end_field_##_item: __assign_##dest: \ { \ __typeof__(__typemap.dest) __tmp = (src); \ - lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__tmp)); \ + lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp)); \ __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\ } \ goto __end_field_##dest; @@ -516,7 +516,7 @@ __assign_##dest: \ __assign_##dest: \ if (0) \ (void) __typemap.dest; \ - lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \ + lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest)); \ __chan->ops->event_write(&__ctx, src, len); \ goto __end_field_##dest; @@ -525,12 +525,12 @@ __assign_##dest: \ __assign_##dest##_1: \ { \ u32 __tmpl = __dynamic_len[__dynamic_len_idx]; \ - lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(u32)); \ + lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(u32)); \ __chan->ops->event_write(&__ctx, &__tmpl, sizeof(u32)); \ } \ goto __end_field_##dest##_1; \ __assign_##dest##_2: \ - lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \ + lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest)); \ __chan->ops->event_write(&__ctx, src, \ sizeof(__typemap.dest) * __get_dynamic_array_len(dest));\ goto __end_field_##dest##_2; @@ -540,7 +540,7 @@ __assign_##dest##_2: \ __assign_##dest: \ if (0) \ (void) __typemap.dest; \ - lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \ + lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest)); \ __chan->ops->event_write_from_user(&__ctx, src, len); \ goto __end_field_##dest; @@ -555,7 +555,7 @@ __assign_##dest##_2: \ \ if (0) \ (void) __typemap.dest; \ - lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));\ + lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest));\ __ustrlen = __get_dynamic_array_len(dest); \ if (likely(__ustrlen > 1)) { \ __chan->ops->event_write_from_user(&__ctx, src, \ @@ -596,8 +596,8 @@ __assign_##dest##_2: \ #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ static void __event_probe__##_name(void *__data, _proto) \ { \ - struct ltt_event *__event = __data; \ - struct ltt_channel *__chan = __event->chan; \ + struct lttng_event *__event = __data; \ + struct lttng_channel *__chan = __event->chan; \ struct lib_ring_buffer_ctx __ctx; \ size_t __event_len, __event_align; \ size_t __dynamic_len_idx = 0; \ @@ -632,8 +632,8 @@ static void __event_probe__##_name(void *__data, _proto) \ #define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \ static void __event_probe__##_name(void *__data) \ { \ - struct ltt_event *__event = __data; \ - struct ltt_channel *__chan = __event->chan; \ + struct lttng_event *__event = __data; \ + struct lttng_channel *__chan = __event->chan; \ struct lib_ring_buffer_ctx __ctx; \ size_t __event_len, __event_align; \ int __ret; \ @@ -680,14 +680,14 @@ static void __event_probe__##_name(void *__data) \ static int TP_ID(__lttng_events_init__, TRACE_SYSTEM)(void) { wrapper_vmalloc_sync_all(); - return ltt_probe_register(&TP_ID(__probe_desc___, TRACE_SYSTEM)); + return lttng_probe_register(&TP_ID(__probe_desc___, TRACE_SYSTEM)); } module_init_eval(__lttng_events_init__, TRACE_SYSTEM); static void TP_ID(__lttng_events_exit__, TRACE_SYSTEM)(void) { - ltt_probe_unregister(&TP_ID(__probe_desc___, TRACE_SYSTEM)); + lttng_probe_unregister(&TP_ID(__probe_desc___, TRACE_SYSTEM)); } module_exit_eval(__lttng_events_exit__, TRACE_SYSTEM); diff --git a/probes/lttng-ftrace.c b/probes/lttng-ftrace.c index 1aa71831..2a939216 100644 --- a/probes/lttng-ftrace.c +++ b/probes/lttng-ftrace.c @@ -20,17 +20,17 @@ #include #include #include -#include "../ltt-events.h" +#include "../lttng-events.h" #include "../wrapper/ringbuffer/frontend_types.h" #include "../wrapper/ftrace.h" #include "../wrapper/vmalloc.h" -#include "../ltt-tracer.h" +#include "../lttng-tracer.h" static void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data) { - struct ltt_event *event = *data; - struct ltt_channel *chan = event->chan; + struct lttng_event *event = *data; + struct lttng_channel *chan = event->chan; struct lib_ring_buffer_ctx ctx; struct { unsigned long ip; @@ -46,13 +46,13 @@ void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data return; lib_ring_buffer_ctx_init(&ctx, chan->chan, event, - sizeof(payload), ltt_alignof(payload), -1); + sizeof(payload), lttng_alignof(payload), -1); ret = chan->ops->event_reserve(&ctx, event->id); if (ret < 0) return; payload.ip = ip; payload.parent_ip = parent_ip; - lib_ring_buffer_align_ctx(&ctx, ltt_alignof(payload)); + lib_ring_buffer_align_ctx(&ctx, lttng_alignof(payload)); chan->ops->event_write(&ctx, &payload, sizeof(payload)); chan->ops->event_commit(&ctx); return; @@ -62,7 +62,7 @@ void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data * Create event description */ static -int lttng_create_ftrace_event(const char *name, struct ltt_event *event) +int lttng_create_ftrace_event(const char *name, struct lttng_event *event) { struct lttng_event_field *fields; struct lttng_event_desc *desc; @@ -86,7 +86,7 @@ int lttng_create_ftrace_event(const char *name, struct ltt_event *event) fields[0].name = "ip"; fields[0].type.atype = atype_integer; fields[0].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; - fields[0].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[0].type.u.basic.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT; fields[0].type.u.basic.integer.signedness = is_signed_type(unsigned long); fields[0].type.u.basic.integer.reverse_byte_order = 0; fields[0].type.u.basic.integer.base = 16; @@ -95,7 +95,7 @@ int lttng_create_ftrace_event(const char *name, struct ltt_event *event) fields[1].name = "parent_ip"; fields[1].type.atype = atype_integer; fields[1].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; - fields[1].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[1].type.u.basic.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT; fields[1].type.u.basic.integer.signedness = is_signed_type(unsigned long); fields[1].type.u.basic.integer.reverse_byte_order = 0; fields[1].type.u.basic.integer.base = 16; @@ -120,7 +120,7 @@ struct ftrace_probe_ops lttng_ftrace_ops = { int lttng_ftrace_register(const char *name, const char *symbol_name, - struct ltt_event *event) + struct lttng_event *event) { int ret; @@ -151,14 +151,14 @@ error: } EXPORT_SYMBOL_GPL(lttng_ftrace_register); -void lttng_ftrace_unregister(struct ltt_event *event) +void lttng_ftrace_unregister(struct lttng_event *event) { wrapper_unregister_ftrace_function_probe(event->u.ftrace.symbol_name, <tng_ftrace_ops, event); } EXPORT_SYMBOL_GPL(lttng_ftrace_unregister); -void lttng_ftrace_destroy_private(struct ltt_event *event) +void lttng_ftrace_destroy_private(struct lttng_event *event) { kfree(event->u.ftrace.symbol_name); kfree(event->desc->fields); diff --git a/probes/lttng-kprobes.c b/probes/lttng-kprobes.c index 784002ae..e9c64960 100644 --- a/probes/lttng-kprobes.c +++ b/probes/lttng-kprobes.c @@ -10,17 +10,17 @@ #include #include #include -#include "../ltt-events.h" +#include "../lttng-events.h" #include "../wrapper/ringbuffer/frontend_types.h" #include "../wrapper/vmalloc.h" -#include "../ltt-tracer.h" +#include "../lttng-tracer.h" static int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs) { - struct ltt_event *event = - container_of(p, struct ltt_event, u.kprobe.kp); - struct ltt_channel *chan = event->chan; + struct lttng_event *event = + container_of(p, struct lttng_event, u.kprobe.kp); + struct lttng_channel *chan = event->chan; struct lib_ring_buffer_ctx ctx; int ret; unsigned long data = (unsigned long) p->addr; @@ -33,11 +33,11 @@ int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs) return 0; lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data), - ltt_alignof(data), -1); + lttng_alignof(data), -1); ret = chan->ops->event_reserve(&ctx, event->id); if (ret < 0) return 0; - lib_ring_buffer_align_ctx(&ctx, ltt_alignof(data)); + lib_ring_buffer_align_ctx(&ctx, lttng_alignof(data)); chan->ops->event_write(&ctx, &data, sizeof(data)); chan->ops->event_commit(&ctx); return 0; @@ -47,7 +47,7 @@ int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs) * Create event description */ static -int lttng_create_kprobe_event(const char *name, struct ltt_event *event) +int lttng_create_kprobe_event(const char *name, struct lttng_event *event) { struct lttng_event_field *field; struct lttng_event_desc *desc; @@ -71,7 +71,7 @@ int lttng_create_kprobe_event(const char *name, struct ltt_event *event) field->name = "ip"; field->type.atype = atype_integer; field->type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; - field->type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + field->type.u.basic.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT; field->type.u.basic.integer.signedness = is_signed_type(unsigned long); field->type.u.basic.integer.reverse_byte_order = 0; field->type.u.basic.integer.base = 16; @@ -92,7 +92,7 @@ int lttng_kprobes_register(const char *name, const char *symbol_name, uint64_t offset, uint64_t addr, - struct ltt_event *event) + struct lttng_event *event) { int ret; @@ -144,13 +144,13 @@ error: } EXPORT_SYMBOL_GPL(lttng_kprobes_register); -void lttng_kprobes_unregister(struct ltt_event *event) +void lttng_kprobes_unregister(struct lttng_event *event) { unregister_kprobe(&event->u.kprobe.kp); } EXPORT_SYMBOL_GPL(lttng_kprobes_unregister); -void lttng_kprobes_destroy_private(struct ltt_event *event) +void lttng_kprobes_destroy_private(struct lttng_event *event) { kfree(event->u.kprobe.symbol_name); kfree(event->desc->fields); diff --git a/probes/lttng-kretprobes.c b/probes/lttng-kretprobes.c index 6b291018..6b75848a 100644 --- a/probes/lttng-kretprobes.c +++ b/probes/lttng-kretprobes.c @@ -11,10 +11,10 @@ #include #include #include -#include "../ltt-events.h" +#include "../lttng-events.h" #include "../wrapper/ringbuffer/frontend_types.h" #include "../wrapper/vmalloc.h" -#include "../ltt-tracer.h" +#include "../lttng-tracer.h" enum lttng_kretprobe_type { EVENT_ENTRY = 0, @@ -23,7 +23,7 @@ enum lttng_kretprobe_type { struct lttng_krp { struct kretprobe krp; - struct ltt_event *event[2]; /* ENTRY and RETURN */ + struct lttng_event *event[2]; /* ENTRY and RETURN */ struct kref kref_register; struct kref kref_alloc; }; @@ -35,9 +35,9 @@ int _lttng_kretprobes_handler(struct kretprobe_instance *krpi, { struct lttng_krp *lttng_krp = container_of(krpi->rp, struct lttng_krp, krp); - struct ltt_event *event = + struct lttng_event *event = lttng_krp->event[type]; - struct ltt_channel *chan = event->chan; + struct lttng_channel *chan = event->chan; struct lib_ring_buffer_ctx ctx; int ret; struct { @@ -56,11 +56,11 @@ int _lttng_kretprobes_handler(struct kretprobe_instance *krpi, payload.parent_ip = (unsigned long) krpi->ret_addr; lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(payload), - ltt_alignof(payload), -1); + lttng_alignof(payload), -1); ret = chan->ops->event_reserve(&ctx, event->id); if (ret < 0) return 0; - lib_ring_buffer_align_ctx(&ctx, ltt_alignof(payload)); + lib_ring_buffer_align_ctx(&ctx, lttng_alignof(payload)); chan->ops->event_write(&ctx, &payload, sizeof(payload)); chan->ops->event_commit(&ctx); return 0; @@ -84,7 +84,7 @@ int lttng_kretprobes_handler_return(struct kretprobe_instance *krpi, * Create event description */ static -int lttng_create_kprobe_event(const char *name, struct ltt_event *event, +int lttng_create_kprobe_event(const char *name, struct lttng_event *event, enum lttng_kretprobe_type type) { struct lttng_event_field *fields; @@ -125,7 +125,7 @@ int lttng_create_kprobe_event(const char *name, struct ltt_event *event, fields[0].name = "ip"; fields[0].type.atype = atype_integer; fields[0].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; - fields[0].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[0].type.u.basic.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT; fields[0].type.u.basic.integer.signedness = is_signed_type(unsigned long); fields[0].type.u.basic.integer.reverse_byte_order = 0; fields[0].type.u.basic.integer.base = 16; @@ -134,7 +134,7 @@ int lttng_create_kprobe_event(const char *name, struct ltt_event *event, fields[1].name = "parent_ip"; fields[1].type.atype = atype_integer; fields[1].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; - fields[1].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[1].type.u.basic.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT; fields[1].type.u.basic.integer.signedness = is_signed_type(unsigned long); fields[1].type.u.basic.integer.reverse_byte_order = 0; fields[1].type.u.basic.integer.base = 16; @@ -156,8 +156,8 @@ int lttng_kretprobes_register(const char *name, const char *symbol_name, uint64_t offset, uint64_t addr, - struct ltt_event *event_entry, - struct ltt_event *event_return) + struct lttng_event *event_entry, + struct lttng_event *event_return) { int ret; struct lttng_krp *lttng_krp; @@ -247,7 +247,7 @@ void _lttng_kretprobes_unregister_release(struct kref *kref) unregister_kretprobe(<tng_krp->krp); } -void lttng_kretprobes_unregister(struct ltt_event *event) +void lttng_kretprobes_unregister(struct lttng_event *event) { kref_put(&event->u.kretprobe.lttng_krp->kref_register, _lttng_kretprobes_unregister_release); @@ -262,7 +262,7 @@ void _lttng_kretprobes_release(struct kref *kref) kfree(lttng_krp->krp.kp.symbol_name); } -void lttng_kretprobes_destroy_private(struct ltt_event *event) +void lttng_kretprobes_destroy_private(struct lttng_event *event) { kfree(event->desc->fields); kfree(event->desc->name); diff --git a/probes/lttng-types.c b/probes/lttng-types.c index 93a9ae54..2975cc49 100644 --- a/probes/lttng-types.c +++ b/probes/lttng-types.c @@ -11,7 +11,7 @@ #include #include #include "../wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ -#include "../ltt-events.h" +#include "../lttng-events.h" #include "lttng-types.h" #include diff --git a/probes/lttng-types.h b/probes/lttng-types.h index 10620280..ea162940 100644 --- a/probes/lttng-types.h +++ b/probes/lttng-types.h @@ -17,9 +17,9 @@ #include #include "lttng.h" -#include "../ltt-events.h" -#include "../ltt-tracer.h" -#include "../ltt-endian.h" +#include "../lttng-events.h" +#include "../lttng-tracer.h" +#include "../lttng-endian.h" #endif /* _LTTNG_PROBES_LTTNG_TYPES_H */ diff --git a/wrapper/ftrace.h b/wrapper/ftrace.h index ace33c54..0f15ee4a 100644 --- a/wrapper/ftrace.h +++ b/wrapper/ftrace.h @@ -1,5 +1,5 @@ -#ifndef _LTT_WRAPPER_FTRACE_H -#define _LTT_WRAPPER_FTRACE_H +#ifndef _LTTNG_WRAPPER_FTRACE_H +#define _LTTNG_WRAPPER_FTRACE_H /* * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com) @@ -67,4 +67,4 @@ void wrapper_unregister_ftrace_function_probe(char *glob, } #endif -#endif /* _LTT_WRAPPER_FTRACE_H */ +#endif /* _LTTNG_WRAPPER_FTRACE_H */ diff --git a/wrapper/kallsyms.h b/wrapper/kallsyms.h index afda9d21..eb904e06 100644 --- a/wrapper/kallsyms.h +++ b/wrapper/kallsyms.h @@ -1,5 +1,5 @@ -#ifndef _LTT_WRAPPER_KALLSYMS_H -#define _LTT_WRAPPER_KALLSYMS_H +#ifndef _LTTNG_WRAPPER_KALLSYMS_H +#define _LTTNG_WRAPPER_KALLSYMS_H /* * Copyright (C) 2011 Avik Sil (avik.sil@linaro.org) @@ -27,4 +27,4 @@ unsigned long kallsyms_lookup_funcptr(const char *name) #endif return addr; } -#endif /* _LTT_WRAPPER_KALLSYMS_H */ +#endif /* _LTTNG_WRAPPER_KALLSYMS_H */ diff --git a/wrapper/perf.h b/wrapper/perf.h index 9a6dbfc0..d774d4ab 100644 --- a/wrapper/perf.h +++ b/wrapper/perf.h @@ -1,5 +1,5 @@ -#ifndef _LTT_WRAPPER_PERF_H -#define _LTT_WRAPPER_PERF_H +#ifndef _LTTNG_WRAPPER_PERF_H +#define _LTTNG_WRAPPER_PERF_H /* * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com) @@ -29,4 +29,4 @@ wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr, } #endif -#endif /* _LTT_WRAPPER_PERF_H */ +#endif /* _LTTNG_WRAPPER_PERF_H */ diff --git a/wrapper/spinlock.h b/wrapper/spinlock.h index 8b1ad992..147ace92 100644 --- a/wrapper/spinlock.h +++ b/wrapper/spinlock.h @@ -1,5 +1,5 @@ -#ifndef _LTT_WRAPPER_SPINLOCK_H -#define _LTT_WRAPPER_SPINLOCK_H +#ifndef _LTTNG_WRAPPER_SPINLOCK_H +#define _LTTNG_WRAPPER_SPINLOCK_H /* * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com) @@ -23,4 +23,4 @@ #endif -#endif /* _LTT_WRAPPER_SPINLOCK_H */ +#endif /* _LTTNG_WRAPPER_SPINLOCK_H */ diff --git a/wrapper/splice.h b/wrapper/splice.h index f75309a8..ee08c6c6 100644 --- a/wrapper/splice.h +++ b/wrapper/splice.h @@ -1,5 +1,5 @@ -#ifndef _LTT_WRAPPER_SPLICE_H -#define _LTT_WRAPPER_SPLICE_H +#ifndef _LTTNG_WRAPPER_SPLICE_H +#define _LTTNG_WRAPPER_SPLICE_H /* * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com) @@ -20,4 +20,4 @@ ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe, #define PIPE_DEF_BUFFERS 16 #endif -#endif /* _LTT_WRAPPER_SPLICE_H */ +#endif /* _LTTNG_WRAPPER_SPLICE_H */ diff --git a/wrapper/trace-clock.h b/wrapper/trace-clock.h index 11bef42b..05ab055a 100644 --- a/wrapper/trace-clock.h +++ b/wrapper/trace-clock.h @@ -7,8 +7,8 @@ * Dual LGPL v2.1/GPL v2 license. */ -#ifndef _LTT_TRACE_CLOCK_H -#define _LTT_TRACE_CLOCK_H +#ifndef _LTTNG_TRACE_CLOCK_H +#define _LTTNG_TRACE_CLOCK_H #ifdef CONFIG_HAVE_TRACE_CLOCK #include @@ -74,4 +74,4 @@ static inline void put_trace_clock(void) #endif /* CONFIG_HAVE_TRACE_CLOCK */ -#endif /* _LTT_TRACE_CLOCK_H */ +#endif /* _LTTNG_TRACE_CLOCK_H */ diff --git a/wrapper/uuid.h b/wrapper/uuid.h index bfa67ff3..b118b365 100644 --- a/wrapper/uuid.h +++ b/wrapper/uuid.h @@ -1,5 +1,5 @@ -#ifndef _LTT_WRAPPER_UUID_H -#define _LTT_WRAPPER_UUID_H +#ifndef _LTTNG_WRAPPER_UUID_H +#define _LTTNG_WRAPPER_UUID_H /* * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com) @@ -26,4 +26,4 @@ void uuid_le_gen(uuid_le *u) } #endif -#endif /* _LTT_WRAPPER_UUID_H */ +#endif /* _LTTNG_WRAPPER_UUID_H */ diff --git a/wrapper/vmalloc.h b/wrapper/vmalloc.h index 765f2ad9..8874b571 100644 --- a/wrapper/vmalloc.h +++ b/wrapper/vmalloc.h @@ -1,5 +1,5 @@ -#ifndef _LTT_WRAPPER_VMALLOC_H -#define _LTT_WRAPPER_VMALLOC_H +#ifndef _LTTNG_WRAPPER_VMALLOC_H +#define _LTTNG_WRAPPER_VMALLOC_H /* * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com) @@ -46,4 +46,4 @@ void wrapper_vmalloc_sync_all(void) } #endif -#endif /* _LTT_WRAPPER_VMALLOC_H */ +#endif /* _LTTNG_WRAPPER_VMALLOC_H */