Fix: handle concurrent flush vs get_next_subbuf on metadata cache
[lttng-modules.git] / lttng-events.c
index ff28c9af559aecff2d5952a6f5fe9a43e2e343fe..1fecff8efc279a76de3c8344f23236d485f7e5b8 100644 (file)
@@ -400,7 +400,7 @@ struct lttng_event *lttng_event_create(struct lttng_channel *chan,
                        ret = -ENOENT;
                        goto register_error;
                }
-               ret = kabi_2635_tracepoint_probe_register(event->desc->kname,
+               ret = lttng_wrapper_tracepoint_probe_register(event->desc->kname,
                                event->desc->probe_callback,
                                event);
                if (ret) {
@@ -519,7 +519,7 @@ int _lttng_event_unregister(struct lttng_event *event)
 
        switch (event->instrumentation) {
        case LTTNG_KERNEL_TRACEPOINT:
-               ret = kabi_2635_tracepoint_probe_unregister(event->desc->kname,
+               ret = lttng_wrapper_tracepoint_probe_unregister(event->desc->kname,
                                                  event->desc->probe_callback,
                                                  event);
                if (ret)
@@ -597,16 +597,20 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream,
 
        /*
         * Ensure we support mutiple get_next / put sequences followed
-        * by put_next.
+        * by put_next. The metadata stream lock internally 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.
         */
+       mutex_lock(&stream->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,6 +632,7 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream,
        ret = reserve_len;
 
 end:
+       mutex_unlock(&stream->lock);
        return ret;
 }
 
@@ -1255,9 +1260,18 @@ static int __init lttng_events_init(void)
 {
        int ret;
 
+       ret = wrapper_lttng_fixup_sig(THIS_MODULE);
+       if (ret)
+               return ret;
+
+       ret = lttng_tracepoint_init();
+       if (ret)
+               return ret;
        event_cache = KMEM_CACHE(lttng_event, 0);
-       if (!event_cache)
-               return -ENOMEM;
+       if (!event_cache) {
+               ret = -ENOMEM;
+               goto error_kmem;
+       }
        ret = lttng_abi_init();
        if (ret)
                goto error_abi;
@@ -1270,6 +1284,8 @@ error_logger:
        lttng_abi_exit();
 error_abi:
        kmem_cache_destroy(event_cache);
+error_kmem:
+       lttng_tracepoint_exit();
        return ret;
 }
 
@@ -1284,6 +1300,7 @@ static void __exit lttng_events_exit(void)
        list_for_each_entry_safe(session, tmpsession, &sessions, list)
                lttng_session_destroy(session);
        kmem_cache_destroy(event_cache);
+       lttng_tracepoint_exit();
 }
 
 module_exit(lttng_events_exit);
This page took 0.026027 seconds and 4 git commands to generate.