X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttng-event-notifier-notification.c;h=811dc50ad8dc93ea7230a71a8c106d9fb6316da4;hb=f5ffbd770ec2b9d1ac9b7059eb33a01432043bce;hp=f675de4b1dbddbf6522928d79e810fe2323172dc;hpb=99d223adfae9b68800e91bda470c92acb14efae6;p=lttng-modules.git diff --git a/src/lttng-event-notifier-notification.c b/src/lttng-event-notifier-notification.c index f675de4b..811dc50a 100644 --- a/src/lttng-event-notifier-notification.c +++ b/src/lttng-event-notifier-notification.c @@ -11,10 +11,16 @@ #include #include #include +#include +#include /* - * FIXME: this probably too low but it needs to be below 1024 bytes to avoid - * the frame to be larger than the 1024 limit enforced by the kernel. + * The capture buffer size needs to be below 1024 bytes to avoid the + * frame to be larger than the 1024 limit enforced by the kernel. If we + * ever need to increase it, we will need to use a memory allocation + * scheme which allows allocating temporary memory chunks from the + * instrumentation sites. This could be done by adapting lttng + * tp-mempool to become nmi-safe and lock-free. */ #define CAPTURE_BUFFER_SIZE 512 @@ -90,7 +96,7 @@ end: static int64_t capture_sequence_element_signed(uint8_t *ptr, - const struct lttng_integer_type *type) + const struct lttng_kernel_type_integer *type) { int64_t value = 0; unsigned int size = type->size; @@ -139,7 +145,7 @@ int64_t capture_sequence_element_signed(uint8_t *ptr, static uint64_t capture_sequence_element_unsigned(uint8_t *ptr, - const struct lttng_integer_type *type) + const struct lttng_kernel_type_integer *type) { uint64_t value = 0; unsigned int size = type->size; @@ -189,8 +195,8 @@ uint64_t capture_sequence_element_unsigned(uint8_t *ptr, int capture_sequence(struct lttng_msgpack_writer *writer, struct lttng_interpreter_output *output) { - const struct lttng_integer_type *integer_type = NULL; - const struct lttng_type *nested_type; + const struct lttng_kernel_type_integer *integer_type = NULL; + const struct lttng_kernel_type_common *nested_type; uint8_t *ptr; bool signedness; int ret, i; @@ -203,13 +209,13 @@ int capture_sequence(struct lttng_msgpack_writer *writer, ptr = (uint8_t *) output->u.sequence.ptr; nested_type = output->u.sequence.nested_type; - switch (nested_type->atype) { - case atype_integer: - integer_type = &nested_type->u.integer; + switch (nested_type->type) { + case lttng_kernel_type_integer: + integer_type = lttng_kernel_get_type_integer(nested_type); break; - case atype_enum_nestable: + case lttng_kernel_type_enum: /* Treat enumeration as an integer. */ - integer_type = &nested_type->u.enum_nestable.container_type->u.integer; + integer_type = lttng_kernel_get_type_integer(lttng_kernel_get_type_enum(nested_type)->container_type); break; default: /* Capture of array of non-integer are not supported. */ @@ -319,18 +325,18 @@ int notification_append_empty_capture( static int notification_init(struct lttng_event_notifier_notification *notif, - struct lttng_event_notifier *event_notifier) + struct lttng_kernel_event_notifier *event_notifier) { struct lttng_msgpack_writer *writer = ¬if->writer; int ret = 0; notif->has_captures = false; - if (event_notifier->num_captures > 0) { + if (event_notifier->priv->num_captures > 0) { lttng_msgpack_writer_init(writer, notif->capture_buf, CAPTURE_BUFFER_SIZE); - ret = lttng_msgpack_begin_array(writer, event_notifier->num_captures); + ret = lttng_msgpack_begin_array(writer, event_notifier->priv->num_captures); if (ret) { WARN_ON_ONCE(1); goto end; @@ -343,18 +349,45 @@ end: return ret; } +static +void record_error(struct lttng_kernel_event_notifier *event_notifier) +{ + + struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group; + struct lttng_counter *error_counter; + size_t dimension_index[1]; + int ret; + + /* + * lttng_smp_load_acquire paired with lttng_smp_store_release orders + * creation of the error counter and setting error_counter_len + * before the error_counter is used. + */ + error_counter = lttng_smp_load_acquire(&event_notifier_group->error_counter); + /* This group may not have an error counter attached to it. */ + if (!error_counter) + return; + + dimension_index[0] = event_notifier->priv->error_counter_index; + + ret = error_counter->ops->counter_add(error_counter->counter, + dimension_index, 1); + if (ret) + WARN_ON_ONCE(1); +} + static void notification_send(struct lttng_event_notifier_notification *notif, - struct lttng_event_notifier *event_notifier) + struct lttng_kernel_event_notifier *event_notifier) { - struct lttng_event_notifier_group *event_notifier_group = event_notifier->group; - struct lib_ring_buffer_ctx ctx; - struct lttng_kernel_event_notifier_notification kernel_notif; + struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group; + struct lttng_kernel_ring_buffer_ctx ctx; + struct lttng_kernel_abi_event_notifier_notification kernel_notif; size_t capture_buffer_content_len, reserve_size; int ret; reserve_size = sizeof(kernel_notif); - kernel_notif.token = event_notifier->user_token; + kernel_notif.token = event_notifier->priv->parent.user_token; if (notif->has_captures) { capture_buffer_content_len = notif->writer.write_pos - notif->writer.buffer; @@ -367,41 +400,38 @@ void notification_send(struct lttng_event_notifier_notification *notif, reserve_size += capture_buffer_content_len; kernel_notif.capture_buf_size = capture_buffer_content_len; - lib_ring_buffer_ctx_init(&ctx, event_notifier_group->chan, NULL, reserve_size, - lttng_alignof(kernel_notif), -1); - ret = event_notifier_group->ops->event_reserve(&ctx, 0); + lib_ring_buffer_ctx_init(&ctx, event_notifier_group->chan, reserve_size, + lttng_alignof(kernel_notif), NULL); + ret = event_notifier_group->ops->event_reserve(&ctx); if (ret < 0) { - //TODO: error handling with counter maps - //silently drop for now. - WARN_ON_ONCE(1); + record_error(event_notifier); return; } - lib_ring_buffer_align_ctx(&ctx, lttng_alignof(kernel_notif)); - /* Write the notif structure. */ event_notifier_group->ops->event_write(&ctx, &kernel_notif, - sizeof(kernel_notif)); + sizeof(kernel_notif), lttng_alignof(kernel_notif)); /* * Write the capture buffer. No need to realigned as the below is a raw * char* buffer. */ event_notifier_group->ops->event_write(&ctx, ¬if->capture_buf, - capture_buffer_content_len); + capture_buffer_content_len, 1); event_notifier_group->ops->event_commit(&ctx); irq_work_queue(&event_notifier_group->wakeup_pending); } -void lttng_event_notifier_notification_send(struct lttng_event_notifier *event_notifier, - struct lttng_probe_ctx *lttng_probe_ctx, - const char *stack_data) +void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier *event_notifier, + const char *stack_data, + struct lttng_kernel_probe_ctx *probe_ctx, + struct lttng_kernel_notification_ctx *notif_ctx) { struct lttng_event_notifier_notification notif = { 0 }; int ret; - if (unlikely(!READ_ONCE(event_notifier->enabled))) + if (unlikely(!READ_ONCE(event_notifier->parent.enabled))) return; ret = notification_init(¬if, event_notifier); @@ -410,8 +440,8 @@ void lttng_event_notifier_notification_send(struct lttng_event_notifier *event_n goto end; } - if (unlikely(!list_empty(&event_notifier->capture_bytecode_runtime_head))) { - struct lttng_bytecode_runtime *capture_bc_runtime; + if (unlikely(notif_ctx->eval_capture)) { + struct lttng_kernel_bytecode_runtime *capture_bc_runtime; /* * Iterate over all the capture bytecodes. If the interpreter @@ -419,12 +449,12 @@ void lttng_event_notifier_notification_send(struct lttng_event_notifier *event_n * `output` parameter to the capture buffer. If the interpreter * fails, append an empty capture to the buffer. */ - list_for_each_entry(capture_bc_runtime, - &event_notifier->capture_bytecode_runtime_head, node) { + list_for_each_entry_rcu(capture_bc_runtime, + &event_notifier->priv->capture_bytecode_runtime_head, node) { struct lttng_interpreter_output output; - if (capture_bc_runtime->interpreter_funcs.capture(capture_bc_runtime, - lttng_probe_ctx, stack_data, &output) & LTTNG_INTERPRETER_RECORD_FLAG) + if (capture_bc_runtime->interpreter_func(capture_bc_runtime, + stack_data, probe_ctx, &output) == LTTNG_KERNEL_BYTECODE_INTERPRETER_OK) ret = notification_append_capture(¬if, &output); else ret = notification_append_empty_capture(¬if);