X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttng-events.c;h=631dfcb6689e0ef2bb346da8dd4a42a5681605dd;hb=30baa3ce479999c0c154acac7627f0006ae2af9d;hp=a85360912271c8725c4d59e329f4c3ea212ca6cf;hpb=cfa6cc1d0f01c2cfcc1a679abf3a6572d411c309;p=lttng-modules.git diff --git a/src/lttng-events.c b/src/lttng-events.c index a8536091..631dfcb6 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -214,8 +214,10 @@ void lttng_session_destroy(struct lttng_session *session) BUG_ON(chan->channel_type == METADATA_CHANNEL); _lttng_channel_destroy(chan); } + mutex_lock(&session->metadata_cache->lock); list_for_each_entry(metadata_stream, &session->metadata_cache->metadata_stream, list) _lttng_metadata_channel_hangup(metadata_stream); + mutex_unlock(&session->metadata_cache->lock); lttng_id_tracker_destroy(&session->pid_tracker, false); lttng_id_tracker_destroy(&session->vpid_tracker, false); lttng_id_tracker_destroy(&session->uid_tracker, false); @@ -500,12 +502,12 @@ struct lttng_channel *lttng_channel_create(struct lttng_session *session, 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", + 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"); + printk(KERN_WARNING "LTTng: Can't lock transport module.\n"); goto notransport; } chan = kzalloc(sizeof(struct lttng_channel), GFP_KERNEL); @@ -1318,7 +1320,7 @@ void lttng_create_tracepoint_if_missing(struct lttng_enabler *enabler) NULL, NULL, desc, LTTNG_KERNEL_TRACEPOINT); if (!event) { - printk(KERN_INFO "Unable to create event %s\n", + printk(KERN_INFO "LTTng: Unable to create event %s\n", probe_desc->event_desc[i]->name); } } @@ -1626,7 +1628,7 @@ void lttng_session_lazy_sync_enablers(struct lttng_session *session) * was written and a negative value on error. */ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, - struct channel *chan) + struct channel *chan, bool *coherent) { struct lib_ring_buffer_ctx ctx; int ret = 0; @@ -1665,6 +1667,7 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, ret = stream->transport->ops.event_reserve(&ctx, 0); if (ret != 0) { printk(KERN_WARNING "LTTng: Metadata event reservation failed\n"); + stream->coherent = false; goto end; } stream->transport->ops.event_write(&ctx, @@ -1672,18 +1675,46 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, reserve_len); stream->transport->ops.event_commit(&ctx); stream->metadata_in += reserve_len; + if (reserve_len < len) + stream->coherent = false; + else + stream->coherent = true; ret = reserve_len; end: + if (coherent) + *coherent = stream->coherent; mutex_unlock(&stream->metadata_cache->lock); return ret; } +static +void lttng_metadata_begin(struct lttng_session *session) +{ + if (atomic_inc_return(&session->metadata_cache->producing) == 1) + mutex_lock(&session->metadata_cache->lock); +} + +static +void lttng_metadata_end(struct lttng_session *session) +{ + WARN_ON_ONCE(!atomic_read(&session->metadata_cache->producing)); + if (atomic_dec_return(&session->metadata_cache->producing) == 0) { + struct lttng_metadata_stream *stream; + + list_for_each_entry(stream, &session->metadata_cache->metadata_stream, list) + wake_up_interruptible(&stream->read_wait); + mutex_unlock(&session->metadata_cache->lock); + } +} + /* * Write the metadata to the metadata cache. * Must be called with sessions_mutex held. * The metadata cache lock protects us from concurrent read access from * thread outputting metadata content to ring buffer. + * The content of the printf is printed as a single atomic metadata + * transaction. */ int lttng_metadata_printf(struct lttng_session *session, const char *fmt, ...) @@ -1691,7 +1722,6 @@ int lttng_metadata_printf(struct lttng_session *session, char *str; size_t len; va_list ap; - struct lttng_metadata_stream *stream; WARN_ON_ONCE(!READ_ONCE(session->active)); @@ -1702,7 +1732,7 @@ int lttng_metadata_printf(struct lttng_session *session, return -ENOMEM; len = strlen(str); - mutex_lock(&session->metadata_cache->lock); + WARN_ON_ONCE(!atomic_read(&session->metadata_cache->producing)); if (session->metadata_cache->metadata_written + len > session->metadata_cache->cache_alloc) { char *tmp_cache_realloc; @@ -1728,16 +1758,11 @@ int lttng_metadata_printf(struct lttng_session *session, session->metadata_cache->metadata_written, str, len); session->metadata_cache->metadata_written += len; - mutex_unlock(&session->metadata_cache->lock); kfree(str); - list_for_each_entry(stream, &session->metadata_cache->metadata_stream, list) - wake_up_interruptible(&stream->read_wait); - return 0; err: - mutex_unlock(&session->metadata_cache->lock); kfree(str); return -ENOMEM; } @@ -2312,6 +2337,8 @@ int _lttng_fields_metadata_statedump(struct lttng_session *session, /* * Must be called with sessions_mutex held. + * The entire event metadata is printed as a single atomic metadata + * transaction. */ static int _lttng_event_metadata_statedump(struct lttng_session *session, @@ -2325,6 +2352,8 @@ int _lttng_event_metadata_statedump(struct lttng_session *session, if (chan->channel_type == METADATA_CHANNEL) return 0; + lttng_metadata_begin(session); + ret = lttng_metadata_printf(session, "event {\n" " name = \"%s\";\n" @@ -2374,12 +2403,15 @@ int _lttng_event_metadata_statedump(struct lttng_session *session, event->metadata_dumped = 1; end: + lttng_metadata_end(session); return ret; } /* * Must be called with sessions_mutex held. + * The entire channel metadata is printed as a single atomic metadata + * transaction. */ static int _lttng_channel_metadata_statedump(struct lttng_session *session, @@ -2393,6 +2425,8 @@ int _lttng_channel_metadata_statedump(struct lttng_session *session, if (chan->channel_type == METADATA_CHANNEL) return 0; + lttng_metadata_begin(session); + WARN_ON_ONCE(!chan->header_type); ret = lttng_metadata_printf(session, "stream {\n" @@ -2426,6 +2460,7 @@ int _lttng_channel_metadata_statedump(struct lttng_session *session, chan->metadata_dumped = 1; end: + lttng_metadata_end(session); return ret; } @@ -2613,6 +2648,9 @@ int _lttng_session_metadata_statedump(struct lttng_session *session) if (!READ_ONCE(session->active)) return 0; + + lttng_metadata_begin(session); + if (session->metadata_dumped) goto skip_session; @@ -2785,6 +2823,7 @@ skip_session: } session->metadata_dumped = 1; end: + lttng_metadata_end(session); return ret; } @@ -3071,7 +3110,7 @@ static void __exit lttng_events_exit(void) module_exit(lttng_events_exit); -#include +#include #ifdef LTTNG_EXTRA_VERSION_GIT MODULE_INFO(extra_version_git, LTTNG_EXTRA_VERSION_GIT); #endif