1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
3 * lttng-trigger-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/trigger-notification.h>
16 * FIXME: this probably too low but it needs to be below 1024 bytes to avoid
17 * the frame to be larger than the 1024 limit enforced by the kernel.
19 #define CAPTURE_BUFFER_SIZE 512
21 struct lttng_trigger_notification
{
24 uint8_t capture_buf
[CAPTURE_BUFFER_SIZE
];
25 struct lttng_msgpack_writer writer
;
30 int capture_enum(struct lttng_msgpack_writer
*writer
,
31 struct lttng_interpreter_output
*output
)
36 * Enums are captured as a map containing 2 key-value pairs. Such as:
40 ret
= lttng_msgpack_begin_map(writer
, 2);
46 ret
= lttng_msgpack_write_str(writer
, "type");
52 ret
= lttng_msgpack_write_str(writer
, "enum");
58 ret
= lttng_msgpack_write_str(writer
, "value");
64 switch (output
->type
) {
65 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
66 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
72 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
73 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.u
);
83 ret
= lttng_msgpack_end_map(writer
);
92 int64_t capture_sequence_element_signed(uint8_t *ptr
,
93 const struct lttng_integer_type
*type
)
96 unsigned int size
= type
->size
;
97 bool byte_order_reversed
= type
->reverse_byte_order
;
106 tmp
= *(int16_t *) ptr
;
107 if (byte_order_reversed
)
116 tmp
= *(int32_t *) ptr
;
117 if (byte_order_reversed
)
126 tmp
= *(int64_t *) ptr
;
127 if (byte_order_reversed
)
141 uint64_t capture_sequence_element_unsigned(uint8_t *ptr
,
142 const struct lttng_integer_type
*type
)
145 unsigned int size
= type
->size
;
146 bool byte_order_reversed
= type
->reverse_byte_order
;
155 tmp
= *(uint16_t *) ptr
;
156 if (byte_order_reversed
)
165 tmp
= *(uint32_t *) ptr
;
166 if (byte_order_reversed
)
175 tmp
= *(uint64_t *) ptr
;
176 if (byte_order_reversed
)
189 int capture_sequence(struct lttng_msgpack_writer
*writer
,
190 struct lttng_interpreter_output
*output
)
192 const struct lttng_integer_type
*integer_type
= NULL
;
193 const struct lttng_type
*nested_type
;
198 ret
= lttng_msgpack_begin_array(writer
, output
->u
.sequence
.nr_elem
);
204 ptr
= (uint8_t *) output
->u
.sequence
.ptr
;
205 nested_type
= output
->u
.sequence
.nested_type
;
206 switch (nested_type
->atype
) {
208 integer_type
= &nested_type
->u
.integer
;
210 case atype_enum_nestable
:
211 /* Treat enumeration as an integer. */
212 integer_type
= &nested_type
->u
.enum_nestable
.container_type
->u
.integer
;
215 /* Capture of array of non-integer are not supported. */
218 signedness
= integer_type
->signedness
;
219 for (i
= 0; i
< output
->u
.sequence
.nr_elem
; i
++) {
221 ret
=lttng_msgpack_write_signed_integer(writer
,
222 capture_sequence_element_signed(ptr
, integer_type
));
228 ret
= lttng_msgpack_write_unsigned_integer(writer
,
229 capture_sequence_element_unsigned(ptr
, integer_type
));
237 * We assume that alignment is smaller or equal to the size.
238 * This currently holds true but if it changes in the future,
239 * we will want to change the pointer arithmetics below to
240 * take into account that the next element might be further
243 WARN_ON(integer_type
->alignment
> integer_type
->size
);
245 /* Size is in number of bits. */
246 ptr
+= (integer_type
->size
/ CHAR_BIT
) ;
249 ret
= lttng_msgpack_end_array(writer
);
257 int notification_append_capture(
258 struct lttng_trigger_notification
*notif
,
259 struct lttng_interpreter_output
*output
)
261 struct lttng_msgpack_writer
*writer
= ¬if
->writer
;
264 switch (output
->type
) {
265 case LTTNG_INTERPRETER_TYPE_S64
:
266 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
272 case LTTNG_INTERPRETER_TYPE_U64
:
273 ret
= lttng_msgpack_write_unsigned_integer(writer
, output
->u
.u
);
279 case LTTNG_INTERPRETER_TYPE_STRING
:
280 ret
= lttng_msgpack_write_str(writer
, output
->u
.str
.str
);
286 case LTTNG_INTERPRETER_TYPE_SEQUENCE
:
287 ret
= capture_sequence(writer
, output
);
293 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
294 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
295 ret
= capture_enum(writer
, output
);
310 int notification_append_empty_capture(
311 struct lttng_trigger_notification
*notif
)
313 int ret
= lttng_msgpack_write_nil(¬if
->writer
);
321 int notification_init(struct lttng_trigger_notification
*notif
,
322 struct lttng_trigger
*trigger
)
324 struct lttng_msgpack_writer
*writer
= ¬if
->writer
;
327 notif
->has_captures
= false;
329 if (trigger
->num_captures
> 0) {
330 lttng_msgpack_writer_init(writer
, notif
->capture_buf
,
331 CAPTURE_BUFFER_SIZE
);
333 ret
= lttng_msgpack_begin_array(writer
, trigger
->num_captures
);
339 notif
->has_captures
= true;
347 void record_error(struct lttng_trigger
*trigger
)
350 struct lttng_trigger_group
*trigger_group
= trigger
->group
;
351 size_t dimension_index
[1];
354 dimension_index
[0] = trigger
->error_counter_index
;
356 ret
= trigger_group
->error_counter
->ops
->counter_add(
357 trigger_group
->error_counter
->counter
,
364 void notification_send(struct lttng_trigger_notification
*notif
,
365 struct lttng_trigger
*trigger
)
367 struct lttng_trigger_group
*trigger_group
= trigger
->group
;
368 struct lib_ring_buffer_ctx ctx
;
369 struct lttng_kernel_trigger_notification kernel_notif
;
370 size_t capture_buffer_content_len
, reserve_size
;
373 reserve_size
= sizeof(kernel_notif
);
374 kernel_notif
.id
= trigger
->id
;
376 if (notif
->has_captures
) {
377 capture_buffer_content_len
= notif
->writer
.write_pos
- notif
->writer
.buffer
;
379 capture_buffer_content_len
= 0;
382 WARN_ON_ONCE(capture_buffer_content_len
> CAPTURE_BUFFER_SIZE
);
384 reserve_size
+= capture_buffer_content_len
;
385 kernel_notif
.capture_buf_size
= capture_buffer_content_len
;
387 lib_ring_buffer_ctx_init(&ctx
, trigger_group
->chan
, NULL
, reserve_size
,
388 lttng_alignof(kernel_notif
), -1);
389 ret
= trigger_group
->ops
->event_reserve(&ctx
, 0);
391 record_error(trigger
);
395 lib_ring_buffer_align_ctx(&ctx
, lttng_alignof(kernel_notif
));
397 /* Write the notif structure. */
398 trigger_group
->ops
->event_write(&ctx
, &kernel_notif
,
399 sizeof(kernel_notif
));
402 * Write the capture buffer. No need to realigned as the below is a raw
405 trigger_group
->ops
->event_write(&ctx
, ¬if
->capture_buf
,
406 capture_buffer_content_len
);
408 trigger_group
->ops
->event_commit(&ctx
);
409 irq_work_queue(&trigger_group
->wakeup_pending
);
412 void lttng_trigger_notification_send(struct lttng_trigger
*trigger
,
413 struct lttng_probe_ctx
*lttng_probe_ctx
,
414 const char *stack_data
)
416 struct lttng_trigger_notification notif
= {0};
419 if (unlikely(!READ_ONCE(trigger
->enabled
)))
422 ret
= notification_init(¬if
, trigger
);
428 if (unlikely(!list_empty(&trigger
->capture_bytecode_runtime_head
))) {
429 struct lttng_bytecode_runtime
*capture_bc_runtime
;
432 * Iterate over all the capture bytecodes. If the interpreter
433 * functions returns successfully, append the value of the
434 * `output` parameter to the capture buffer. If the interpreter
435 * fails, append an empty capture to the buffer.
437 list_for_each_entry(capture_bc_runtime
,
438 &trigger
->capture_bytecode_runtime_head
, node
) {
439 struct lttng_interpreter_output output
;
441 if (capture_bc_runtime
->interpreter_funcs
.capture(capture_bc_runtime
,
442 lttng_probe_ctx
, stack_data
, &output
) & LTTNG_INTERPRETER_RECORD_FLAG
)
443 ret
= notification_append_capture(¬if
, &output
);
445 ret
= notification_append_empty_capture(¬if
);
448 printk(KERN_WARNING
"Error appending capture to notification");
453 * Send the notification (including the capture buffer) to the
456 notification_send(¬if
, trigger
);