Fix: non-enabler events should be disabled by default
[lttng-modules.git] / lttng-events.c
index 24a7b3ca9101464f774a4ec0cc5469d1224b96de..4b76ea03d72c5f7d31aadf975b2667072a07e857 100644 (file)
@@ -39,6 +39,7 @@
 #include "wrapper/file.h"
 #include <linux/jhash.h>
 #include <linux/uaccess.h>
+#include <linux/vmalloc.h>
 
 #include "wrapper/uuid.h"
 #include "wrapper/vmalloc.h"   /* for wrapper_vmalloc_sync_all() */
@@ -49,6 +50,7 @@
 #include "lttng-events.h"
 #include "lttng-tracer.h"
 #include "lttng-abi-old.h"
+#include "wrapper/vzalloc.h"
 
 #define METADATA_CACHE_DEFAULT_SIZE 4096
 
@@ -132,8 +134,7 @@ struct lttng_session *lttng_session_create(void)
                        GFP_KERNEL);
        if (!metadata_cache)
                goto err_free_session;
-       metadata_cache->data = kzalloc(METADATA_CACHE_DEFAULT_SIZE,
-                       GFP_KERNEL);
+       metadata_cache->data = lttng_vzalloc(METADATA_CACHE_DEFAULT_SIZE);
        if (!metadata_cache->data)
                goto err_free_cache;
        metadata_cache->cache_alloc = METADATA_CACHE_DEFAULT_SIZE;
@@ -163,7 +164,7 @@ void metadata_cache_destroy(struct kref *kref)
 {
        struct lttng_metadata_cache *cache =
                container_of(kref, struct lttng_metadata_cache, refcount);
-       kfree(cache->data);
+       vfree(cache->data);
        kfree(cache);
 }
 
@@ -328,8 +329,23 @@ int lttng_event_enable(struct lttng_event *event)
                ret = -EEXIST;
                goto end;
        }
-       ACCESS_ONCE(event->enabled) = 1;
-       lttng_session_sync_enablers(event->chan->session);
+       switch (event->instrumentation) {
+       case LTTNG_KERNEL_TRACEPOINT:
+       case LTTNG_KERNEL_SYSCALL:
+               ret = -EINVAL;
+               break;
+       case LTTNG_KERNEL_KPROBE:
+       case LTTNG_KERNEL_FUNCTION:
+       case LTTNG_KERNEL_NOOP:
+               ACCESS_ONCE(event->enabled) = 1;
+               break;
+       case LTTNG_KERNEL_KRETPROBE:
+               ret = lttng_kretprobes_event_enable_state(event, 1);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               ret = -EINVAL;
+       }
 end:
        mutex_unlock(&sessions_mutex);
        return ret;
@@ -348,8 +364,23 @@ int lttng_event_disable(struct lttng_event *event)
                ret = -EEXIST;
                goto end;
        }
-       ACCESS_ONCE(event->enabled) = 0;
-       lttng_session_sync_enablers(event->chan->session);
+       switch (event->instrumentation) {
+       case LTTNG_KERNEL_TRACEPOINT:
+       case LTTNG_KERNEL_SYSCALL:
+               ret = -EINVAL;
+               break;
+       case LTTNG_KERNEL_KPROBE:
+       case LTTNG_KERNEL_FUNCTION:
+       case LTTNG_KERNEL_NOOP:
+               ACCESS_ONCE(event->enabled) = 0;
+               break;
+       case LTTNG_KERNEL_KRETPROBE:
+               ret = lttng_kretprobes_event_enable_state(event, 0);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               ret = -EINVAL;
+       }
 end:
        mutex_unlock(&sessions_mutex);
        return ret;
@@ -537,7 +568,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
                smp_wmb();
                break;
        case LTTNG_KERNEL_KPROBE:
-               event->enabled = 1;
+               /*
+                * Needs to be explicitly enabled after creation, since
+                * we may want to apply filters.
+                */
+               event->enabled = 0;
                event->registered = 1;
                /*
                 * Populate lttng_event structure before event
@@ -561,7 +596,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
                struct lttng_event *event_return;
 
                /* kretprobe defines 2 events */
-               event->enabled = 1;
+               /*
+                * Needs to be explicitly enabled after creation, since
+                * we may want to apply filters.
+                */
+               event->enabled = 0;
                event->registered = 1;
                event_return =
                        kmem_cache_zalloc(event_cache, GFP_KERNEL);
@@ -572,7 +611,7 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
                event_return->chan = chan;
                event_return->filter = filter;
                event_return->id = chan->free_event_id++;
-               event_return->enabled = 1;
+               event_return->enabled = 0;
                event_return->registered = 1;
                event_return->instrumentation = itype;
                /*
@@ -607,7 +646,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
                break;
        }
        case LTTNG_KERNEL_FUNCTION:
-               event->enabled = 1;
+               /*
+                * Needs to be explicitly enabled after creation, since
+                * we may want to apply filters.
+                */
+               event->enabled = 0;
                event->registered = 1;
                /*
                 * Populate lttng_event structure before event
@@ -625,7 +668,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
                break;
        case LTTNG_KERNEL_NOOP:
        case LTTNG_KERNEL_SYSCALL:
-               event->enabled = 1;
+               /*
+                * Needs to be explicitly enabled after creation, since
+                * we may want to apply filters.
+                */
+               event->enabled = 0;
                event->registered = 0;
                event->desc = event_desc;
                if (!event->desc) {
@@ -1531,10 +1578,16 @@ int lttng_metadata_printf(struct lttng_session *session,
                tmp_cache_alloc_size = max_t(unsigned int,
                                session->metadata_cache->cache_alloc + len,
                                session->metadata_cache->cache_alloc << 1);
-               tmp_cache_realloc = krealloc(session->metadata_cache->data,
-                               tmp_cache_alloc_size, GFP_KERNEL);
+               tmp_cache_realloc = lttng_vzalloc(tmp_cache_alloc_size);
                if (!tmp_cache_realloc)
                        goto err;
+               if (session->metadata_cache->data) {
+                       memcpy(tmp_cache_realloc,
+                               session->metadata_cache->data,
+                               session->metadata_cache->cache_alloc);
+                       vfree(session->metadata_cache->data);
+               }
+
                session->metadata_cache->cache_alloc = tmp_cache_alloc_size;
                session->metadata_cache->data = tmp_cache_realloc;
        }
This page took 0.033553 seconds and 4 git commands to generate.