Rename "tsc" to "timestamp"
[lttng-modules.git] / src / lttng-event-notifier-notification.c
CommitLineData
21f58fb7
FD
1/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
2 *
3 * lttng-event-notifier-notification.c
4 *
5 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
6 */
7
a27c8df7 8#include <asm/barrier.h>
42f3ef8c
FD
9#include <linux/bug.h>
10
11#include <lttng/lttng-bytecode.h>
21f58fb7 12#include <lttng/events.h>
42f3ef8c 13#include <lttng/msgpack.h>
21f58fb7 14#include <lttng/event-notifier-notification.h>
437d5aa5 15#include <lttng/events-internal.h>
11b589f6 16#include <lttng/probe-user.h>
21f58fb7 17
99d223ad 18/*
e699ee6c
MD
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.
99d223ad
FD
25 */
26#define CAPTURE_BUFFER_SIZE 512
27
f125ded4
MD
28#define MSG_WRITE_NIL_LEN 1
29
99d223ad
FD
30struct lttng_event_notifier_notification {
31 int notification_fd;
32 uint64_t event_notifier_token;
33 uint8_t capture_buf[CAPTURE_BUFFER_SIZE];
34 struct lttng_msgpack_writer writer;
35 bool has_captures;
36};
37
42f3ef8c
FD
38static
39int capture_enum(struct lttng_msgpack_writer *writer,
40 struct lttng_interpreter_output *output)
41{
42 int ret;
43
44 /*
45 * Enums are captured as a map containing 2 key-value pairs. Such as:
46 * - type: enum
47 * value: 177
48 */
49 ret = lttng_msgpack_begin_map(writer, 2);
50 if (ret) {
42f3ef8c
FD
51 goto end;
52 }
53
54 ret = lttng_msgpack_write_str(writer, "type");
55 if (ret) {
42f3ef8c
FD
56 goto end;
57 }
58
59 ret = lttng_msgpack_write_str(writer, "enum");
60 if (ret) {
42f3ef8c
FD
61 goto end;
62 }
63
64 ret = lttng_msgpack_write_str(writer, "value");
65 if (ret) {
42f3ef8c
FD
66 goto end;
67 }
68
69 switch (output->type) {
70 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM:
71 ret = lttng_msgpack_write_signed_integer(writer, output->u.s);
72 if (ret) {
42f3ef8c
FD
73 goto end;
74 }
75 break;
76 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM:
77 ret = lttng_msgpack_write_signed_integer(writer, output->u.u);
78 if (ret) {
42f3ef8c
FD
79 goto end;
80 }
81 break;
82 default:
736f2dd6 83 WARN_ON_ONCE(1);
60ae08f0
MD
84 ret = -1;
85 goto end;
42f3ef8c
FD
86 }
87
88 ret = lttng_msgpack_end_map(writer);
42f3ef8c
FD
89end:
90 return ret;
91}
92
93static
60ae08f0
MD
94int capture_sequence_element_signed(uint8_t *ptr,
95 const struct lttng_kernel_type_integer *type,
96 int64_t *_value)
42f3ef8c
FD
97{
98 int64_t value = 0;
99 unsigned int size = type->size;
11b589f6 100 bool user = type->user;
42f3ef8c
FD
101 bool byte_order_reversed = type->reverse_byte_order;
102
103 switch (size) {
104 case 8:
11b589f6
MD
105 {
106 int8_t tmp;
107
108 if (user) {
109 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int8_t)))
60ae08f0 110 return -1;
11b589f6
MD
111 } else {
112 tmp = *ptr;
113 }
114 value = tmp;
42f3ef8c 115 break;
11b589f6 116 }
42f3ef8c
FD
117 case 16:
118 {
119 int16_t tmp;
11b589f6
MD
120
121 if (user) {
122 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int16_t)))
60ae08f0 123 return -1;
11b589f6
MD
124 } else {
125 tmp = *(int16_t *) ptr;
126 }
42f3ef8c
FD
127 if (byte_order_reversed)
128 __swab16s(&tmp);
42f3ef8c
FD
129 value = tmp;
130 break;
131 }
132 case 32:
133 {
134 int32_t tmp;
11b589f6
MD
135
136 if (user) {
137 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int32_t)))
60ae08f0 138 return -1;
11b589f6
MD
139 } else {
140 tmp = *(int32_t *) ptr;
141 }
42f3ef8c
FD
142 if (byte_order_reversed)
143 __swab32s(&tmp);
42f3ef8c
FD
144 value = tmp;
145 break;
146 }
147 case 64:
148 {
149 int64_t tmp;
11b589f6
MD
150
151 if (user) {
152 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int64_t)))
60ae08f0 153 return -1;
11b589f6
MD
154 } else {
155 tmp = *(int64_t *) ptr;
156 }
42f3ef8c
FD
157 if (byte_order_reversed)
158 __swab64s(&tmp);
42f3ef8c
FD
159 value = tmp;
160 break;
161 }
162 default:
736f2dd6 163 WARN_ON_ONCE(1);
60ae08f0 164 return -1;
42f3ef8c
FD
165 }
166
60ae08f0
MD
167 *_value = value;
168 return 0;
42f3ef8c
FD
169}
170
171static
60ae08f0
MD
172int capture_sequence_element_unsigned(uint8_t *ptr,
173 const struct lttng_kernel_type_integer *type,
174 uint64_t *_value)
42f3ef8c
FD
175{
176 uint64_t value = 0;
177 unsigned int size = type->size;
11b589f6 178 bool user = type->user;
42f3ef8c
FD
179 bool byte_order_reversed = type->reverse_byte_order;
180
181 switch (size) {
182 case 8:
11b589f6
MD
183 {
184 uint8_t tmp;
185
186 if (user) {
187 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint8_t)))
60ae08f0 188 return -1;
11b589f6
MD
189 } else {
190 tmp = *ptr;
191 }
192 value = tmp;
42f3ef8c 193 break;
11b589f6 194 }
42f3ef8c
FD
195 case 16:
196 {
197 uint16_t tmp;
11b589f6
MD
198
199 if (user) {
200 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint16_t)))
60ae08f0 201 return -1;
11b589f6
MD
202 } else {
203 tmp = *(uint16_t *) ptr;
204 }
42f3ef8c
FD
205 if (byte_order_reversed)
206 __swab16s(&tmp);
42f3ef8c
FD
207 value = tmp;
208 break;
209 }
210 case 32:
211 {
212 uint32_t tmp;
11b589f6
MD
213
214 if (user) {
215 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint32_t)))
60ae08f0 216 return -1;
11b589f6
MD
217 } else {
218 tmp = *(uint32_t *) ptr;
219 }
42f3ef8c
FD
220 if (byte_order_reversed)
221 __swab32s(&tmp);
42f3ef8c
FD
222 value = tmp;
223 break;
224 }
225 case 64:
226 {
227 uint64_t tmp;
11b589f6
MD
228
229 if (user) {
230 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint64_t)))
60ae08f0 231 return -1;
11b589f6
MD
232 } else {
233 tmp = *(uint64_t *) ptr;
234 }
42f3ef8c
FD
235 if (byte_order_reversed)
236 __swab64s(&tmp);
42f3ef8c
FD
237 value = tmp;
238 break;
239 }
240 default:
736f2dd6 241 WARN_ON_ONCE(1);
60ae08f0 242 return -1;
42f3ef8c
FD
243 }
244
60ae08f0
MD
245 *_value = value;
246 return 0;
42f3ef8c
FD
247}
248
42f3ef8c
FD
249int capture_sequence(struct lttng_msgpack_writer *writer,
250 struct lttng_interpreter_output *output)
251{
437d5aa5
MD
252 const struct lttng_kernel_type_integer *integer_type = NULL;
253 const struct lttng_kernel_type_common *nested_type;
42f3ef8c
FD
254 uint8_t *ptr;
255 bool signedness;
256 int ret, i;
257
258 ret = lttng_msgpack_begin_array(writer, output->u.sequence.nr_elem);
259 if (ret) {
42f3ef8c
FD
260 goto end;
261 }
262
263 ptr = (uint8_t *) output->u.sequence.ptr;
264 nested_type = output->u.sequence.nested_type;
12bb2edb
MD
265 switch (nested_type->type) {
266 case lttng_kernel_type_integer:
437d5aa5 267 integer_type = lttng_kernel_get_type_integer(nested_type);
42f3ef8c 268 break;
437d5aa5 269 case lttng_kernel_type_enum:
42f3ef8c 270 /* Treat enumeration as an integer. */
437d5aa5 271 integer_type = lttng_kernel_get_type_integer(lttng_kernel_get_type_enum(nested_type)->container_type);
42f3ef8c
FD
272 break;
273 default:
274 /* Capture of array of non-integer are not supported. */
736f2dd6
MD
275 WARN_ON_ONCE(1);
276 ret = -1;
277 goto end;
42f3ef8c
FD
278 }
279 signedness = integer_type->signedness;
280 for (i = 0; i < output->u.sequence.nr_elem; i++) {
281 if (signedness) {
60ae08f0
MD
282 int64_t v;
283
284 ret = capture_sequence_element_signed(ptr, integer_type, &v);
285 if (ret) {
286 goto end;
287 }
288 ret = lttng_msgpack_write_signed_integer(writer, v);
42f3ef8c 289 if (ret) {
42f3ef8c
FD
290 goto end;
291 }
292 } else {
60ae08f0
MD
293 uint64_t v;
294
295 ret = capture_sequence_element_unsigned(ptr, integer_type, &v);
296 if (ret) {
297 goto end;
298 }
299 ret = lttng_msgpack_write_unsigned_integer(writer, v);
42f3ef8c 300 if (ret) {
42f3ef8c
FD
301 goto end;
302 }
303 }
304
305 /*
306 * We assume that alignment is smaller or equal to the size.
307 * This currently holds true but if it changes in the future,
308 * we will want to change the pointer arithmetics below to
309 * take into account that the next element might be further
310 * away.
311 */
736f2dd6 312 WARN_ON_ONCE(integer_type->alignment > integer_type->size);
42f3ef8c
FD
313
314 /* Size is in number of bits. */
315 ptr += (integer_type->size / CHAR_BIT) ;
316 }
317
318 ret = lttng_msgpack_end_array(writer);
42f3ef8c
FD
319end:
320 return ret;
321}
322
99d223ad
FD
323static
324int notification_append_capture(
325 struct lttng_event_notifier_notification *notif,
326 struct lttng_interpreter_output *output)
327{
328 struct lttng_msgpack_writer *writer = &notif->writer;
329 int ret = 0;
330
331 switch (output->type) {
332 case LTTNG_INTERPRETER_TYPE_S64:
333 ret = lttng_msgpack_write_signed_integer(writer, output->u.s);
99d223ad
FD
334 break;
335 case LTTNG_INTERPRETER_TYPE_U64:
336 ret = lttng_msgpack_write_unsigned_integer(writer, output->u.u);
99d223ad
FD
337 break;
338 case LTTNG_INTERPRETER_TYPE_STRING:
8915cf5e
MD
339 if (output->u.str.user) {
340 ret = lttng_msgpack_write_user_str(writer, output->u.str.user_str);
341 } else {
342 ret = lttng_msgpack_write_str(writer, output->u.str.str);
343 }
99d223ad
FD
344 break;
345 case LTTNG_INTERPRETER_TYPE_SEQUENCE:
346 ret = capture_sequence(writer, output);
99d223ad
FD
347 break;
348 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM:
349 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM:
350 ret = capture_enum(writer, output);
99d223ad
FD
351 break;
352 default:
353 ret = -1;
736f2dd6 354 WARN_ON_ONCE(1);
99d223ad 355 }
99d223ad
FD
356 return ret;
357}
358
359static
360int notification_append_empty_capture(
361 struct lttng_event_notifier_notification *notif)
362{
736f2dd6 363 return lttng_msgpack_write_nil(&notif->writer);
99d223ad
FD
364}
365
366static
367int notification_init(struct lttng_event_notifier_notification *notif,
a67ba386 368 struct lttng_kernel_event_notifier *event_notifier)
99d223ad
FD
369{
370 struct lttng_msgpack_writer *writer = &notif->writer;
371 int ret = 0;
372
373 notif->has_captures = false;
374
a67ba386 375 if (event_notifier->priv->num_captures > 0) {
99d223ad
FD
376 lttng_msgpack_writer_init(writer, notif->capture_buf,
377 CAPTURE_BUFFER_SIZE);
378
a67ba386 379 ret = lttng_msgpack_begin_array(writer, event_notifier->priv->num_captures);
99d223ad 380 if (ret) {
99d223ad
FD
381 goto end;
382 }
383
384 notif->has_captures = true;
385 }
386
387end:
388 return ret;
389}
390
99f52fcc 391static
a67ba386 392void record_error(struct lttng_kernel_event_notifier *event_notifier)
99f52fcc
FD
393{
394
a67ba386 395 struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
ab04d7b1 396 struct lttng_counter *error_counter;
99f52fcc
FD
397 size_t dimension_index[1];
398 int ret;
399
ab04d7b1 400 /*
a27c8df7
MJ
401 * smp_load_acquire paired with smp_store_release orders creation of
402 * the error counter and setting error_counter_len before the
403 * error_counter is used.
ab04d7b1 404 */
a27c8df7 405 error_counter = smp_load_acquire(&event_notifier_group->error_counter);
a83d6831 406 /* This group may not have an error counter attached to it. */
ab04d7b1 407 if (!error_counter)
a83d6831
FD
408 return;
409
a67ba386 410 dimension_index[0] = event_notifier->priv->error_counter_index;
99f52fcc 411
ab04d7b1 412 ret = error_counter->ops->counter_add(error_counter->counter,
99f52fcc
FD
413 dimension_index, 1);
414 if (ret)
415 WARN_ON_ONCE(1);
416}
417
99d223ad
FD
418static
419void notification_send(struct lttng_event_notifier_notification *notif,
a67ba386 420 struct lttng_kernel_event_notifier *event_notifier)
21f58fb7 421{
a67ba386 422 struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
8a57ec02 423 struct lttng_kernel_ring_buffer_ctx ctx;
606828e4 424 struct lttng_kernel_abi_event_notifier_notification kernel_notif;
99d223ad 425 size_t capture_buffer_content_len, reserve_size;
21f58fb7
FD
426 int ret;
427
99d223ad 428 reserve_size = sizeof(kernel_notif);
a67ba386 429 kernel_notif.token = event_notifier->priv->parent.user_token;
21f58fb7 430
99d223ad
FD
431 if (notif->has_captures) {
432 capture_buffer_content_len = notif->writer.write_pos - notif->writer.buffer;
433 } else {
434 capture_buffer_content_len = 0;
435 }
436
437 WARN_ON_ONCE(capture_buffer_content_len > CAPTURE_BUFFER_SIZE);
438
439 reserve_size += capture_buffer_content_len;
440 kernel_notif.capture_buf_size = capture_buffer_content_len;
441
8a445457 442 lib_ring_buffer_ctx_init(&ctx, event_notifier_group->chan, reserve_size,
b1199bd3 443 lttng_alignof(kernel_notif), NULL);
c2fb9c1c 444 ret = event_notifier_group->ops->event_reserve(&ctx);
21f58fb7 445 if (ret < 0) {
99f52fcc 446 record_error(event_notifier);
21f58fb7
FD
447 return;
448 }
99d223ad 449
99d223ad
FD
450 /* Write the notif structure. */
451 event_notifier_group->ops->event_write(&ctx, &kernel_notif,
f5ffbd77 452 sizeof(kernel_notif), lttng_alignof(kernel_notif));
99d223ad
FD
453
454 /*
455 * Write the capture buffer. No need to realigned as the below is a raw
456 * char* buffer.
457 */
458 event_notifier_group->ops->event_write(&ctx, &notif->capture_buf,
f5ffbd77 459 capture_buffer_content_len, 1);
99d223ad 460
21f58fb7
FD
461 event_notifier_group->ops->event_commit(&ctx);
462 irq_work_queue(&event_notifier_group->wakeup_pending);
463}
99d223ad 464
f125ded4
MD
465/*
466 * Validate that the buffer has enough room to hold empty capture fields.
467 */
468static
469bool validate_buffer_len(struct lttng_event_notifier_notification *notif, size_t captures_left)
470{
471 if (notif->writer.end_write_pos - notif->writer.write_pos < MSG_WRITE_NIL_LEN * captures_left)
472 return false;
473 return true;
474}
475
a67ba386 476void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier *event_notifier,
c3eddb2e 477 const char *stack_data,
a92e844e 478 struct lttng_kernel_probe_ctx *probe_ctx,
a67ba386 479 struct lttng_kernel_notification_ctx *notif_ctx)
99d223ad
FD
480{
481 struct lttng_event_notifier_notification notif = { 0 };
f125ded4 482 size_t captures_left;
99d223ad 483
f125ded4
MD
484 if (notification_init(&notif, event_notifier))
485 goto error;
486
487 captures_left = event_notifier->priv->num_captures;
488 if (!validate_buffer_len(&notif, captures_left))
489 goto error;
99d223ad 490
c3eddb2e 491 if (unlikely(notif_ctx->eval_capture)) {
218585b9 492 struct lttng_kernel_bytecode_runtime *capture_bc_runtime;
99d223ad
FD
493
494 /*
495 * Iterate over all the capture bytecodes. If the interpreter
496 * functions returns successfully, append the value of the
497 * `output` parameter to the capture buffer. If the interpreter
498 * fails, append an empty capture to the buffer.
499 */
c3eddb2e 500 list_for_each_entry_rcu(capture_bc_runtime,
a67ba386 501 &event_notifier->priv->capture_bytecode_runtime_head, node) {
99d223ad 502 struct lttng_interpreter_output output;
736f2dd6 503 uint8_t *save_pos;
f125ded4 504 int ret = -1;
99d223ad 505
736f2dd6 506 lttng_msgpack_save_writer_pos(&notif.writer, &save_pos);
f125ded4 507 captures_left--;
8a445457
MD
508 if (capture_bc_runtime->interpreter_func(capture_bc_runtime,
509 stack_data, probe_ctx, &output) == LTTNG_KERNEL_BYTECODE_INTERPRETER_OK)
99d223ad 510 ret = notification_append_capture(&notif, &output);
f125ded4 511 if (ret || !validate_buffer_len(&notif, captures_left)) {
736f2dd6 512 /*
f125ded4
MD
513 * On append capture error or if the generated
514 * buffer data would not leave enough room to
515 * write empty capture fields for the remaining
516 * fields, skip the field capture by restoring
517 * the msgpack writer position and writing an
518 * empty capture field.
736f2dd6
MD
519 */
520 lttng_msgpack_restore_writer_pos(&notif.writer, save_pos);
f125ded4
MD
521 ret = notification_append_empty_capture(&notif);
522 WARN_ON_ONCE(ret);
736f2dd6 523 }
99d223ad
FD
524 }
525 }
526
f125ded4
MD
527 if (notif.has_captures && lttng_msgpack_end_array(&notif.writer))
528 goto error;
529
99d223ad
FD
530 /*
531 * Send the notification (including the capture buffer) to the
532 * sessiond.
533 */
534 notification_send(&notif, event_notifier);
f125ded4
MD
535 return;
536
537error:
538 record_error(event_notifier);
99d223ad
FD
539 return;
540}
This page took 0.067844 seconds and 4 git commands to generate.