Add enable/disable per event/channel/session (new ABI)
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 22 Jun 2011 19:51:06 +0000 (15:51 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 22 Jun 2011 19:51:06 +0000 (15:51 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
ltt-debugfs-abi.c
ltt-debugfs-abi.h
ltt-events.c
ltt-events.h
probes/lttng-events.h
probes/lttng-ftrace.c
probes/lttng-kprobes.c

index e3f5b55df1219bb2f9ae76313d6532d0bb712f9e..53cc35d673c5e65a943e2dfea6ccbec96918ba8d 100644 (file)
@@ -330,10 +330,10 @@ fd_error:
  *     This ioctl implements lttng commands:
  *     LTTNG_KERNEL_CHANNEL
  *             Returns a LTTng channel file descriptor
- *     LTTNG_KERNEL_SESSION_START
- *             Starts tracing session
- *     LTTNG_KERNEL_SESSION_STOP
- *             Stops tracing session
+ *     LTTNG_KERNEL_ENABLE
+ *             Enables tracing for a session (weak enable)
+ *     LTTNG_KERNEL_DISABLE
+ *             Disables tracing for a session (strong disable)
  *     LTTNG_KERNEL_METADATA
  *             Returns a LTTng metadata file descriptor
  *
@@ -350,9 +350,11 @@ long lttng_session_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                (struct lttng_kernel_channel __user *) arg,
                                PER_CPU_CHANNEL);
        case LTTNG_KERNEL_SESSION_START:
-               return ltt_session_start(session);
+       case LTTNG_KERNEL_ENABLE:
+               return ltt_session_enable(session);
        case LTTNG_KERNEL_SESSION_STOP:
-               return ltt_session_stop(session);
+       case LTTNG_KERNEL_DISABLE:
+               return ltt_session_disable(session);
        case LTTNG_KERNEL_METADATA:
                return lttng_abi_create_channel(file,
                                (struct lttng_kernel_channel __user *) arg,
@@ -506,6 +508,10 @@ fd_error:
  *             Returns an event file descriptor or failure.
  *     LTTNG_KERNEL_CONTEXT
  *             Prepend a context field to each event in the channel
+ *     LTTNG_KERNEL_ENABLE
+ *             Enable recording for events in this channel (weak enable)
+ *     LTTNG_KERNEL_DISABLE
+ *             Disable recording for events in this channel (strong disable)
  *
  * Channel and event file descriptors also hold a reference on the session.
  */
@@ -523,6 +529,10 @@ long lttng_channel_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                return lttng_abi_add_context(file,
                                (struct lttng_kernel_context __user *) arg,
                                &channel->ctx, channel->session);
+       case LTTNG_KERNEL_ENABLE:
+               return ltt_channel_enable(channel);
+       case LTTNG_KERNEL_DISABLE:
+               return ltt_channel_disable(channel);
        default:
                return -ENOIOCTLCMD;
        }
@@ -614,13 +624,12 @@ static const struct file_operations lttng_metadata_fops = {
  *     @arg: command arg
  *
  *     This ioctl implements lttng commands:
- *      LTTNG_KERNEL_STREAM
- *              Returns an event stream file descriptor or failure.
- *              (typically, one event stream records events from one CPU)
- *     LTTNG_KERNEL_EVENT
- *             Returns an event file descriptor or failure.
  *     LTTNG_KERNEL_CONTEXT
  *             Prepend a context field to each record of this event
+ *     LTTNG_KERNEL_ENABLE
+ *             Enable recording for this event (weak enable)
+ *     LTTNG_KERNEL_DISABLE
+ *             Disable recording for this event (strong disable)
  */
 static
 long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -632,6 +641,10 @@ long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                return lttng_abi_add_context(file,
                                (struct lttng_kernel_context __user *) arg,
                                &event->ctx, event->chan->session);
+       case LTTNG_KERNEL_ENABLE:
+               return ltt_event_enable(event);
+       case LTTNG_KERNEL_DISABLE:
+               return ltt_event_disable(event);
        default:
                return -ENOIOCTLCMD;
        }
index 87be71bddc9e406128dc0b4c0a3efc198e1fb3c8..dd38507ee252ab9e75d356f6286d08263872af38 100644 (file)
@@ -107,4 +107,8 @@ struct lttng_kernel_context {
 #define LTTNG_KERNEL_CONTEXT                   \
        _IOW(0xF6, 0x70, struct lttng_kernel_context)
 
+/* Event, Channel and Session ioctl */
+#define LTTNG_KERNEL_ENABLE                    _IO(0xF6, 0x80)
+#define LTTNG_KERNEL_DISABLE                   _IO(0xF6, 0x81)
+
 #endif /* _LTT_DEBUGFS_ABI_H */
index 40e8e459183efacae2744fcc6a6071bd9625e5b1..a94e8f9a1dde6a6e315133e59c66e3659455f99d 100644 (file)
@@ -82,7 +82,7 @@ void ltt_session_destroy(struct ltt_session *session)
        kfree(session);
 }
 
-int ltt_session_start(struct ltt_session *session)
+int ltt_session_enable(struct ltt_session *session)
 {
        int ret = 0;
        struct ltt_channel *chan;
@@ -119,7 +119,7 @@ end:
        return ret;
 }
 
-int ltt_session_stop(struct ltt_session *session)
+int ltt_session_disable(struct ltt_session *session)
 {
        int ret = 0;
 
@@ -135,6 +135,46 @@ end:
        return ret;
 }
 
+int ltt_channel_enable(struct ltt_channel *channel)
+{
+       int old;
+
+       old = xchg(&channel->enabled, 1);
+       if (old)
+               return -EEXIST;
+       return 0;
+}
+
+int ltt_channel_disable(struct ltt_channel *channel)
+{
+       int old;
+
+       old = xchg(&channel->enabled, 0);
+       if (!old)
+               return -EEXIST;
+       return 0;
+}
+
+int ltt_event_enable(struct ltt_event *event)
+{
+       int old;
+
+       old = xchg(&event->enabled, 1);
+       if (old)
+               return -EEXIST;
+       return 0;
+}
+
+int ltt_event_disable(struct ltt_event *event)
+{
+       int old;
+
+       old = xchg(&event->enabled, 0);
+       if (!old)
+               return -EEXIST;
+       return 0;
+}
+
 static struct ltt_transport *ltt_transport_find(const char *name)
 {
        struct ltt_transport *transport;
@@ -180,6 +220,7 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session,
                        read_timer_interval);
        if (!chan->chan)
                goto create_error;
+       chan->enabled = 1;
        chan->ops = &transport->ops;
        list_add(&chan->list, &session->chan);
        mutex_unlock(&sessions_mutex);
@@ -232,6 +273,7 @@ struct ltt_event *ltt_event_create(struct ltt_channel *chan,
        event->chan = chan;
        event->filter = filter;
        event->id = chan->free_event_id++;
+       event->enabled = 1;
        event->instrumentation = event_param->instrumentation;
        /* Populate ltt_event structure before tracepoint registration. */
        smp_wmb();
index 05eff540726defe0b8e14d3a8c28785e65aef8bc..787868a99156bae9f960c86670e9ade05f56512e 100644 (file)
@@ -164,6 +164,7 @@ struct lttng_probe_desc {
 struct ltt_event {
        unsigned int id;
        struct ltt_channel *chan;
+       int enabled;
        const struct lttng_event_desc *desc;
        void *filter;
        struct lttng_ctx *ctx;
@@ -211,6 +212,7 @@ struct ltt_channel_ops {
 struct ltt_channel {
        unsigned int id;
        struct channel *chan;           /* Channel buffers */
+       int enabled;
        struct lttng_ctx *ctx;
        /* Event ID management */
        struct ltt_session *session;
@@ -243,8 +245,8 @@ struct ltt_transport {
 };
 
 struct ltt_session *ltt_session_create(void);
-int ltt_session_start(struct ltt_session *session);
-int ltt_session_stop(struct ltt_session *session);
+int ltt_session_enable(struct ltt_session *session);
+int ltt_session_disable(struct ltt_session *session);
 void ltt_session_destroy(struct ltt_session *session);
 
 struct ltt_channel *ltt_channel_create(struct ltt_session *session,
@@ -263,6 +265,11 @@ struct ltt_event *ltt_event_create(struct ltt_channel *chan,
                                   struct lttng_kernel_event *event_param,
                                   void *filter);
 
+int ltt_channel_enable(struct ltt_channel *channel);
+int ltt_channel_disable(struct ltt_channel *channel);
+int ltt_event_enable(struct ltt_event *event);
+int ltt_event_disable(struct ltt_event *event);
+
 void ltt_transport_register(struct ltt_transport *transport);
 void ltt_transport_unregister(struct ltt_transport *transport);
 
index 16e268044aefda3a77534605f6b67198ecc56474..f97804859c2f8ebffbcd3e98346de102cb90d21d 100644 (file)
@@ -529,7 +529,11 @@ static void __event_probe__##_name(void *__data, _proto)                 \
                                                                              \
        if (0)                                                                \
                (void) __dynamic_len_idx;       /* don't warn if unused */    \
-       if (!ACCESS_ONCE(__chan->session->active))                            \
+       if (unlikely(!ACCESS_ONCE(__chan->session->active)))                  \
+               return;                                                       \
+       if (unlikely(!ACCESS_ONCE(__chan->enabled)))                          \
+               return;                                                       \
+       if (unlikely(!ACCESS_ONCE(__event->enabled)))                         \
                return;                                                       \
        __event_len = __event_get_size__##_name(__dynamic_len, _args);        \
        __event_align = __event_get_align__##_name(_args);                    \
index b8bd344749b201ecec08b6e93ebcba2715fb08f7..1aa71831e86fd4bd21780278bb78d385f79ebc8b 100644 (file)
@@ -38,8 +38,13 @@ void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data
        } payload;
        int ret;
 
-       if (!ACCESS_ONCE(chan->session->active))
+       if (unlikely(!ACCESS_ONCE(chan->session->active)))
                return;
+       if (unlikely(!ACCESS_ONCE(chan->enabled)))
+               return;
+       if (unlikely(!ACCESS_ONCE(event->enabled)))
+               return;
+
        lib_ring_buffer_ctx_init(&ctx, chan->chan, event,
                                 sizeof(payload), ltt_alignof(payload), -1);
        ret = chan->ops->event_reserve(&ctx, event->id);
index 89cfe07364779f6a2094979b16c6f039252fac89..38ee4513811691273de7454f0415ee56c6da44ce 100644 (file)
@@ -25,8 +25,13 @@ int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs)
        int ret;
        unsigned long data = (unsigned long) p->addr;
 
-       if (!ACCESS_ONCE(chan->session->active))
+       if (unlikely(!ACCESS_ONCE(chan->session->active)))
                return 0;
+       if (unlikely(!ACCESS_ONCE(chan->enabled)))
+               return 0;
+       if (unlikely(!ACCESS_ONCE(event->enabled)))
+               return 0;
+
        lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data),
                                 ltt_alignof(data), -1);
        ret = chan->ops->event_reserve(&ctx, event->id);
This page took 0.030899 seconds and 4 git commands to generate.