Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
* This ioctl implements lttng commands:
* LTTNG_KERNEL_CHANNEL
* Returns a LTTng channel file descriptor
* 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
*
* LTTNG_KERNEL_METADATA
* Returns a LTTng metadata file descriptor
*
(struct lttng_kernel_channel __user *) arg,
PER_CPU_CHANNEL);
case LTTNG_KERNEL_SESSION_START:
(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:
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,
case LTTNG_KERNEL_METADATA:
return lttng_abi_create_channel(file,
(struct lttng_kernel_channel __user *) arg,
* Returns an event file descriptor or failure.
* LTTNG_KERNEL_CONTEXT
* Prepend a context field to each event in the channel
* 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.
*/
*
* Channel and event file descriptors also hold a reference on the session.
*/
return lttng_abi_add_context(file,
(struct lttng_kernel_context __user *) arg,
&channel->ctx, channel->session);
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;
}
default:
return -ENOIOCTLCMD;
}
* @arg: command arg
*
* This ioctl implements lttng commands:
* @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_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)
*/
static
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);
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;
}
default:
return -ENOIOCTLCMD;
}
#define LTTNG_KERNEL_CONTEXT \
_IOW(0xF6, 0x70, 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 */
#endif /* _LTT_DEBUGFS_ABI_H */
-int ltt_session_start(struct ltt_session *session)
+int ltt_session_enable(struct ltt_session *session)
{
int ret = 0;
struct ltt_channel *chan;
{
int ret = 0;
struct ltt_channel *chan;
-int ltt_session_stop(struct ltt_session *session)
+int ltt_session_disable(struct ltt_session *session)
+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;
static struct ltt_transport *ltt_transport_find(const char *name)
{
struct ltt_transport *transport;
read_timer_interval);
if (!chan->chan)
goto create_error;
read_timer_interval);
if (!chan->chan)
goto create_error;
chan->ops = &transport->ops;
list_add(&chan->list, &session->chan);
mutex_unlock(&sessions_mutex);
chan->ops = &transport->ops;
list_add(&chan->list, &session->chan);
mutex_unlock(&sessions_mutex);
event->chan = chan;
event->filter = filter;
event->id = chan->free_event_id++;
event->chan = chan;
event->filter = filter;
event->id = chan->free_event_id++;
event->instrumentation = event_param->instrumentation;
/* Populate ltt_event structure before tracepoint registration. */
smp_wmb();
event->instrumentation = event_param->instrumentation;
/* Populate ltt_event structure before tracepoint registration. */
smp_wmb();
struct ltt_event {
unsigned int id;
struct ltt_channel *chan;
struct ltt_event {
unsigned int id;
struct ltt_channel *chan;
const struct lttng_event_desc *desc;
void *filter;
struct lttng_ctx *ctx;
const struct lttng_event_desc *desc;
void *filter;
struct lttng_ctx *ctx;
struct ltt_channel {
unsigned int id;
struct channel *chan; /* Channel buffers */
struct ltt_channel {
unsigned int id;
struct channel *chan; /* Channel buffers */
struct lttng_ctx *ctx;
/* Event ID management */
struct ltt_session *session;
struct lttng_ctx *ctx;
/* Event ID management */
struct ltt_session *session;
};
struct ltt_session *ltt_session_create(void);
};
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,
void ltt_session_destroy(struct ltt_session *session);
struct ltt_channel *ltt_channel_create(struct ltt_session *session,
struct lttng_kernel_event *event_param,
void *filter);
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);
void ltt_transport_register(struct ltt_transport *transport);
void ltt_transport_unregister(struct ltt_transport *transport);
\
if (0) \
(void) __dynamic_len_idx; /* don't warn if unused */ \
\
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); \
return; \
__event_len = __event_get_size__##_name(__dynamic_len, _args); \
__event_align = __event_get_align__##_name(_args); \
- if (!ACCESS_ONCE(chan->session->active))
+ if (unlikely(!ACCESS_ONCE(chan->session->active)))
+ 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);
lib_ring_buffer_ctx_init(&ctx, chan->chan, event,
sizeof(payload), ltt_alignof(payload), -1);
ret = chan->ops->event_reserve(&ctx, event->id);
int ret;
unsigned long data = (unsigned long) p->addr;
int ret;
unsigned long data = (unsigned long) p->addr;
- if (!ACCESS_ONCE(chan->session->active))
+ if (unlikely(!ACCESS_ONCE(chan->session->active)))
+ 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);
lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data),
ltt_alignof(data), -1);
ret = chan->ops->event_reserve(&ctx, event->id);