X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=lttng-events.c;h=9b3d766915fd4dcd78f564b1681497eccccf5b26;hb=9a0aa3b1fd7f693fc14b29cce9eb07cd275b0347;hp=eefee69b31a5cc59583fb57d7f074c5715aec654;hpb=20591cf76d5dfd42d61a18bd494b40a70a04dd59;p=lttng-modules.git diff --git a/lttng-events.c b/lttng-events.c index eefee69b..9b3d7669 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -20,6 +20,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* + * This page_alloc.h wrapper needs to be included before gfpflags.h because it + * overrides a function with a define. + */ +#include "wrapper/page_alloc.h" + #include #include #include @@ -96,8 +102,11 @@ struct lttng_session *lttng_session_create(void) goto err_free_cache; metadata_cache->cache_alloc = METADATA_CACHE_DEFAULT_SIZE; kref_init(&metadata_cache->refcount); + mutex_init(&metadata_cache->lock); session->metadata_cache = metadata_cache; INIT_LIST_HEAD(&metadata_cache->metadata_stream); + memcpy(&metadata_cache->uuid, &session->uuid, + sizeof(metadata_cache->uuid)); list_add(&session->list, &sessions); mutex_unlock(&sessions_mutex); return session; @@ -377,8 +386,14 @@ struct lttng_event *lttng_event_create(struct lttng_channel *chan, */ list_for_each_entry(event, &chan->session->events, list) { if (!strcmp(event->desc->name, event_param->name)) { - ret = -EEXIST; - goto exist; + /* + * Allow events with the same name to appear in + * different channels. + */ + if (event->chan == chan) { + ret = -EEXIST; + goto exist; + } } } event = kmem_cache_zalloc(event_cache, GFP_KERNEL); @@ -581,10 +596,12 @@ void _lttng_event_destroy(struct lttng_event *event) /* * Serialize at most one packet worth of metadata into a metadata * channel. - * 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. + * We grab the metadata cache mutex to get exclusive access to our metadata + * buffer and to the metadata cache. Exclusive access to the metadata buffer + * allows us to do racy operations such as looking for remaining space left in + * packet and write, since mutual exclusion protects us from concurrent writes. + * Mutual exclusion on the metadata cache allow us to read the cache content + * without racing against reallocation of the cache by updates. * Returns the number of bytes written in the channel, 0 if no data * was written and a negative value on error. */ @@ -596,17 +613,23 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, size_t len, reserve_len; /* - * Ensure we support mutiple get_next / put sequences followed - * by put_next. + * Ensure we support mutiple get_next / put sequences followed by + * put_next. The metadata cache lock protects reading the metadata + * cache. It can indeed be read concurrently by "get_next_subbuf" and + * "flush" operations on the buffer invoked by different processes. + * Moreover, since the metadata cache memory can be reallocated, we + * need to have exclusive access against updates even though we only + * read it. */ + mutex_lock(&stream->metadata_cache->lock); WARN_ON(stream->metadata_in < stream->metadata_out); if (stream->metadata_in != stream->metadata_out) - return 0; + goto end; len = stream->metadata_cache->metadata_written - stream->metadata_in; if (!len) - return 0; + goto end; reserve_len = min_t(size_t, stream->transport->ops.packet_avail_size(chan), len); @@ -628,12 +651,15 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, ret = reserve_len; end: + mutex_unlock(&stream->metadata_cache->lock); return ret; } /* * 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. */ int lttng_metadata_printf(struct lttng_session *session, const char *fmt, ...) @@ -652,6 +678,7 @@ int lttng_metadata_printf(struct lttng_session *session, return -ENOMEM; len = strlen(str); + mutex_lock(&session->metadata_cache->lock); if (session->metadata_cache->metadata_written + len > session->metadata_cache->cache_alloc) { char *tmp_cache_realloc; @@ -671,6 +698,7 @@ 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) @@ -679,6 +707,7 @@ int lttng_metadata_printf(struct lttng_session *session, return 0; err: + mutex_unlock(&session->metadata_cache->lock); kfree(str); return -ENOMEM; } @@ -1255,6 +1284,12 @@ static int __init lttng_events_init(void) { int ret; + ret = wrapper_lttng_fixup_sig(THIS_MODULE); + if (ret) + return ret; + ret = wrapper_get_pfnblock_flags_mask_init(); + if (ret) + return ret; ret = lttng_tracepoint_init(); if (ret) return ret;