Fix: non-enabler events should be disabled by default
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 2 Sep 2015 02:27:35 +0000 (22:27 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 2 Sep 2015 02:28:58 +0000 (22:28 -0400)
The session daemon expects that all events (enablers and events) are
disabled when created, so we can attach a filter before enabling them.

Also fix the kretprobe to ensure we can enable/disable both the entry
and return probe (--function instrumentation).

Fixes: #926
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lttng-events.c
lttng-events.h
probes/lttng-kretprobes.c

index c49174ddc0966e0977b2a9d62a680b3f67ad85b7..bd7b4efedba7d8522f81b2f7c54623155ebbe3c4 100644 (file)
@@ -329,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;
@@ -349,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;
@@ -538,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
@@ -562,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);
@@ -573,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;
                /*
@@ -608,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
@@ -626,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) {
index b3e94a0c60b670acd814c21010be72cc0c128b86..82b88e851769fe5ed813945921311d1ad72244b9 100644 (file)
@@ -681,6 +681,8 @@ int lttng_kretprobes_register(const char *name,
                struct lttng_event *event_exit);
 void lttng_kretprobes_unregister(struct lttng_event *event);
 void lttng_kretprobes_destroy_private(struct lttng_event *event);
+int lttng_kretprobes_event_enable_state(struct lttng_event *event,
+       int enable);
 #else
 static inline
 int lttng_kretprobes_register(const char *name,
@@ -702,6 +704,13 @@ static inline
 void lttng_kretprobes_destroy_private(struct lttng_event *event)
 {
 }
+
+static inline
+int lttng_kretprobes_event_enable_state(struct lttng_event *event,
+       int enable)
+{
+       return -ENOSYS;
+}
 #endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE
index d71090a2bc321edcac3695c774508c1d0d025655..52b3f78138f94978427eedc8e197175527270274 100644 (file)
@@ -285,6 +285,26 @@ void lttng_kretprobes_destroy_private(struct lttng_event *event)
 }
 EXPORT_SYMBOL_GPL(lttng_kretprobes_destroy_private);
 
+int lttng_kretprobes_event_enable_state(struct lttng_event *event,
+               int enable)
+{
+       struct lttng_event *event_return;
+       struct lttng_krp *lttng_krp;
+
+       if (event->instrumentation != LTTNG_KERNEL_KRETPROBE) {
+               return -EINVAL;
+       }
+       if (event->enabled == enable) {
+               return -EBUSY;
+       }
+       lttng_krp = event->u.kretprobe.lttng_krp;
+       event_return = lttng_krp->event[EVENT_RETURN];
+       ACCESS_ONCE(event->enabled) = enable;
+       ACCESS_ONCE(event_return->enabled) = enable;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_kretprobes_event_enable_state);
+
 MODULE_LICENSE("GPL and additional rights");
 MODULE_AUTHOR("Mathieu Desnoyers");
 MODULE_DESCRIPTION("Linux Trace Toolkit Kretprobes Support");
This page took 0.03002 seconds and 4 git commands to generate.