1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
3 * lttng-event-notifier-notification.c
5 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
10 #include <lttng/lttng-bytecode.h>
11 #include <lttng/events.h>
12 #include <lttng/msgpack.h>
13 #include <lttng/event-notifier-notification.h>
14 #include <lttng/events-internal.h>
15 #include <lttng/probe-user.h>
16 #include <wrapper/barrier.h>
19 * The capture buffer size needs to be below 1024 bytes to avoid the
20 * frame to be larger than the 1024 limit enforced by the kernel. If we
21 * ever need to increase it, we will need to use a memory allocation
22 * scheme which allows allocating temporary memory chunks from the
23 * instrumentation sites. This could be done by adapting lttng
24 * tp-mempool to become nmi-safe and lock-free.
26 #define CAPTURE_BUFFER_SIZE 512
28 #define MSG_WRITE_NIL_LEN 1
30 struct lttng_event_notifier_notification
{
32 uint64_t event_notifier_token
;
33 uint8_t capture_buf
[CAPTURE_BUFFER_SIZE
];
34 struct lttng_msgpack_writer writer
;
39 int capture_enum(struct lttng_msgpack_writer
*writer
,
40 struct lttng_interpreter_output
*output
)
45 * Enums are captured as a map containing 2 key-value pairs. Such as:
49 ret
= lttng_msgpack_begin_map(writer
, 2);
54 ret
= lttng_msgpack_write_str(writer
, "type");
59 ret
= lttng_msgpack_write_str(writer
, "enum");
64 ret
= lttng_msgpack_write_str(writer
, "value");
69 switch (output
->type
) {
70 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
71 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
76 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
77 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.u
);
86 ret
= lttng_msgpack_end_map(writer
);
92 int64_t capture_sequence_element_signed(uint8_t *ptr
,
93 const struct lttng_kernel_type_integer
*type
)
96 unsigned int size
= type
->size
;
97 bool user
= type
->user
;
98 bool byte_order_reversed
= type
->reverse_byte_order
;
106 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(int8_t)))
119 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(int16_t)))
122 tmp
= *(int16_t *) ptr
;
124 if (byte_order_reversed
)
134 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(int32_t)))
137 tmp
= *(int32_t *) ptr
;
139 if (byte_order_reversed
)
149 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(int64_t)))
152 tmp
= *(int64_t *) ptr
;
154 if (byte_order_reversed
)
167 uint64_t capture_sequence_element_unsigned(uint8_t *ptr
,
168 const struct lttng_kernel_type_integer
*type
)
171 unsigned int size
= type
->size
;
172 bool user
= type
->user
;
173 bool byte_order_reversed
= type
->reverse_byte_order
;
181 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(uint8_t)))
194 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(uint16_t)))
197 tmp
= *(uint16_t *) ptr
;
199 if (byte_order_reversed
)
209 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(uint32_t)))
212 tmp
= *(uint32_t *) ptr
;
214 if (byte_order_reversed
)
224 if (lttng_copy_from_user_check_nofault(&tmp
, ptr
, sizeof(uint64_t)))
227 tmp
= *(uint64_t *) ptr
;
229 if (byte_order_reversed
)
241 int capture_sequence(struct lttng_msgpack_writer
*writer
,
242 struct lttng_interpreter_output
*output
)
244 const struct lttng_kernel_type_integer
*integer_type
= NULL
;
245 const struct lttng_kernel_type_common
*nested_type
;
250 ret
= lttng_msgpack_begin_array(writer
, output
->u
.sequence
.nr_elem
);
255 ptr
= (uint8_t *) output
->u
.sequence
.ptr
;
256 nested_type
= output
->u
.sequence
.nested_type
;
257 switch (nested_type
->type
) {
258 case lttng_kernel_type_integer
:
259 integer_type
= lttng_kernel_get_type_integer(nested_type
);
261 case lttng_kernel_type_enum
:
262 /* Treat enumeration as an integer. */
263 integer_type
= lttng_kernel_get_type_integer(lttng_kernel_get_type_enum(nested_type
)->container_type
);
266 /* Capture of array of non-integer are not supported. */
271 signedness
= integer_type
->signedness
;
272 for (i
= 0; i
< output
->u
.sequence
.nr_elem
; i
++) {
274 ret
= lttng_msgpack_write_signed_integer(writer
,
275 capture_sequence_element_signed(ptr
, integer_type
));
280 ret
= lttng_msgpack_write_unsigned_integer(writer
,
281 capture_sequence_element_unsigned(ptr
, integer_type
));
288 * We assume that alignment is smaller or equal to the size.
289 * This currently holds true but if it changes in the future,
290 * we will want to change the pointer arithmetics below to
291 * take into account that the next element might be further
294 WARN_ON_ONCE(integer_type
->alignment
> integer_type
->size
);
296 /* Size is in number of bits. */
297 ptr
+= (integer_type
->size
/ CHAR_BIT
) ;
300 ret
= lttng_msgpack_end_array(writer
);
306 int notification_append_capture(
307 struct lttng_event_notifier_notification
*notif
,
308 struct lttng_interpreter_output
*output
)
310 struct lttng_msgpack_writer
*writer
= ¬if
->writer
;
313 switch (output
->type
) {
314 case LTTNG_INTERPRETER_TYPE_S64
:
315 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
317 case LTTNG_INTERPRETER_TYPE_U64
:
318 ret
= lttng_msgpack_write_unsigned_integer(writer
, output
->u
.u
);
320 case LTTNG_INTERPRETER_TYPE_STRING
:
321 if (output
->u
.str
.user
) {
322 ret
= lttng_msgpack_write_user_str(writer
, output
->u
.str
.user_str
);
324 ret
= lttng_msgpack_write_str(writer
, output
->u
.str
.str
);
327 case LTTNG_INTERPRETER_TYPE_SEQUENCE
:
328 ret
= capture_sequence(writer
, output
);
330 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
331 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
332 ret
= capture_enum(writer
, output
);
342 int notification_append_empty_capture(
343 struct lttng_event_notifier_notification
*notif
)
345 return lttng_msgpack_write_nil(¬if
->writer
);
349 int notification_init(struct lttng_event_notifier_notification
*notif
,
350 struct lttng_kernel_event_notifier
*event_notifier
)
352 struct lttng_msgpack_writer
*writer
= ¬if
->writer
;
355 notif
->has_captures
= false;
357 if (event_notifier
->priv
->num_captures
> 0) {
358 lttng_msgpack_writer_init(writer
, notif
->capture_buf
,
359 CAPTURE_BUFFER_SIZE
);
361 ret
= lttng_msgpack_begin_array(writer
, event_notifier
->priv
->num_captures
);
366 notif
->has_captures
= true;
374 void record_error(struct lttng_kernel_event_notifier
*event_notifier
)
377 struct lttng_event_notifier_group
*event_notifier_group
= event_notifier
->priv
->group
;
378 struct lttng_counter
*error_counter
;
379 size_t dimension_index
[1];
383 * lttng_smp_load_acquire paired with lttng_smp_store_release orders
384 * creation of the error counter and setting error_counter_len
385 * before the error_counter is used.
387 error_counter
= lttng_smp_load_acquire(&event_notifier_group
->error_counter
);
388 /* This group may not have an error counter attached to it. */
392 dimension_index
[0] = event_notifier
->priv
->error_counter_index
;
394 ret
= error_counter
->ops
->counter_add(error_counter
->counter
,
401 void notification_send(struct lttng_event_notifier_notification
*notif
,
402 struct lttng_kernel_event_notifier
*event_notifier
)
404 struct lttng_event_notifier_group
*event_notifier_group
= event_notifier
->priv
->group
;
405 struct lttng_kernel_ring_buffer_ctx ctx
;
406 struct lttng_kernel_abi_event_notifier_notification kernel_notif
;
407 size_t capture_buffer_content_len
, reserve_size
;
410 reserve_size
= sizeof(kernel_notif
);
411 kernel_notif
.token
= event_notifier
->priv
->parent
.user_token
;
413 if (notif
->has_captures
) {
414 capture_buffer_content_len
= notif
->writer
.write_pos
- notif
->writer
.buffer
;
416 capture_buffer_content_len
= 0;
419 WARN_ON_ONCE(capture_buffer_content_len
> CAPTURE_BUFFER_SIZE
);
421 reserve_size
+= capture_buffer_content_len
;
422 kernel_notif
.capture_buf_size
= capture_buffer_content_len
;
424 lib_ring_buffer_ctx_init(&ctx
, event_notifier_group
->chan
, reserve_size
,
425 lttng_alignof(kernel_notif
), NULL
);
426 ret
= event_notifier_group
->ops
->event_reserve(&ctx
);
428 record_error(event_notifier
);
432 /* Write the notif structure. */
433 event_notifier_group
->ops
->event_write(&ctx
, &kernel_notif
,
434 sizeof(kernel_notif
), lttng_alignof(kernel_notif
));
437 * Write the capture buffer. No need to realigned as the below is a raw
440 event_notifier_group
->ops
->event_write(&ctx
, ¬if
->capture_buf
,
441 capture_buffer_content_len
, 1);
443 event_notifier_group
->ops
->event_commit(&ctx
);
444 irq_work_queue(&event_notifier_group
->wakeup_pending
);
448 * Validate that the buffer has enough room to hold empty capture fields.
451 bool validate_buffer_len(struct lttng_event_notifier_notification
*notif
, size_t captures_left
)
453 if (notif
->writer
.end_write_pos
- notif
->writer
.write_pos
< MSG_WRITE_NIL_LEN
* captures_left
)
458 void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier
*event_notifier
,
459 const char *stack_data
,
460 struct lttng_kernel_probe_ctx
*probe_ctx
,
461 struct lttng_kernel_notification_ctx
*notif_ctx
)
463 struct lttng_event_notifier_notification notif
= { 0 };
464 size_t captures_left
;
466 if (unlikely(!READ_ONCE(event_notifier
->parent
.enabled
)))
469 if (notification_init(¬if
, event_notifier
))
472 captures_left
= event_notifier
->priv
->num_captures
;
473 if (!validate_buffer_len(¬if
, captures_left
))
476 if (unlikely(notif_ctx
->eval_capture
)) {
477 struct lttng_kernel_bytecode_runtime
*capture_bc_runtime
;
480 * Iterate over all the capture bytecodes. If the interpreter
481 * functions returns successfully, append the value of the
482 * `output` parameter to the capture buffer. If the interpreter
483 * fails, append an empty capture to the buffer.
485 list_for_each_entry_rcu(capture_bc_runtime
,
486 &event_notifier
->priv
->capture_bytecode_runtime_head
, node
) {
487 struct lttng_interpreter_output output
;
491 lttng_msgpack_save_writer_pos(¬if
.writer
, &save_pos
);
493 if (capture_bc_runtime
->interpreter_func(capture_bc_runtime
,
494 stack_data
, probe_ctx
, &output
) == LTTNG_KERNEL_BYTECODE_INTERPRETER_OK
)
495 ret
= notification_append_capture(¬if
, &output
);
496 if (ret
|| !validate_buffer_len(¬if
, captures_left
)) {
498 * On append capture error or if the generated
499 * buffer data would not leave enough room to
500 * write empty capture fields for the remaining
501 * fields, skip the field capture by restoring
502 * the msgpack writer position and writing an
503 * empty capture field.
505 lttng_msgpack_restore_writer_pos(¬if
.writer
, save_pos
);
506 ret
= notification_append_empty_capture(¬if
);
512 if (notif
.has_captures
&& lttng_msgpack_end_array(¬if
.writer
))
516 * Send the notification (including the capture buffer) to the
519 notification_send(¬if
, event_notifier
);
523 record_error(event_notifier
);