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