X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libust%2Fltt-events.c;h=91842bc015c3bf08631654d64a7713df84d058ea;hb=4cfec15c93af7e0cfe3ce769ee90486bb8ab7c37;hp=3457699f812edfaa347aec64086321b2aa341b49;hpb=4b4de73e56cad17f87de69bd9386389ed69c0a12;p=lttng-ust.git diff --git a/libust/ltt-events.c b/libust/ltt-events.c index 3457699f..91842bc0 100644 --- a/libust/ltt-events.c +++ b/libust/ltt-events.c @@ -8,21 +8,65 @@ * Dual LGPL v2.1/GPL v2 license. */ -#include -#include -#include -#include -#include -#include -#include -#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ -#include "ltt-events.h" +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ust/core.h" #include "ltt-tracer.h" +#include "ltt-tracer-core.h" +#include "ust/wait.h" +#include "../libringbuffer/shm.h" -static LIST_HEAD(sessions); -static LIST_HEAD(ltt_transport_list); +typedef u32 uint32_t; +#include + +/* + * The sessions mutex is the centralized mutex across UST tracing + * control and probe registration. All operations within this file are + * called by the communication thread, under ust_lock protection. + */ static DEFINE_MUTEX(sessions_mutex); -static struct kmem_cache *event_cache; + +void ust_lock(void) +{ + pthread_mutex_lock(&sessions_mutex); +} + +void ust_unlock(void) +{ + pthread_mutex_unlock(&sessions_mutex); +} + +static CDS_LIST_HEAD(sessions); +static CDS_LIST_HEAD(ltt_transport_list); + +/* + * Pending probes hash table, containing the registered ltt events for + * which tracepoint probes are still missing. Protected by the sessions + * mutex. + */ +#define PENDING_PROBE_HASH_BITS 6 +#define PENDING_PROBE_HASH_SIZE (1 << PENDING_PROBE_HASH_BITS) +static struct cds_hlist_head pending_probe_table[PENDING_PROBE_HASH_SIZE]; + +struct ust_pending_probe { + struct ltt_event *event; + struct cds_hlist_node node; + char name[]; +}; static void _ltt_event_destroy(struct ltt_event *event); static void _ltt_channel_destroy(struct ltt_channel *chan); @@ -34,27 +78,99 @@ int _ltt_event_metadata_statedump(struct ltt_session *session, static int _ltt_session_metadata_statedump(struct ltt_session *session); +/* + * called at event creation if probe is missing. + * called with session mutex held. + */ +static +int add_pending_probe(struct ltt_event *event, const char *name) +{ + struct cds_hlist_head *head; + struct ust_pending_probe *e; + size_t name_len = strlen(name) + 1; + u32 hash = jhash(name, name_len - 1, 0); + + head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)]; + e = zmalloc(sizeof(struct ust_pending_probe) + name_len); + if (!e) + return -ENOMEM; + memcpy(&e->name[0], name, name_len); + cds_hlist_add_head(&e->node, head); + e->event = event; + event->pending_probe = e; + return 0; +} + +/* + * remove a pending probe. called when at event teardown and when an + * event is fixed (probe is loaded). + * called with session mutex held. + */ +static +void remove_pending_probe(struct ust_pending_probe *e) +{ + if (!e) + return; + cds_hlist_del(&e->node); + free(e); +} + +/* + * Called at library load: connect the probe on the events pending on + * probe load. + * called with session mutex held. + */ +int pending_probe_fix_events(const struct lttng_event_desc *desc) +{ + struct cds_hlist_head *head; + struct cds_hlist_node *node, *p; + struct ust_pending_probe *e; + const char *name = desc->name; + size_t name_len = strlen(name) + 1; + u32 hash = jhash(name, name_len - 1, 0); + int ret = 0; + + head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)]; + cds_hlist_for_each_entry_safe(e, node, p, head, node) { + struct ltt_event *event; + struct ltt_channel *chan; + + if (strcmp(name, e->name)) + continue; + event = e->event; + chan = event->chan; + assert(!event->desc); + event->desc = desc; + event->pending_probe = NULL; + remove_pending_probe(e); + ret |= __tracepoint_probe_register(name, + event->desc->probe_callback, + event); + if (ret) + continue; + event->id = chan->free_event_id++; + ret |= _ltt_event_metadata_statedump(chan->session, chan, + event); + } + return ret; +} + 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); + session = zmalloc(sizeof(struct ltt_session)); 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); + CDS_INIT_LIST_HEAD(&session->chan); + CDS_INIT_LIST_HEAD(&session->events); + uuid_generate(session->uuid); + cds_list_add(&session->list, &sessions); return session; } @@ -64,20 +180,18 @@ void ltt_session_destroy(struct ltt_session *session) struct ltt_event *event, *tmpevent; int ret; - mutex_lock(&sessions_mutex); - ACCESS_ONCE(session->active) = 0; - list_for_each_entry(event, &session->events, list) { + CMM_ACCESS_ONCE(session->active) = 0; + cds_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) + cds_list_for_each_entry_safe(event, tmpevent, &session->events, list) _ltt_event_destroy(event); - list_for_each_entry_safe(chan, tmpchan, &session->chan, list) + cds_list_for_each_entry_safe(chan, tmpchan, &session->chan, list) _ltt_channel_destroy(chan); - list_del(&session->list); - mutex_unlock(&sessions_mutex); - kfree(session); + cds_list_del(&session->list); + free(session); } int ltt_session_enable(struct ltt_session *session) @@ -85,7 +199,6 @@ 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; @@ -95,7 +208,7 @@ int ltt_session_enable(struct ltt_session *session) * 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) { + cds_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) @@ -104,13 +217,12 @@ int ltt_session_enable(struct ltt_session *session) chan->header_type = 2; /* large */ } - ACCESS_ONCE(session->active) = 1; - ACCESS_ONCE(session->been_active) = 1; + CMM_ACCESS_ONCE(session->active) = 1; + CMM_ACCESS_ONCE(session->been_active) = 1; ret = _ltt_session_metadata_statedump(session); if (ret) - ACCESS_ONCE(session->active) = 0; + CMM_ACCESS_ONCE(session->active) = 0; end: - mutex_unlock(&sessions_mutex); return ret; } @@ -118,14 +230,12 @@ 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; + CMM_ACCESS_ONCE(session->active) = 0; end: - mutex_unlock(&sessions_mutex); return ret; } @@ -135,7 +245,7 @@ int ltt_channel_enable(struct ltt_channel *channel) if (channel == channel->session->metadata) return -EPERM; - old = xchg(&channel->enabled, 1); + old = uatomic_xchg(&channel->enabled, 1); if (old) return -EEXIST; return 0; @@ -147,7 +257,7 @@ int ltt_channel_disable(struct ltt_channel *channel) if (channel == channel->session->metadata) return -EPERM; - old = xchg(&channel->enabled, 0); + old = uatomic_xchg(&channel->enabled, 0); if (!old) return -EEXIST; return 0; @@ -159,7 +269,7 @@ int ltt_event_enable(struct ltt_event *event) if (event->chan == event->chan->session->metadata) return -EPERM; - old = xchg(&event->enabled, 1); + old = uatomic_xchg(&event->enabled, 1); if (old) return -EEXIST; return 0; @@ -171,7 +281,7 @@ int ltt_event_disable(struct ltt_event *event) if (event->chan == event->chan->session->metadata) return -EPERM; - old = xchg(&event->enabled, 0); + old = uatomic_xchg(&event->enabled, 0); if (!old) return -EEXIST; return 0; @@ -181,7 +291,7 @@ static struct ltt_transport *ltt_transport_find(const char *name) { struct ltt_transport *transport; - list_for_each_entry(transport, <t_transport_list, node) { + cds_list_for_each_entry(transport, <t_transport_list, node) { if (!strcmp(transport->name, name)) return transport; } @@ -193,21 +303,22 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, void *buf_addr, size_t subbuf_size, size_t num_subbuf, unsigned int switch_timer_interval, - unsigned int read_timer_interval) + unsigned int read_timer_interval, + int *shm_fd, int *wait_fd, + uint64_t *memory_map_size) { struct ltt_channel *chan; struct ltt_transport *transport; - 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", + DBG("LTTng transport %s not found\n", transport_name); goto notransport; } - chan = kzalloc(sizeof(struct ltt_channel), GFP_KERNEL); + chan = zmalloc(sizeof(struct ltt_channel)); if (!chan) goto nomem; chan->session = session; @@ -217,23 +328,22 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, * headers. Therefore the "chan" information used as input * should be already accessible. */ - chan->chan = transport->ops.channel_create("[lttng]", chan, buf_addr, + transport->ops.channel_create("[lttng]", chan, buf_addr, subbuf_size, num_subbuf, switch_timer_interval, - read_timer_interval); + read_timer_interval, shm_fd, wait_fd, + memory_map_size); if (!chan->chan) goto create_error; chan->enabled = 1; chan->ops = &transport->ops; - list_add(&chan->list, &session->chan); - mutex_unlock(&sessions_mutex); + cds_list_add(&chan->list, &session->chan); return chan; create_error: - kfree(chan); + free(chan); nomem: notransport: active: - mutex_unlock(&sessions_mutex); return NULL; } @@ -243,94 +353,90 @@ active: static void _ltt_channel_destroy(struct ltt_channel *chan) { - chan->ops->channel_destroy(chan->chan); - list_del(&chan->list); + chan->ops->channel_destroy(chan); + cds_list_del(&chan->list); lttng_destroy_context(chan->ctx); - kfree(chan); + free(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, + struct lttng_ust_event *event_param, void *filter) { struct ltt_event *event; int ret; - mutex_lock(&sessions_mutex); - if (chan->free_event_id == -1UL) + if (chan->used_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)) + cds_list_for_each_entry(event, &chan->session->events, list) + if (event->desc && !strcmp(event->desc->name, event_param->name)) goto exist; - event = kmem_cache_zalloc(event_cache, GFP_KERNEL); + event = zmalloc(sizeof(struct ltt_event)); if (!event) goto cache_error; event->chan = chan; event->filter = filter; - event->id = chan->free_event_id++; + /* + * used_event_id counts the maximum number of event IDs that can + * register if all probes register. + */ + chan->used_event_id++; event->enabled = 1; event->instrumentation = event_param->instrumentation; /* Populate ltt_event structure before tracepoint registration. */ - smp_wmb(); + cmm_smp_wmb(); switch (event_param->instrumentation) { - case LTTNG_KERNEL_TRACEPOINT: + case LTTNG_UST_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_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); + if (event->desc) { + ret = __tracepoint_probe_register(event_param->name, + event->desc->probe_callback, + event); + if (ret) + goto register_error; + event->id = chan->free_event_id++; + } else { + /* + * If the probe is not present, event->desc stays NULL, + * waiting for the probe to register, and the event->id + * stays unallocated. + */ + ret = add_pending_probe(event, event_param->name); + if (ret) + goto add_pending_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); + if (event->desc) { + ret = _ltt_event_metadata_statedump(chan->session, chan, event); + if (ret) + goto statedump_error; + } + cds_list_add(&event->list, &chan->session->events); return event; statedump_error: - WARN_ON_ONCE(tracepoint_probe_unregister(event_param->name, - event->desc->probe_callback, - event)); - ltt_event_put(event->desc); + if (event->desc) { + WARN_ON_ONCE(__tracepoint_probe_unregister(event_param->name, + event->desc->probe_callback, + event)); + ltt_event_put(event->desc); + } +add_pending_error: register_error: - kmem_cache_free(event_cache, event); + free(event); cache_error: exist: full: - mutex_unlock(&sessions_mutex); return NULL; } @@ -342,20 +448,17 @@ 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_FUNCTION: - lttng_ftrace_unregister(event); - ret = 0; + case LTTNG_UST_TRACEPOINT: + if (event->desc) { + ret = __tracepoint_probe_unregister(event->desc->name, + event->desc->probe_callback, + event); + if (ret) + return ret; + } else { + remove_pending_probe(event->pending_probe); + ret = 0; + } break; default: WARN_ON_ONCE(1); @@ -370,47 +473,41 @@ 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_FUNCTION: - module_put(event->desc->owner); - lttng_ftrace_destroy_private(event); + case LTTNG_UST_TRACEPOINT: + if (event->desc) { + ltt_event_put(event->desc); + } break; default: WARN_ON_ONCE(1); } - list_del(&event->list); + cds_list_del(&event->list); lttng_destroy_context(event->ctx); - kmem_cache_free(event_cache, event); + free(event); } /* * We have exclusive access to our metadata buffer (protected by the - * sessions_mutex), so we can do racy operations such as looking for + * ust_lock), 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 lttng_ust_lib_ring_buffer_ctx ctx; struct ltt_channel *chan = session->metadata; - char *str; + char *str = NULL; int ret = 0, waitret; size_t len, reserve_len, pos; va_list ap; - WARN_ON_ONCE(!ACCESS_ONCE(session->active)); + WARN_ON_ONCE(!CMM_ACCESS_ONCE(session->active)); va_start(ap, fmt); - str = kvasprintf(GFP_KERNEL, fmt, ap); + ret = vasprintf(&str, fmt, ap); va_end(ap); - if (!str) + if (ret < 0) return -ENOMEM; len = strlen(str); @@ -418,27 +515,27 @@ int lttng_metadata_printf(struct ltt_session *session, for (pos = 0; pos < len; pos += reserve_len) { reserve_len = min_t(size_t, - chan->ops->packet_avail_size(chan->chan), + chan->ops->packet_avail_size(chan->chan, chan->handle), len - pos); lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len, - sizeof(char), -1); + sizeof(char), -1, chan->handle); /* * 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_reader_wait_queue(chan->chan), + waitret = wait_cond_interruptible_timeout( ({ 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" : + LTTNG_METADATA_TIMEOUT_MSEC); + if (waitret == -ETIMEDOUT || waitret == -EINTR || ret) { + DBG("LTTng: Failure to write metadata to buffers (%s)\n", + waitret == -EINTR ? "interrupted" : (ret == -ENOBUFS ? "timeout" : "I/O error")); - if (waitret == -ERESTARTSYS) + if (waitret == -EINTR) ret = waitret; goto end; } @@ -446,7 +543,7 @@ int lttng_metadata_printf(struct ltt_session *session, chan->ops->event_commit(&ctx); } end: - kfree(str); + free(str); return ret; } @@ -459,7 +556,7 @@ int _ltt_field_statedump(struct ltt_session *session, 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", + " 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, @@ -469,7 +566,20 @@ int _ltt_field_statedump(struct ltt_session *session, ? "UTF8" : "ASCII", field->type.u.basic.integer.base, -#ifdef __BIG_ENDIAN +#if (BYTE_ORDER == 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_float: + ret = lttng_metadata_printf(session, + " floating_point { exp_dig = %u; mant_dig = %u; align = %u;%s } _%s;\n", + field->type.u.basic._float.exp_dig, + field->type.u.basic._float.mant_dig, + field->type.u.basic._float.alignment, +#if (BYTE_ORDER == 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;" : "", @@ -488,7 +598,7 @@ int _ltt_field_statedump(struct ltt_session *session, 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", + " 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, @@ -498,7 +608,7 @@ int _ltt_field_statedump(struct ltt_session *session, ? "UTF8" : "ASCII", elem_type->u.basic.integer.base, -#ifdef __BIG_ENDIAN +#if (BYTE_ORDER == 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;" : "", @@ -524,7 +634,7 @@ int _ltt_field_statedump(struct ltt_session *session, ? "UTF8" : "ASCII"), length_type->u.basic.integer.base, -#ifdef __BIG_ENDIAN +#if (BYTE_ORDER == 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;" : "", @@ -534,7 +644,7 @@ int _ltt_field_statedump(struct ltt_session *session, return ret; ret = lttng_metadata_printf(session, - " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } %s[ __%s_length ];\n", + " 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, @@ -544,7 +654,7 @@ int _ltt_field_statedump(struct ltt_session *session, ? "UTF8" : "ASCII"), elem_type->u.basic.integer.base, -#ifdef __BIG_ENDIAN +#if (BYTE_ORDER == 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;" : "", @@ -557,7 +667,7 @@ int _ltt_field_statedump(struct ltt_session *session, case atype_string: /* Default encoding is UTF8 */ ret = lttng_metadata_printf(session, - " string%s %s;\n", + " string%s _%s;\n", field->type.u.basic.string.encoding == lttng_encode_ASCII ? " { encoding = ASCII; }" : "", field->name); @@ -613,10 +723,15 @@ int _ltt_event_metadata_statedump(struct ltt_session *session, { int ret = 0; - if (event->metadata_dumped || !ACCESS_ONCE(session->active)) + if (event->metadata_dumped || !CMM_ACCESS_ONCE(session->active)) return 0; if (chan == session->metadata) return 0; + /* + * Don't print events for which probe load is pending. + */ + if (!event->desc) + return 0; ret = lttng_metadata_printf(session, "event {\n" @@ -677,7 +792,7 @@ int _ltt_channel_metadata_statedump(struct ltt_session *session, { int ret = 0; - if (chan->metadata_dumped || !ACCESS_ONCE(session->active)) + if (chan->metadata_dumped || !CMM_ACCESS_ONCE(session->active)) return 0; if (chan == session->metadata) return 0; @@ -771,8 +886,8 @@ int _ltt_event_header_declare(struct ltt_session *session) " } extended;\n" " } v;\n" "} align(%u);\n\n", - ltt_alignof(uint32_t) * CHAR_BIT, - ltt_alignof(uint16_t) * CHAR_BIT + lttng_alignof(uint32_t) * CHAR_BIT, + lttng_alignof(uint16_t) * CHAR_BIT ); } @@ -782,18 +897,18 @@ int _ltt_event_header_declare(struct ltt_session *session) static int _ltt_session_metadata_statedump(struct ltt_session *session) { - unsigned char *uuid_c = session->uuid.b; - unsigned char uuid_s[37]; + unsigned char *uuid_c = session->uuid; + char uuid_s[37]; struct ltt_channel *chan; struct ltt_event *event; int ret = 0; - if (!ACCESS_ONCE(session->active)) + if (!CMM_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"); + DBG("LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n"); return -EPERM; } @@ -823,14 +938,14 @@ int _ltt_session_metadata_statedump(struct ltt_session *session) " 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, + 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 +#if (BYTE_ORDER == BIG_ENDIAN) "be" #else "le" @@ -848,13 +963,13 @@ int _ltt_session_metadata_statedump(struct ltt_session *session) goto end; skip_session: - list_for_each_entry(chan, &session->chan, list) { + cds_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) { + cds_list_for_each_entry(event, &session->events, list) { ret = _ltt_event_metadata_statedump(session, event->chan, event); if (ret) goto end; @@ -869,70 +984,27 @@ end: * @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. + * LTTng. Called with ust_lock held. */ 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); + cds_list_add_tail(&transport->node, <t_transport_list); } -EXPORT_SYMBOL_GPL(ltt_transport_register); /** * ltt_transport_unregister - LTT transport unregistration * @transport: transport structure + * Called with ust_lock held. */ void ltt_transport_unregister(struct ltt_transport *transport) { - mutex_lock(&sessions_mutex); - list_del(&transport->node); - mutex_unlock(&sessions_mutex); + cds_list_del(&transport->node); } -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 = ltt_debugfs_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) +void ltt_events_exit(void) { struct ltt_session *session, *tmpsession; - ltt_debugfs_abi_exit(); - list_for_each_entry_safe(session, tmpsession, &sessions, list) + cds_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");