page alloc wrapper: Fix get_pfnblock_flags_mask prototype
[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 static
250 int capture_sequence(struct lttng_msgpack_writer *writer,
251 struct lttng_interpreter_output *output)
252 {
253 const struct lttng_kernel_type_integer *integer_type = NULL;
254 const struct lttng_kernel_type_common *nested_type;
255 uint8_t *ptr;
256 bool signedness;
257 int ret, i;
258
259 ret = lttng_msgpack_begin_array(writer, output->u.sequence.nr_elem);
260 if (ret) {
261 goto end;
262 }
263
264 ptr = (uint8_t *) output->u.sequence.ptr;
265 nested_type = output->u.sequence.nested_type;
266 switch (nested_type->type) {
267 case lttng_kernel_type_integer:
268 integer_type = lttng_kernel_get_type_integer(nested_type);
269 break;
270 case lttng_kernel_type_enum:
271 /* Treat enumeration as an integer. */
272 integer_type = lttng_kernel_get_type_integer(lttng_kernel_get_type_enum(nested_type)->container_type);
273 break;
274 default:
275 /* Capture of array of non-integer are not supported. */
276 WARN_ON_ONCE(1);
277 ret = -1;
278 goto end;
279 }
280 signedness = integer_type->signedness;
281 for (i = 0; i < output->u.sequence.nr_elem; i++) {
282 if (signedness) {
283 int64_t v;
284
285 ret = capture_sequence_element_signed(ptr, integer_type, &v);
286 if (ret) {
287 goto end;
288 }
289 ret = lttng_msgpack_write_signed_integer(writer, v);
290 if (ret) {
291 goto end;
292 }
293 } else {
294 uint64_t v;
295
296 ret = capture_sequence_element_unsigned(ptr, integer_type, &v);
297 if (ret) {
298 goto end;
299 }
300 ret = lttng_msgpack_write_unsigned_integer(writer, v);
301 if (ret) {
302 goto end;
303 }
304 }
305
306 /*
307 * We assume that alignment is smaller or equal to the size.
308 * This currently holds true but if it changes in the future,
309 * we will want to change the pointer arithmetics below to
310 * take into account that the next element might be further
311 * away.
312 */
313 WARN_ON_ONCE(integer_type->alignment > integer_type->size);
314
315 /* Size is in number of bits. */
316 ptr += (integer_type->size / CHAR_BIT) ;
317 }
318
319 ret = lttng_msgpack_end_array(writer);
320 end:
321 return ret;
322 }
323
324 static
325 int notification_append_capture(
326 struct lttng_event_notifier_notification *notif,
327 struct lttng_interpreter_output *output)
328 {
329 struct lttng_msgpack_writer *writer = &notif->writer;
330 int ret = 0;
331
332 switch (output->type) {
333 case LTTNG_INTERPRETER_TYPE_S64:
334 ret = lttng_msgpack_write_signed_integer(writer, output->u.s);
335 break;
336 case LTTNG_INTERPRETER_TYPE_U64:
337 ret = lttng_msgpack_write_unsigned_integer(writer, output->u.u);
338 break;
339 case LTTNG_INTERPRETER_TYPE_STRING:
340 if (output->u.str.user) {
341 ret = lttng_msgpack_write_user_str(writer, output->u.str.user_str);
342 } else {
343 ret = lttng_msgpack_write_str(writer, output->u.str.str);
344 }
345 break;
346 case LTTNG_INTERPRETER_TYPE_SEQUENCE:
347 ret = capture_sequence(writer, output);
348 break;
349 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM:
350 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM:
351 ret = capture_enum(writer, output);
352 break;
353 default:
354 ret = -1;
355 WARN_ON_ONCE(1);
356 }
357 return ret;
358 }
359
360 static
361 int notification_append_empty_capture(
362 struct lttng_event_notifier_notification *notif)
363 {
364 return lttng_msgpack_write_nil(&notif->writer);
365 }
366
367 static
368 int notification_init(struct lttng_event_notifier_notification *notif,
369 struct lttng_kernel_event_notifier *event_notifier)
370 {
371 struct lttng_msgpack_writer *writer = &notif->writer;
372 int ret = 0;
373
374 notif->has_captures = false;
375
376 if (event_notifier->priv->num_captures > 0) {
377 lttng_msgpack_writer_init(writer, notif->capture_buf,
378 CAPTURE_BUFFER_SIZE);
379
380 ret = lttng_msgpack_begin_array(writer, event_notifier->priv->num_captures);
381 if (ret) {
382 goto end;
383 }
384
385 notif->has_captures = true;
386 }
387
388 end:
389 return ret;
390 }
391
392 static
393 void record_error(struct lttng_kernel_event_notifier *event_notifier)
394 {
395
396 struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
397 struct lttng_counter *error_counter;
398 size_t dimension_index[1];
399 int ret;
400
401 /*
402 * smp_load_acquire paired with smp_store_release orders creation of
403 * the error counter and setting error_counter_len before the
404 * error_counter is used.
405 */
406 error_counter = smp_load_acquire(&event_notifier_group->error_counter);
407 /* This group may not have an error counter attached to it. */
408 if (!error_counter)
409 return;
410
411 dimension_index[0] = event_notifier->priv->error_counter_index;
412
413 ret = error_counter->ops->counter_add(error_counter->counter,
414 dimension_index, 1);
415 if (ret)
416 WARN_ON_ONCE(1);
417 }
418
419 static
420 void notification_send(struct lttng_event_notifier_notification *notif,
421 struct lttng_kernel_event_notifier *event_notifier)
422 {
423 struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
424 struct lttng_kernel_ring_buffer_ctx ctx;
425 struct lttng_kernel_abi_event_notifier_notification kernel_notif;
426 size_t capture_buffer_content_len, reserve_size;
427 int ret;
428
429 reserve_size = sizeof(kernel_notif);
430 kernel_notif.token = event_notifier->priv->parent.user_token;
431
432 if (notif->has_captures) {
433 capture_buffer_content_len = notif->writer.write_pos - notif->writer.buffer;
434 } else {
435 capture_buffer_content_len = 0;
436 }
437
438 WARN_ON_ONCE(capture_buffer_content_len > CAPTURE_BUFFER_SIZE);
439
440 reserve_size += capture_buffer_content_len;
441 kernel_notif.capture_buf_size = capture_buffer_content_len;
442
443 lib_ring_buffer_ctx_init(&ctx, event_notifier_group->chan, reserve_size,
444 lttng_alignof(kernel_notif), NULL);
445 ret = event_notifier_group->ops->event_reserve(&ctx);
446 if (ret < 0) {
447 record_error(event_notifier);
448 return;
449 }
450
451 /* Write the notif structure. */
452 event_notifier_group->ops->event_write(&ctx, &kernel_notif,
453 sizeof(kernel_notif), lttng_alignof(kernel_notif));
454
455 /*
456 * Write the capture buffer. No need to realigned as the below is a raw
457 * char* buffer.
458 */
459 event_notifier_group->ops->event_write(&ctx, &notif->capture_buf,
460 capture_buffer_content_len, 1);
461
462 event_notifier_group->ops->event_commit(&ctx);
463 irq_work_queue(&event_notifier_group->wakeup_pending);
464 }
465
466 /*
467 * Validate that the buffer has enough room to hold empty capture fields.
468 */
469 static
470 bool validate_buffer_len(struct lttng_event_notifier_notification *notif, size_t captures_left)
471 {
472 if (notif->writer.end_write_pos - notif->writer.write_pos < MSG_WRITE_NIL_LEN * captures_left)
473 return false;
474 return true;
475 }
476
477 void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier *event_notifier,
478 const char *stack_data,
479 struct lttng_kernel_probe_ctx *probe_ctx,
480 struct lttng_kernel_notification_ctx *notif_ctx)
481 {
482 struct lttng_event_notifier_notification notif = { 0 };
483 size_t captures_left;
484
485 if (notification_init(&notif, event_notifier))
486 goto error;
487
488 captures_left = event_notifier->priv->num_captures;
489 if (!validate_buffer_len(&notif, captures_left))
490 goto error;
491
492 if (unlikely(notif_ctx->eval_capture)) {
493 struct lttng_kernel_bytecode_runtime *capture_bc_runtime;
494
495 /*
496 * Iterate over all the capture bytecodes. If the interpreter
497 * functions returns successfully, append the value of the
498 * `output` parameter to the capture buffer. If the interpreter
499 * fails, append an empty capture to the buffer.
500 */
501 list_for_each_entry_rcu(capture_bc_runtime,
502 &event_notifier->priv->capture_bytecode_runtime_head, node) {
503 struct lttng_interpreter_output output;
504 uint8_t *save_pos;
505 int ret = -1;
506
507 lttng_msgpack_save_writer_pos(&notif.writer, &save_pos);
508 captures_left--;
509 if (capture_bc_runtime->interpreter_func(capture_bc_runtime,
510 stack_data, probe_ctx, &output) == LTTNG_KERNEL_BYTECODE_INTERPRETER_OK)
511 ret = notification_append_capture(&notif, &output);
512 if (ret || !validate_buffer_len(&notif, captures_left)) {
513 /*
514 * On append capture error or if the generated
515 * buffer data would not leave enough room to
516 * write empty capture fields for the remaining
517 * fields, skip the field capture by restoring
518 * the msgpack writer position and writing an
519 * empty capture field.
520 */
521 lttng_msgpack_restore_writer_pos(&notif.writer, save_pos);
522 ret = notification_append_empty_capture(&notif);
523 WARN_ON_ONCE(ret);
524 }
525 }
526 }
527
528 if (notif.has_captures && lttng_msgpack_end_array(&notif.writer))
529 goto error;
530
531 /*
532 * Send the notification (including the capture buffer) to the
533 * sessiond.
534 */
535 notification_send(&notif, event_notifier);
536 return;
537
538 error:
539 record_error(event_notifier);
540 return;
541 }
This page took 0.042531 seconds and 5 git commands to generate.