Rename "tsc" to "timestamp"
[lttng-modules.git] / src / lttng-event-notifier-notification.c
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
8 #include <asm/barrier.h>
9 #include <linux/bug.h>
10
11 #include <lttng/lttng-bytecode.h>
12 #include <lttng/events.h>
13 #include <lttng/msgpack.h>
14 #include <lttng/event-notifier-notification.h>
15 #include <lttng/events-internal.h>
16 #include <lttng/probe-user.h>
17
18 /*
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.
25 */
26 #define CAPTURE_BUFFER_SIZE 512
27
28 #define MSG_WRITE_NIL_LEN 1
29
30 struct 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
38 static
39 int 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) {
51 goto end;
52 }
53
54 ret = lttng_msgpack_write_str(writer, "type");
55 if (ret) {
56 goto end;
57 }
58
59 ret = lttng_msgpack_write_str(writer, "enum");
60 if (ret) {
61 goto end;
62 }
63
64 ret = lttng_msgpack_write_str(writer, "value");
65 if (ret) {
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) {
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) {
79 goto end;
80 }
81 break;
82 default:
83 WARN_ON_ONCE(1);
84 ret = -1;
85 goto end;
86 }
87
88 ret = lttng_msgpack_end_map(writer);
89 end:
90 return ret;
91 }
92
93 static
94 int capture_sequence_element_signed(uint8_t *ptr,
95 const struct lttng_kernel_type_integer *type,
96 int64_t *_value)
97 {
98 int64_t value = 0;
99 unsigned int size = type->size;
100 bool user = type->user;
101 bool byte_order_reversed = type->reverse_byte_order;
102
103 switch (size) {
104 case 8:
105 {
106 int8_t tmp;
107
108 if (user) {
109 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int8_t)))
110 return -1;
111 } else {
112 tmp = *ptr;
113 }
114 value = tmp;
115 break;
116 }
117 case 16:
118 {
119 int16_t tmp;
120
121 if (user) {
122 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int16_t)))
123 return -1;
124 } else {
125 tmp = *(int16_t *) ptr;
126 }
127 if (byte_order_reversed)
128 __swab16s(&tmp);
129 value = tmp;
130 break;
131 }
132 case 32:
133 {
134 int32_t tmp;
135
136 if (user) {
137 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int32_t)))
138 return -1;
139 } else {
140 tmp = *(int32_t *) ptr;
141 }
142 if (byte_order_reversed)
143 __swab32s(&tmp);
144 value = tmp;
145 break;
146 }
147 case 64:
148 {
149 int64_t tmp;
150
151 if (user) {
152 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(int64_t)))
153 return -1;
154 } else {
155 tmp = *(int64_t *) ptr;
156 }
157 if (byte_order_reversed)
158 __swab64s(&tmp);
159 value = tmp;
160 break;
161 }
162 default:
163 WARN_ON_ONCE(1);
164 return -1;
165 }
166
167 *_value = value;
168 return 0;
169 }
170
171 static
172 int capture_sequence_element_unsigned(uint8_t *ptr,
173 const struct lttng_kernel_type_integer *type,
174 uint64_t *_value)
175 {
176 uint64_t value = 0;
177 unsigned int size = type->size;
178 bool user = type->user;
179 bool byte_order_reversed = type->reverse_byte_order;
180
181 switch (size) {
182 case 8:
183 {
184 uint8_t tmp;
185
186 if (user) {
187 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint8_t)))
188 return -1;
189 } else {
190 tmp = *ptr;
191 }
192 value = tmp;
193 break;
194 }
195 case 16:
196 {
197 uint16_t tmp;
198
199 if (user) {
200 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint16_t)))
201 return -1;
202 } else {
203 tmp = *(uint16_t *) ptr;
204 }
205 if (byte_order_reversed)
206 __swab16s(&tmp);
207 value = tmp;
208 break;
209 }
210 case 32:
211 {
212 uint32_t tmp;
213
214 if (user) {
215 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint32_t)))
216 return -1;
217 } else {
218 tmp = *(uint32_t *) ptr;
219 }
220 if (byte_order_reversed)
221 __swab32s(&tmp);
222 value = tmp;
223 break;
224 }
225 case 64:
226 {
227 uint64_t tmp;
228
229 if (user) {
230 if (lttng_copy_from_user_check_nofault(&tmp, ptr, sizeof(uint64_t)))
231 return -1;
232 } else {
233 tmp = *(uint64_t *) ptr;
234 }
235 if (byte_order_reversed)
236 __swab64s(&tmp);
237 value = tmp;
238 break;
239 }
240 default:
241 WARN_ON_ONCE(1);
242 return -1;
243 }
244
245 *_value = value;
246 return 0;
247 }
248
249 int capture_sequence(struct lttng_msgpack_writer *writer,
250 struct lttng_interpreter_output *output)
251 {
252 const struct lttng_kernel_type_integer *integer_type = NULL;
253 const struct lttng_kernel_type_common *nested_type;
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) {
260 goto end;
261 }
262
263 ptr = (uint8_t *) output->u.sequence.ptr;
264 nested_type = output->u.sequence.nested_type;
265 switch (nested_type->type) {
266 case lttng_kernel_type_integer:
267 integer_type = lttng_kernel_get_type_integer(nested_type);
268 break;
269 case lttng_kernel_type_enum:
270 /* Treat enumeration as an integer. */
271 integer_type = lttng_kernel_get_type_integer(lttng_kernel_get_type_enum(nested_type)->container_type);
272 break;
273 default:
274 /* Capture of array of non-integer are not supported. */
275 WARN_ON_ONCE(1);
276 ret = -1;
277 goto end;
278 }
279 signedness = integer_type->signedness;
280 for (i = 0; i < output->u.sequence.nr_elem; i++) {
281 if (signedness) {
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);
289 if (ret) {
290 goto end;
291 }
292 } else {
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);
300 if (ret) {
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 */
312 WARN_ON_ONCE(integer_type->alignment > integer_type->size);
313
314 /* Size is in number of bits. */
315 ptr += (integer_type->size / CHAR_BIT) ;
316 }
317
318 ret = lttng_msgpack_end_array(writer);
319 end:
320 return ret;
321 }
322
323 static
324 int 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);
334 break;
335 case LTTNG_INTERPRETER_TYPE_U64:
336 ret = lttng_msgpack_write_unsigned_integer(writer, output->u.u);
337 break;
338 case LTTNG_INTERPRETER_TYPE_STRING:
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 }
344 break;
345 case LTTNG_INTERPRETER_TYPE_SEQUENCE:
346 ret = capture_sequence(writer, output);
347 break;
348 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM:
349 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM:
350 ret = capture_enum(writer, output);
351 break;
352 default:
353 ret = -1;
354 WARN_ON_ONCE(1);
355 }
356 return ret;
357 }
358
359 static
360 int notification_append_empty_capture(
361 struct lttng_event_notifier_notification *notif)
362 {
363 return lttng_msgpack_write_nil(&notif->writer);
364 }
365
366 static
367 int notification_init(struct lttng_event_notifier_notification *notif,
368 struct lttng_kernel_event_notifier *event_notifier)
369 {
370 struct lttng_msgpack_writer *writer = &notif->writer;
371 int ret = 0;
372
373 notif->has_captures = false;
374
375 if (event_notifier->priv->num_captures > 0) {
376 lttng_msgpack_writer_init(writer, notif->capture_buf,
377 CAPTURE_BUFFER_SIZE);
378
379 ret = lttng_msgpack_begin_array(writer, event_notifier->priv->num_captures);
380 if (ret) {
381 goto end;
382 }
383
384 notif->has_captures = true;
385 }
386
387 end:
388 return ret;
389 }
390
391 static
392 void record_error(struct lttng_kernel_event_notifier *event_notifier)
393 {
394
395 struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
396 struct lttng_counter *error_counter;
397 size_t dimension_index[1];
398 int ret;
399
400 /*
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.
404 */
405 error_counter = smp_load_acquire(&event_notifier_group->error_counter);
406 /* This group may not have an error counter attached to it. */
407 if (!error_counter)
408 return;
409
410 dimension_index[0] = event_notifier->priv->error_counter_index;
411
412 ret = error_counter->ops->counter_add(error_counter->counter,
413 dimension_index, 1);
414 if (ret)
415 WARN_ON_ONCE(1);
416 }
417
418 static
419 void notification_send(struct lttng_event_notifier_notification *notif,
420 struct lttng_kernel_event_notifier *event_notifier)
421 {
422 struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
423 struct lttng_kernel_ring_buffer_ctx ctx;
424 struct lttng_kernel_abi_event_notifier_notification kernel_notif;
425 size_t capture_buffer_content_len, reserve_size;
426 int ret;
427
428 reserve_size = sizeof(kernel_notif);
429 kernel_notif.token = event_notifier->priv->parent.user_token;
430
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
442 lib_ring_buffer_ctx_init(&ctx, event_notifier_group->chan, reserve_size,
443 lttng_alignof(kernel_notif), NULL);
444 ret = event_notifier_group->ops->event_reserve(&ctx);
445 if (ret < 0) {
446 record_error(event_notifier);
447 return;
448 }
449
450 /* Write the notif structure. */
451 event_notifier_group->ops->event_write(&ctx, &kernel_notif,
452 sizeof(kernel_notif), lttng_alignof(kernel_notif));
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,
459 capture_buffer_content_len, 1);
460
461 event_notifier_group->ops->event_commit(&ctx);
462 irq_work_queue(&event_notifier_group->wakeup_pending);
463 }
464
465 /*
466 * Validate that the buffer has enough room to hold empty capture fields.
467 */
468 static
469 bool 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
476 void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier *event_notifier,
477 const char *stack_data,
478 struct lttng_kernel_probe_ctx *probe_ctx,
479 struct lttng_kernel_notification_ctx *notif_ctx)
480 {
481 struct lttng_event_notifier_notification notif = { 0 };
482 size_t captures_left;
483
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;
490
491 if (unlikely(notif_ctx->eval_capture)) {
492 struct lttng_kernel_bytecode_runtime *capture_bc_runtime;
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 */
500 list_for_each_entry_rcu(capture_bc_runtime,
501 &event_notifier->priv->capture_bytecode_runtime_head, node) {
502 struct lttng_interpreter_output output;
503 uint8_t *save_pos;
504 int ret = -1;
505
506 lttng_msgpack_save_writer_pos(&notif.writer, &save_pos);
507 captures_left--;
508 if (capture_bc_runtime->interpreter_func(capture_bc_runtime,
509 stack_data, probe_ctx, &output) == LTTNG_KERNEL_BYTECODE_INTERPRETER_OK)
510 ret = notification_append_capture(&notif, &output);
511 if (ret || !validate_buffer_len(&notif, captures_left)) {
512 /*
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.
519 */
520 lttng_msgpack_restore_writer_pos(&notif.writer, save_pos);
521 ret = notification_append_empty_capture(&notif);
522 WARN_ON_ONCE(ret);
523 }
524 }
525 }
526
527 if (notif.has_captures && lttng_msgpack_end_array(&notif.writer))
528 goto error;
529
530 /*
531 * Send the notification (including the capture buffer) to the
532 * sessiond.
533 */
534 notification_send(&notif, event_notifier);
535 return;
536
537 error:
538 record_error(event_notifier);
539 return;
540 }
This page took 0.039748 seconds and 4 git commands to generate.