X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttng-events.c;h=4cb0f037e174e8aea12dfca0d2cb6a47368d2a1e;hb=e978f27486ddac0b9cbea5577fc413c67bc61141;hp=0c5b49d981bb6a864061277c282d4d24fc78877c;hpb=0648898e20d4fa769d5e7abd2591dab218888868;p=lttng-modules.git diff --git a/src/lttng-events.c b/src/lttng-events.c index 0c5b49d9..4cb0f037 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -89,7 +89,7 @@ int _lttng_type_statedump(struct lttng_session *session, static int _lttng_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting); + size_t nesting, const char **prev_field_name_p); void synchronize_trace(void) { @@ -603,57 +603,37 @@ end: return ret; } -int lttng_event_enable(struct lttng_kernel_event_recorder *event_recorder) +int lttng_event_enable(struct lttng_kernel_event_common *event) { - struct lttng_kernel_event_common *event = &event_recorder->parent; int ret = 0; mutex_lock(&sessions_mutex); - if (event_recorder->chan->channel_type == METADATA_CHANNEL) { - ret = -EPERM; - goto end; - } - if (event->enabled) { - ret = -EEXIST; - goto end; - } - switch (event->priv->instrumentation) { - case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */ - case LTTNG_KERNEL_ABI_SYSCALL: - ret = -EINVAL; - break; + switch (event->type) { + case LTTNG_KERNEL_EVENT_TYPE_RECORDER: + { + struct lttng_kernel_event_recorder *event_recorder = + container_of(event, struct lttng_kernel_event_recorder, parent); - case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ - case LTTNG_KERNEL_ABI_UPROBE: - WRITE_ONCE(event->enabled, 1); + if (event_recorder->chan->channel_type == METADATA_CHANNEL) { + ret = -EPERM; + goto end; + } break; - - case LTTNG_KERNEL_ABI_KRETPROBE: - ret = lttng_kretprobes_event_enable_state(event_recorder, 1); + } + case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER: + switch (event->priv->instrumentation) { + case LTTNG_KERNEL_ABI_KRETPROBE: + ret = -EINVAL; + goto end; + default: + break; + } break; - - case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ - case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */ default: - WARN_ON_ONCE(1); - ret = -EINVAL; + break; } -end: - mutex_unlock(&sessions_mutex); - return ret; -} - -int lttng_event_disable(struct lttng_kernel_event_recorder *event_recorder) -{ - struct lttng_kernel_event_common *event = &event_recorder->parent; - int ret = 0; - mutex_lock(&sessions_mutex); - if (event_recorder->chan->channel_type == METADATA_CHANNEL) { - ret = -EPERM; - goto end; - } - if (!event->enabled) { + if (event->enabled) { ret = -EEXIST; goto end; } @@ -665,12 +645,11 @@ int lttng_event_disable(struct lttng_kernel_event_recorder *event_recorder) case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ case LTTNG_KERNEL_ABI_UPROBE: - WRITE_ONCE(event->enabled, 0); + WRITE_ONCE(event->enabled, 1); break; case LTTNG_KERNEL_ABI_KRETPROBE: - - ret = lttng_kretprobes_event_enable_state(event_recorder, 0); + ret = lttng_kretprobes_event_enable_state(event, 1); break; case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ @@ -684,45 +663,36 @@ end: return ret; } -int lttng_event_notifier_enable(struct lttng_kernel_event_notifier *event_notifier) +int lttng_event_disable(struct lttng_kernel_event_common *event) { - struct lttng_kernel_event_common *event = &event_notifier->parent; int ret = 0; mutex_lock(&sessions_mutex); - if (event->enabled) { - ret = -EEXIST; - goto end; - } - switch (event->priv->instrumentation) { - case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */ - case LTTNG_KERNEL_ABI_SYSCALL: - ret = -EINVAL; - break; + switch (event->type) { + case LTTNG_KERNEL_EVENT_TYPE_RECORDER: + { + struct lttng_kernel_event_recorder *event_recorder = + container_of(event, struct lttng_kernel_event_recorder, parent); - case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ - case LTTNG_KERNEL_ABI_UPROBE: - WRITE_ONCE(event->enabled, 1); + if (event_recorder->chan->channel_type == METADATA_CHANNEL) { + ret = -EPERM; + goto end; + } + break; + } + case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER: + switch (event->priv->instrumentation) { + case LTTNG_KERNEL_ABI_KRETPROBE: + ret = -EINVAL; + goto end; + default: + break; + } break; - - case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ - case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */ - case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */ default: - WARN_ON_ONCE(1); - ret = -EINVAL; + break; } -end: - mutex_unlock(&sessions_mutex); - return ret; -} -int lttng_event_notifier_disable(struct lttng_kernel_event_notifier *event_notifier) -{ - struct lttng_kernel_event_common *event = &event_notifier->parent; - int ret = 0; - - mutex_lock(&sessions_mutex); if (!event->enabled) { ret = -EEXIST; goto end; @@ -738,8 +708,11 @@ int lttng_event_notifier_disable(struct lttng_kernel_event_notifier *event_notif WRITE_ONCE(event->enabled, 0); break; + case LTTNG_KERNEL_ABI_KRETPROBE: + ret = lttng_kretprobes_event_enable_state(event, 0); + break; + case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ - case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */ case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */ default: WARN_ON_ONCE(1); @@ -912,6 +885,7 @@ struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct l event_recorder->parent.priv = &event_recorder_priv->parent; event_recorder->parent.type = LTTNG_KERNEL_EVENT_TYPE_RECORDER; + event_recorder->parent.run_filter = lttng_kernel_interpret_event_filter; event_recorder->chan = chan; event_recorder->priv->id = chan->free_event_id++; event_recorder->priv->parent.instrumentation = itype; @@ -987,6 +961,7 @@ struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct l event_recorder_return->parent.priv = &event_recorder_return_priv->parent; event_recorder_return->parent.type = LTTNG_KERNEL_EVENT_TYPE_RECORDER; + event_recorder_return->parent.run_filter = lttng_kernel_interpret_event_filter; event_recorder_return->chan = chan; event_recorder_return->priv->id = chan->free_event_id++; event_recorder_return->priv->parent.instrumentation = itype; @@ -1188,6 +1163,7 @@ struct lttng_kernel_event_notifier *_lttng_event_notifier_create( INIT_LIST_HEAD(&event_notifier->priv->parent.filter_bytecode_runtime_head); INIT_LIST_HEAD(&event_notifier->priv->parent.enablers_ref_head); INIT_LIST_HEAD(&event_notifier->priv->capture_bytecode_runtime_head); + event_notifier->parent.run_filter = lttng_kernel_interpret_event_filter; switch (itype) { case LTTNG_KERNEL_ABI_TRACEPOINT: @@ -1497,7 +1473,7 @@ void register_event_notifier(struct lttng_kernel_event_notifier *event_notifier) switch (event_notifier->priv->parent.instrumentation) { case LTTNG_KERNEL_ABI_TRACEPOINT: ret = lttng_wrapper_tracepoint_probe_register(desc->event_kname, - desc->event_notifier_callback, + desc->probe_callback, event_notifier); break; @@ -1534,7 +1510,7 @@ int _lttng_event_notifier_unregister( switch (event_notifier->priv->parent.instrumentation) { case LTTNG_KERNEL_ABI_TRACEPOINT: ret = lttng_wrapper_tracepoint_probe_unregister(event_notifier->priv->parent.desc->event_kname, - event_notifier->priv->parent.desc->event_notifier_callback, + event_notifier->priv->parent.desc->probe_callback, event_notifier); break; @@ -2473,7 +2449,7 @@ static int lttng_enabler_attach_filter_bytecode(struct lttng_enabler *enabler, struct lttng_kernel_abi_filter_bytecode __user *bytecode) { - struct lttng_bytecode_node *bytecode_node; + struct lttng_kernel_bytecode_node *bytecode_node; uint32_t bytecode_len; int ret; @@ -2489,7 +2465,7 @@ int lttng_enabler_attach_filter_bytecode(struct lttng_enabler *enabler, if (ret) goto error_free; - bytecode_node->type = LTTNG_BYTECODE_NODE_TYPE_FILTER; + bytecode_node->type = LTTNG_KERNEL_BYTECODE_TYPE_FILTER; bytecode_node->enabler = enabler; /* Enforce length based on allocated size */ bytecode_node->bc.len = bytecode_len; @@ -2518,13 +2494,13 @@ error: return ret; } -int lttng_event_add_callsite(struct lttng_kernel_event_recorder *event_recorder, +int lttng_event_add_callsite(struct lttng_kernel_event_common *event, struct lttng_kernel_abi_event_callsite __user *callsite) { - switch (event_recorder->priv->parent.instrumentation) { + switch (event->priv->instrumentation) { case LTTNG_KERNEL_ABI_UPROBE: - return lttng_uprobes_event_add_callsite(event_recorder, callsite); + return lttng_uprobes_event_add_callsite(event, callsite); default: return -EINVAL; } @@ -2533,7 +2509,7 @@ int lttng_event_add_callsite(struct lttng_kernel_event_recorder *event_recorder, static void lttng_enabler_destroy(struct lttng_enabler *enabler) { - struct lttng_bytecode_node *filter_node, *tmp_filter_node; + struct lttng_kernel_bytecode_node *filter_node, *tmp_filter_node; /* Destroy filter bytecode */ list_for_each_entry_safe(filter_node, tmp_filter_node, @@ -2628,7 +2604,7 @@ int lttng_event_notifier_enabler_attach_capture_bytecode( struct lttng_event_notifier_enabler *event_notifier_enabler, struct lttng_kernel_abi_capture_bytecode __user *bytecode) { - struct lttng_bytecode_node *bytecode_node; + struct lttng_kernel_bytecode_node *bytecode_node; struct lttng_enabler *enabler = lttng_event_notifier_enabler_as_enabler(event_notifier_enabler); uint32_t bytecode_len; @@ -2648,7 +2624,7 @@ int lttng_event_notifier_enabler_attach_capture_bytecode( if (ret) goto error_free; - bytecode_node->type = LTTNG_BYTECODE_NODE_TYPE_CAPTURE; + bytecode_node->type = LTTNG_KERNEL_BYTECODE_TYPE_CAPTURE; bytecode_node->enabler = enabler; /* Enforce length based on allocated size */ @@ -2666,19 +2642,6 @@ end: return ret; } -int lttng_event_notifier_add_callsite(struct lttng_kernel_event_notifier *event_notifier, - struct lttng_kernel_abi_event_callsite __user *callsite) -{ - - switch (event_notifier->priv->parent.instrumentation) { - case LTTNG_KERNEL_ABI_UPROBE: - return lttng_uprobes_event_notifier_add_callsite(event_notifier, - callsite); - default: - return -EINVAL; - } -} - static void lttng_event_notifier_enabler_destroy( struct lttng_event_notifier_enabler *event_notifier_enabler) @@ -2714,8 +2677,9 @@ void lttng_session_sync_event_enablers(struct lttng_session *session) list_for_each_entry(event_recorder_priv, &session->events, node) { struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub; struct lttng_enabler_ref *enabler_ref; - struct lttng_bytecode_runtime *runtime; - int enabled = 0, has_enablers_without_bytecode = 0; + struct lttng_kernel_bytecode_runtime *runtime; + int enabled = 0, has_enablers_without_filter_bytecode = 0; + int nr_filters = 0; switch (event_recorder_priv->parent.instrumentation) { case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */ @@ -2757,17 +2721,21 @@ void lttng_session_sync_event_enablers(struct lttng_session *session) &event_recorder_priv->parent.enablers_ref_head, node) { if (enabler_ref->ref->enabled && list_empty(&enabler_ref->ref->filter_bytecode_head)) { - has_enablers_without_bytecode = 1; + has_enablers_without_filter_bytecode = 1; break; } } event_recorder_priv->parent.has_enablers_without_filter_bytecode = - has_enablers_without_bytecode; + has_enablers_without_filter_bytecode; /* Enable filters */ list_for_each_entry(runtime, - &event_recorder_priv->parent.filter_bytecode_runtime_head, node) - lttng_bytecode_filter_sync_state(runtime); + &event_recorder_priv->parent.filter_bytecode_runtime_head, node) { + lttng_bytecode_sync_state(runtime); + nr_filters++; + } + WRITE_ONCE(event_recorder_priv->parent.pub->eval_filter, + !(has_enablers_without_filter_bytecode || !nr_filters)); } } @@ -2803,8 +2771,9 @@ void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group list_for_each_entry(event_notifier_priv, &event_notifier_group->event_notifiers_head, node) { struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub; struct lttng_enabler_ref *enabler_ref; - struct lttng_bytecode_runtime *runtime; - int enabled = 0, has_enablers_without_bytecode = 0; + struct lttng_kernel_bytecode_runtime *runtime; + int enabled = 0, has_enablers_without_filter_bytecode = 0; + int nr_filters = 0, nr_captures = 0; switch (event_notifier_priv->parent.instrumentation) { case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */ @@ -2842,24 +2811,29 @@ void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group &event_notifier_priv->parent.enablers_ref_head, node) { if (enabler_ref->ref->enabled && list_empty(&enabler_ref->ref->filter_bytecode_head)) { - has_enablers_without_bytecode = 1; + has_enablers_without_filter_bytecode = 1; break; } } event_notifier_priv->parent.has_enablers_without_filter_bytecode = - has_enablers_without_bytecode; + has_enablers_without_filter_bytecode; /* Enable filters */ list_for_each_entry(runtime, - &event_notifier_priv->parent.filter_bytecode_runtime_head, node) - lttng_bytecode_filter_sync_state(runtime); + &event_notifier_priv->parent.filter_bytecode_runtime_head, node) { + lttng_bytecode_sync_state(runtime); + nr_filters++; + } + WRITE_ONCE(event_notifier_priv->parent.pub->eval_filter, + !(has_enablers_without_filter_bytecode || !nr_filters)); /* Enable captures */ list_for_each_entry(runtime, - &event_notifier_priv->capture_bytecode_runtime_head, node) - lttng_bytecode_capture_sync_state(runtime); - - WRITE_ONCE(event_notifier->eval_capture, !!event_notifier_priv->num_captures); + &event_notifier_priv->capture_bytecode_runtime_head, node) { + lttng_bytecode_sync_state(runtime); + nr_captures++; + } + WRITE_ONCE(event_notifier->eval_capture, !!nr_captures); } } @@ -2907,12 +2881,12 @@ int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, reserve_len = min_t(size_t, stream->transport->ops.packet_avail_size(chan), len); - lib_ring_buffer_ctx_init(&ctx, chan, NULL, reserve_len, - sizeof(char), -1); + lib_ring_buffer_ctx_init(&ctx, chan, reserve_len, + sizeof(char), NULL); /* * If reservation failed, return an error to the caller. */ - ret = stream->transport->ops.event_reserve(&ctx, 0); + ret = stream->transport->ops.event_reserve(&ctx); if (ret != 0) { printk(KERN_WARNING "LTTng: Metadata event reservation failed\n"); stream->coherent = false; @@ -3078,6 +3052,7 @@ int _lttng_struct_type_statedump(struct lttng_session *session, const struct lttng_kernel_type_struct *type, size_t nesting) { + const char *prev_field_name = NULL; int ret; uint32_t i, nr_fields; unsigned int alignment; @@ -3094,7 +3069,7 @@ int _lttng_struct_type_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *iter_field; iter_field = type->fields[i]; - ret = _lttng_field_statedump(session, iter_field, nesting + 1); + ret = _lttng_field_statedump(session, iter_field, nesting + 1, &prev_field_name); if (ret) return ret; } @@ -3136,11 +3111,18 @@ int _lttng_struct_field_statedump(struct lttng_session *session, static int _lttng_variant_type_statedump(struct lttng_session *session, const struct lttng_kernel_type_variant *type, - size_t nesting) + size_t nesting, + const char *prev_field_name) { + const char *tag_name; int ret; uint32_t i, nr_choices; + tag_name = type->tag_name; + if (!tag_name) + tag_name = prev_field_name; + if (!tag_name) + return -EINVAL; /* * CTF 1.8 does not allow expressing nonzero variant alignment in a nestable way. */ @@ -3151,7 +3133,7 @@ int _lttng_variant_type_statedump(struct lttng_session *session, return ret; ret = lttng_metadata_printf(session, "variant <_%s> {\n", - type->tag_name); + tag_name); if (ret) return ret; nr_choices = type->nr_choices; @@ -3159,7 +3141,7 @@ int _lttng_variant_type_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *iter_field; iter_field = type->choices[i]; - ret = _lttng_field_statedump(session, iter_field, nesting + 1); + ret = _lttng_field_statedump(session, iter_field, nesting + 1, NULL); if (ret) return ret; } @@ -3177,12 +3159,14 @@ int _lttng_variant_type_statedump(struct lttng_session *session, static int _lttng_variant_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting) + size_t nesting, + const char *prev_field_name) { int ret; ret = _lttng_variant_type_statedump(session, - lttng_kernel_get_type_variant(field->type), nesting); + lttng_kernel_get_type_variant(field->type), nesting, + prev_field_name); if (ret) return ret; return lttng_field_name_statedump(session, field, nesting); @@ -3245,7 +3229,8 @@ int _lttng_array_field_statedump(struct lttng_session *session, static int _lttng_sequence_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting) + size_t nesting, + const char *prev_field_name) { int ret; const char *length_name; @@ -3256,6 +3241,10 @@ int _lttng_sequence_field_statedump(struct lttng_session *session, WARN_ON_ONCE(!sequence_type); length_name = sequence_type->length_name; + if (!length_name) + length_name = prev_field_name; + if (!length_name) + return -EINVAL; if (sequence_type->alignment) { ret = print_tabs(session, nesting); @@ -3290,7 +3279,7 @@ int _lttng_sequence_field_statedump(struct lttng_session *session, ret = lttng_metadata_printf(session, " _%s[ _%s ];\n", field->name, - sequence_type->length_name); + length_name); return ret; } @@ -3513,7 +3502,7 @@ int _lttng_type_statedump(struct lttng_session *session, case lttng_kernel_type_variant: ret = _lttng_variant_type_statedump(session, lttng_kernel_get_type_variant(type), - nesting); + nesting, NULL); break; /* Nested arrays and sequences are not supported yet. */ @@ -3532,10 +3521,14 @@ int _lttng_type_statedump(struct lttng_session *session, static int _lttng_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting) + size_t nesting, + const char **prev_field_name_p) { + const char *prev_field_name = NULL; int ret = 0; + if (prev_field_name_p) + prev_field_name = *prev_field_name_p; switch (field->type->type) { case lttng_kernel_type_integer: ret = _lttng_integer_field_statedump(session, field, nesting); @@ -3553,16 +3546,18 @@ int _lttng_field_statedump(struct lttng_session *session, ret = _lttng_array_field_statedump(session, field, nesting); break; case lttng_kernel_type_sequence: - ret = _lttng_sequence_field_statedump(session, field, nesting); + ret = _lttng_sequence_field_statedump(session, field, nesting, prev_field_name); break; case lttng_kernel_type_variant: - ret = _lttng_variant_field_statedump(session, field, nesting); + ret = _lttng_variant_field_statedump(session, field, nesting, prev_field_name); break; default: WARN_ON_ONCE(1); return -EINVAL; } + if (prev_field_name_p) + *prev_field_name_p = field->name; return ret; } @@ -3570,6 +3565,7 @@ static int _lttng_context_metadata_statedump(struct lttng_session *session, struct lttng_kernel_ctx *ctx) { + const char *prev_field_name = NULL; int ret = 0; int i; @@ -3578,7 +3574,7 @@ int _lttng_context_metadata_statedump(struct lttng_session *session, for (i = 0; i < ctx->nr_fields; i++) { const struct lttng_kernel_ctx_field *field = &ctx->fields[i]; - ret = _lttng_field_statedump(session, field->event_field, 2); + ret = _lttng_field_statedump(session, field->event_field, 2, &prev_field_name); if (ret) return ret; } @@ -3589,6 +3585,7 @@ static int _lttng_fields_metadata_statedump(struct lttng_session *session, struct lttng_kernel_event_recorder *event_recorder) { + const char *prev_field_name = NULL; const struct lttng_kernel_event_desc *desc = event_recorder->priv->parent.desc; int ret = 0; int i; @@ -3596,7 +3593,7 @@ int _lttng_fields_metadata_statedump(struct lttng_session *session, for (i = 0; i < desc->nr_fields; i++) { const struct lttng_kernel_event_field *field = desc->fields[i]; - ret = _lttng_field_statedump(session, field, 2); + ret = _lttng_field_statedump(session, field, 2, &prev_field_name); if (ret) return ret; }