lttng-modules v0.19-stable: setup_trace_write: Fix recursive locking
[lttng-modules.git] / ltt-serialize.c
CommitLineData
1c8284eb
MD
1/*
2 * LTTng serializing code.
3 *
4 * Copyright Mathieu Desnoyers, March 2007.
5 *
6 * Dual LGPL v2.1/GPL v2 license.
7 *
8 * See this discussion about weirdness about passing va_list and then va_list to
9 * functions. (related to array argument passing). va_list seems to be
10 * implemented as an array on x86_64, but not on i386... This is why we pass a
11 * va_list * to ltt_vtrace.
12 */
13
14#include <stdarg.h>
15#include <linux/ctype.h>
16#include <linux/string.h>
17#include <linux/module.h>
18
19#include "ltt-tracer.h"
20#include "ltt-relay-lockless.h"
21
22enum ltt_type {
23 LTT_TYPE_SIGNED_INT,
24 LTT_TYPE_UNSIGNED_INT,
25 LTT_TYPE_STRING,
26 LTT_TYPE_NONE,
27};
28
29#define LTT_ATTRIBUTE_NETWORK_BYTE_ORDER (1<<1)
30
31/*
32 * Stack used to keep track of string length at size calculation, passed to
33 * string copy to handle racy input string updates.
34 * Can be used by any context; this is ensured by putting the stack position
35 * back to its original position after using it.
36 */
37#define TRACER_STACK_LEN (PAGE_SIZE / sizeof(unsigned long))
38static DEFINE_PER_CPU(unsigned long [TRACER_STACK_LEN],
39 tracer_stack);
40static DEFINE_PER_CPU(unsigned int, tracer_stack_pos);
41
42/*
43 * Inspired from vsnprintf
44 *
45 * The serialization format string supports the basic printf format strings.
46 * In addition, it defines new formats that can be used to serialize more
47 * complex/non portable data structures.
48 *
49 * Typical use:
50 *
51 * field_name %ctype
52 * field_name #tracetype %ctype
53 * field_name #tracetype %ctype1 %ctype2 ...
54 *
55 * A conversion is performed between format string types supported by GCC and
56 * the trace type requested. GCC type is used to perform type checking on format
57 * strings. Trace type is used to specify the exact binary representation
58 * in the trace. A mapping is done between one or more GCC types to one trace
59 * type. Sign extension, if required by the conversion, is performed following
60 * the trace type.
61 *
62 * If a gcc format is not declared with a trace format, the gcc format is
63 * also used as binary representation in the trace.
64 *
65 * Strings are supported with %s.
66 * A single tracetype (sequence) can take multiple c types as parameter.
67 *
68 * c types:
69 *
70 * see printf(3).
71 *
72 * Note: to write a uint32_t in a trace, the following expression is recommended
73 * si it can be portable:
74 *
75 * ("#4u%lu", (unsigned long)var)
76 *
77 * trace types:
78 *
79 * Serialization specific formats :
80 *
81 * Fixed size integers
82 * #1u writes uint8_t
83 * #2u writes uint16_t
84 * #4u writes uint32_t
85 * #8u writes uint64_t
86 * #1d writes int8_t
87 * #2d writes int16_t
88 * #4d writes int32_t
89 * #8d writes int64_t
90 * i.e.:
91 * #1u%lu #2u%lu #4d%lu #8d%lu #llu%hu #d%lu
92 *
93 * * Attributes:
94 *
95 * n: (for network byte order)
96 * #ntracetype%ctype
97 * is written in the trace in network byte order.
98 *
99 * i.e.: #bn4u%lu, #n%lu, #b%u
100 *
101 * TODO (eventually)
102 * Variable length sequence
103 * #a #tracetype1 #tracetype2 %array_ptr %elem_size %num_elems
104 * In the trace:
105 * #a specifies that this is a sequence
106 * #tracetype1 is the type of elements in the sequence
107 * #tracetype2 is the type of the element count
108 * GCC input:
109 * array_ptr is a pointer to an array that contains members of size
110 * elem_size.
111 * num_elems is the number of elements in the array.
112 * i.e.: #a #lu #lu %p %lu %u
113 *
114 * Callback
115 * #k callback (taken from the probe data)
116 * The following % arguments are exepected by the callback
117 *
118 * i.e.: #a #lu #lu #k %p
119 *
120 * Note: No conversion is done from floats to integers, nor from integers to
121 * floats between c types and trace types. float conversion from double to float
122 * or from float to double is also not supported.
123 *
124 * REMOVE
125 * %*b expects sizeof(data), data
126 * where sizeof(data) is 1, 2, 4 or 8
127 *
128 * Fixed length struct, union or array.
129 * FIXME: unable to extract those sizes statically.
130 * %*r expects sizeof(*ptr), ptr
131 * %*.*r expects sizeof(*ptr), __alignof__(*ptr), ptr
132 * struct and unions removed.
133 * Fixed length array:
134 * [%p]#a[len #tracetype]
135 * i.e.: [%p]#a[12 #lu]
136 *
137 * Variable length sequence
138 * %*.*:*v expects sizeof(*ptr), __alignof__(*ptr), elem_num, ptr
139 * where elem_num is the number of elements in the sequence
140 */
141static inline
142const char *parse_trace_type(const char *fmt, char *trace_size,
143 enum ltt_type *trace_type,
144 unsigned long *attributes)
145{
146 int qualifier; /* 'h', 'l', or 'L' for integer fields */
147 /* 'z' support added 23/7/1999 S.H. */
148 /* 'z' changed to 'Z' --davidm 1/25/99 */
149 /* 't' added for ptrdiff_t */
150
151 /* parse attributes. */
152repeat:
153 switch (*fmt) {
154 case 'n':
155 *attributes |= LTT_ATTRIBUTE_NETWORK_BYTE_ORDER;
156 ++fmt;
157 goto repeat;
158 }
159
160 /* get the conversion qualifier */
161 qualifier = -1;
162 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
163 *fmt == 'Z' || *fmt == 'z' || *fmt == 't' ||
164 *fmt == 'S' || *fmt == '1' || *fmt == '2' ||
165 *fmt == '4' || *fmt == 8) {
166 qualifier = *fmt;
167 ++fmt;
168 if (qualifier == 'l' && *fmt == 'l') {
169 qualifier = 'L';
170 ++fmt;
171 }
172 }
173
174 switch (*fmt) {
175 case 'c':
176 *trace_type = LTT_TYPE_UNSIGNED_INT;
177 *trace_size = sizeof(unsigned char);
178 goto parse_end;
179 case 's':
180 *trace_type = LTT_TYPE_STRING;
181 goto parse_end;
182 case 'p':
183 *trace_type = LTT_TYPE_UNSIGNED_INT;
184 *trace_size = sizeof(void *);
185 goto parse_end;
186 case 'd':
187 case 'i':
188 *trace_type = LTT_TYPE_SIGNED_INT;
189 break;
190 case 'o':
191 case 'u':
192 case 'x':
193 case 'X':
194 *trace_type = LTT_TYPE_UNSIGNED_INT;
195 break;
196 default:
197 if (!*fmt)
198 --fmt;
199 goto parse_end;
200 }
201 switch (qualifier) {
202 case 'L':
203 *trace_size = sizeof(long long);
204 break;
205 case 'l':
206 *trace_size = sizeof(long);
207 break;
208 case 'Z':
209 case 'z':
210 *trace_size = sizeof(size_t);
211 break;
212 case 't':
213 *trace_size = sizeof(ptrdiff_t);
214 break;
215 case 'h':
216 *trace_size = sizeof(short);
217 break;
218 case '1':
219 *trace_size = sizeof(uint8_t);
220 break;
221 case '2':
222 *trace_size = sizeof(uint16_t);
223 break;
224 case '4':
225 *trace_size = sizeof(uint32_t);
226 break;
227 case '8':
228 *trace_size = sizeof(uint64_t);
229 break;
230 default:
231 *trace_size = sizeof(int);
232 }
233
234parse_end:
235 return fmt;
236}
237
238/*
239 * Restrictions:
240 * Field width and precision are *not* supported.
241 * %n not supported.
242 */
243static inline
244const char *parse_c_type(const char *fmt, char *c_size, enum ltt_type *c_type,
245 char *outfmt)
246{
247 int qualifier; /* 'h', 'l', or 'L' for integer fields */
248 /* 'z' support added 23/7/1999 S.H. */
249 /* 'z' changed to 'Z' --davidm 1/25/99 */
250 /* 't' added for ptrdiff_t */
251
252 /* process flags : ignore standard print formats for now. */
253repeat:
254 switch (*fmt) {
255 case '-':
256 case '+':
257 case ' ':
258 case '#':
259 case '0':
260 ++fmt;
261 goto repeat;
262 }
263
264 /* get the conversion qualifier */
265 qualifier = -1;
266 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
267 *fmt == 'Z' || *fmt == 'z' || *fmt == 't' ||
268 *fmt == 'S') {
269 qualifier = *fmt;
270 ++fmt;
271 if (qualifier == 'l' && *fmt == 'l') {
272 qualifier = 'L';
273 ++fmt;
274 }
275 }
276
277 if (outfmt) {
278 if (qualifier != -1)
279 *outfmt++ = (char)qualifier;
280 *outfmt++ = *fmt;
281 *outfmt = 0;
282 }
283
284 switch (*fmt) {
285 case 'c':
286 *c_type = LTT_TYPE_UNSIGNED_INT;
287 *c_size = sizeof(unsigned char);
288 goto parse_end;
289 case 's':
290 *c_type = LTT_TYPE_STRING;
291 goto parse_end;
292 case 'p':
293 *c_type = LTT_TYPE_UNSIGNED_INT;
294 *c_size = sizeof(void *);
295 goto parse_end;
296 case 'd':
297 case 'i':
298 *c_type = LTT_TYPE_SIGNED_INT;
299 break;
300 case 'o':
301 case 'u':
302 case 'x':
303 case 'X':
304 *c_type = LTT_TYPE_UNSIGNED_INT;
305 break;
306 default:
307 if (!*fmt)
308 --fmt;
309 goto parse_end;
310 }
311 switch (qualifier) {
312 case 'L':
313 *c_size = sizeof(long long);
314 break;
315 case 'l':
316 *c_size = sizeof(long);
317 break;
318 case 'Z':
319 case 'z':
320 *c_size = sizeof(size_t);
321 break;
322 case 't':
323 *c_size = sizeof(ptrdiff_t);
324 break;
325 case 'h':
326 *c_size = sizeof(short);
327 break;
328 default:
329 *c_size = sizeof(int);
330 }
331
332parse_end:
333 return fmt;
334}
335
336static inline
337size_t serialize_trace_data(struct ltt_chanbuf *buf, size_t buf_offset,
338 char trace_size, enum ltt_type trace_type,
339 char c_size, enum ltt_type c_type,
340 unsigned int *stack_pos_ctx,
341 int *largest_align,
342 va_list *args)
343{
344 union {
345 unsigned long v_ulong;
346 uint64_t v_uint64;
347 struct {
348 const char *s;
349 size_t len;
350 } v_string;
351 } tmp;
352
353 /*
354 * Be careful about sign extension here.
355 * Sign extension is done with the destination (trace) type.
356 */
357 switch (trace_type) {
358 case LTT_TYPE_SIGNED_INT:
359 switch (c_size) {
360 case 1:
361 tmp.v_ulong = (long)(int8_t)va_arg(*args, int);
362 break;
363 case 2:
364 tmp.v_ulong = (long)(int16_t)va_arg(*args, int);
365 break;
366 case 4:
367 tmp.v_ulong = (long)(int32_t)va_arg(*args, int);
368 break;
369 case 8:
370 tmp.v_uint64 = va_arg(*args, int64_t);
371 break;
372 default:
373 BUG();
374 }
375 break;
376 case LTT_TYPE_UNSIGNED_INT:
377 switch (c_size) {
378 case 1:
379 tmp.v_ulong = (unsigned long)(uint8_t)va_arg(*args, unsigned int);
380 break;
381 case 2:
382 tmp.v_ulong = (unsigned long)(uint16_t)va_arg(*args, unsigned int);
383 break;
384 case 4:
385 tmp.v_ulong = (unsigned long)(uint32_t)va_arg(*args, unsigned int);
386 break;
387 case 8:
388 tmp.v_uint64 = va_arg(*args, uint64_t);
389 break;
390 default:
391 BUG();
392 }
393 break;
394 case LTT_TYPE_STRING:
395 tmp.v_string.s = va_arg(*args, const char *);
396 if ((unsigned long)tmp.v_string.s < PAGE_SIZE)
397 tmp.v_string.s = "<NULL>";
398 if (!buf) {
399 /*
400 * Reserve tracer stack entry.
401 */
402 __get_cpu_var(tracer_stack_pos)++;
403 WARN_ON_ONCE(__get_cpu_var(tracer_stack_pos)
404 > TRACER_STACK_LEN);
405 barrier();
406 __get_cpu_var(tracer_stack)[*stack_pos_ctx] =
407 strlen(tmp.v_string.s) + 1;
408 }
409 tmp.v_string.len = __get_cpu_var(tracer_stack)
410 [(*stack_pos_ctx)++];
411 if (buf)
412 ltt_relay_strncpy(&buf->a, buf->a.chan, buf_offset,
413 tmp.v_string.s, tmp.v_string.len);
414 buf_offset += tmp.v_string.len;
415 goto copydone;
416 default:
417 BUG();
418 }
419
420 /*
421 * If trace_size is lower or equal to 4 bytes, there is no sign
422 * extension to do because we are already encoded in a long. Therefore,
423 * we can combine signed and unsigned ops. 4 bytes float also works
424 * with this, because we do a simple copy of 4 bytes into 4 bytes
425 * without manipulation (and we do not support conversion from integers
426 * to floats).
427 * It is also the case if c_size is 8 bytes, which is the largest
428 * possible integer.
429 */
430 if (ltt_get_alignment()) {
431 buf_offset += ltt_align(buf_offset, trace_size);
432 if (largest_align)
433 *largest_align = max_t(int, *largest_align, trace_size);
434 }
435 if (trace_size <= 4 || c_size == 8) {
436 if (buf) {
437 switch (trace_size) {
438 case 1:
439 if (c_size == 8)
440 ltt_relay_write(&buf->a, buf->a.chan,
441 buf_offset,
442 (uint8_t[]){ (uint8_t)tmp.v_uint64 },
443 sizeof(uint8_t));
444 else
445 ltt_relay_write(&buf->a, buf->a.chan,
446 buf_offset,
447 (uint8_t[]){ (uint8_t)tmp.v_ulong },
448 sizeof(uint8_t));
449 break;
450 case 2:
451 if (c_size == 8)
452 ltt_relay_write(&buf->a, buf->a.chan,
453 buf_offset,
454 (uint16_t[]){ (uint16_t)tmp.v_uint64 },
455 sizeof(uint16_t));
456 else
457 ltt_relay_write(&buf->a, buf->a.chan,
458 buf_offset,
459 (uint16_t[]){ (uint16_t)tmp.v_ulong },
460 sizeof(uint16_t));
461 break;
462 case 4:
463 if (c_size == 8)
464 ltt_relay_write(&buf->a, buf->a.chan,
465 buf_offset,
466 (uint32_t[]){ (uint32_t)tmp.v_uint64 },
467 sizeof(uint32_t));
468 else
469 ltt_relay_write(&buf->a, buf->a.chan,
470 buf_offset,
471 (uint32_t[]){ (uint32_t)tmp.v_ulong },
472 sizeof(uint32_t));
473 break;
474 case 8:
475 /*
476 * c_size cannot be other than 8 here because
477 * trace_size > 4.
478 */
479 ltt_relay_write(&buf->a, buf->a.chan, buf_offset,
480 (uint64_t[]){ (uint64_t)tmp.v_uint64 },
481 sizeof(uint64_t));
482 break;
483 default:
484 BUG();
485 }
486 }
487 buf_offset += trace_size;
488 goto copydone;
489 } else {
490 /*
491 * Perform sign extension.
492 */
493 if (buf) {
494 switch (trace_type) {
495 case LTT_TYPE_SIGNED_INT:
496 ltt_relay_write(&buf->a, buf->a.chan, buf_offset,
497 (int64_t[]){ (int64_t)tmp.v_ulong },
498 sizeof(int64_t));
499 break;
500 case LTT_TYPE_UNSIGNED_INT:
501 ltt_relay_write(&buf->a, buf->a.chan, buf_offset,
502 (uint64_t[]){ (uint64_t)tmp.v_ulong },
503 sizeof(uint64_t));
504 break;
505 default:
506 BUG();
507 }
508 }
509 buf_offset += trace_size;
510 goto copydone;
511 }
512
513copydone:
514 return buf_offset;
515}
516
517notrace size_t
518ltt_serialize_data(struct ltt_chanbuf *buf, size_t buf_offset,
519 struct ltt_serialize_closure *closure,
520 void *serialize_private, unsigned int stack_pos_ctx,
521 int *largest_align, const char *fmt, va_list *args)
522{
523 char trace_size = 0, c_size = 0; /*
524 * 0 (unset), 1, 2, 4, 8 bytes.
525 */
526 enum ltt_type trace_type = LTT_TYPE_NONE, c_type = LTT_TYPE_NONE;
527 unsigned long attributes = 0;
528
529 for (; *fmt ; ++fmt) {
530 switch (*fmt) {
531 case '#':
532 /* tracetypes (#) */
533 ++fmt; /* skip first '#' */
534 if (*fmt == '#') /* Escaped ## */
535 break;
536 attributes = 0;
537 fmt = parse_trace_type(fmt, &trace_size, &trace_type,
538 &attributes);
539 break;
540 case '%':
541 /* c types (%) */
542 ++fmt; /* skip first '%' */
543 if (*fmt == '%') /* Escaped %% */
544 break;
545 fmt = parse_c_type(fmt, &c_size, &c_type, NULL);
546 /*
547 * Output c types if no trace types has been
548 * specified.
549 */
550 if (!trace_size)
551 trace_size = c_size;
552 if (trace_type == LTT_TYPE_NONE)
553 trace_type = c_type;
554 if (c_type == LTT_TYPE_STRING)
555 trace_type = LTT_TYPE_STRING;
556 /* perform trace write */
557 buf_offset = serialize_trace_data(buf, buf_offset,
558 trace_size,
559 trace_type, c_size,
560 c_type,
561 &stack_pos_ctx,
562 largest_align,
563 args);
564 trace_size = 0;
565 c_size = 0;
566 trace_type = LTT_TYPE_NONE;
567 c_size = LTT_TYPE_NONE;
568 attributes = 0;
569 break;
570 /* default is to skip the text, doing nothing */
571 }
572 }
573 return buf_offset;
574}
575EXPORT_SYMBOL_GPL(ltt_serialize_data);
576
577static inline
578uint64_t unserialize_base_type(struct ltt_chanbuf *buf,
579 size_t *ppos, char trace_size,
580 enum ltt_type trace_type)
581{
582 uint64_t tmp;
583
584 *ppos += ltt_align(*ppos, trace_size);
585 ltt_relay_read(&buf->a, *ppos, &tmp, trace_size);
586 *ppos += trace_size;
587
588 switch (trace_type) {
589 case LTT_TYPE_SIGNED_INT:
590 switch (trace_size) {
591 case 1:
592 return (uint64_t)*(int8_t *)&tmp;
593 case 2:
594 return (uint64_t)*(int16_t *)&tmp;
595 case 4:
596 return (uint64_t)*(int32_t *)&tmp;
597 case 8:
598 return tmp;
599 }
600 break;
601 case LTT_TYPE_UNSIGNED_INT:
602 switch (trace_size) {
603 case 1:
604 return (uint64_t)*(uint8_t *)&tmp;
605 case 2:
606 return (uint64_t)*(uint16_t *)&tmp;
607 case 4:
608 return (uint64_t)*(uint32_t *)&tmp;
609 case 8:
610 return tmp;
611 }
612 break;
613 default:
614 break;
615 }
616
617 BUG();
618 return 0;
619}
620
621static
622int serialize_printf_data(struct ltt_chanbuf *buf, size_t *ppos,
623 char trace_size, enum ltt_type trace_type,
624 char c_size, enum ltt_type c_type, char *output,
625 ssize_t outlen, const char *outfmt)
626{
627 u64 value;
628 outlen = outlen < 0 ? 0 : outlen;
629
630 if (trace_type == LTT_TYPE_STRING) {
631 size_t len = ltt_relay_read_cstr(&buf->a, *ppos, output,
632 outlen);
633 *ppos += len + 1;
634 return len;
635 }
636
637 value = unserialize_base_type(buf, ppos, trace_size, trace_type);
638
639 if (c_size == 8)
640 return snprintf(output, outlen, outfmt, value);
641 else
642 return snprintf(output, outlen, outfmt, (unsigned int)value);
643}
644
645/**
646 * ltt_serialize_printf - Format a string and place it in a buffer
647 * @buf: The ltt-relay buffer that store binary data
648 * @buf_offset: binary data's offset in @buf (should be masked to use as offset)
649 * @msg_size: return message's length
650 * @output: The buffer to place the result into
651 * @outlen: The size of the buffer, including the trailing '\0'
652 * @fmt: The format string to use
653 *
654 * The return value is the number of characters which would
655 * be generated for the given input, excluding the trailing
656 * '\0', as per ISO C99. If the return is greater than or equal to @outlen,
657 * the resulting string is truncated.
658 */
659size_t ltt_serialize_printf(struct ltt_chanbuf *buf, unsigned long buf_offset,
660 size_t *msg_size, char *output, size_t outlen,
661 const char *fmt)
662{
663 char trace_size = 0, c_size = 0; /*
664 * 0 (unset), 1, 2, 4, 8 bytes.
665 */
666 enum ltt_type trace_type = LTT_TYPE_NONE, c_type = LTT_TYPE_NONE;
667 unsigned long attributes = 0;
668 char outfmt[4] = "%";
669 size_t outpos = 0;
670 size_t len;
671 size_t msgpos = buf_offset;
672
673 for (; *fmt ; ++fmt) {
674 switch (*fmt) {
675 case '#':
676 /* tracetypes (#) */
677 ++fmt; /* skip first '#' */
678 if (*fmt == '#') { /* Escaped ## */
679 if (outpos < outlen)
680 output[outpos] = '#';
681 outpos++;
682 break;
683 }
684 attributes = 0;
685 fmt = parse_trace_type(fmt, &trace_size, &trace_type,
686 &attributes);
687 break;
688 case '%':
689 /* c types (%) */
690 ++fmt; /* skip first '%' */
691 if (*fmt == '%') { /* Escaped %% */
692 if (outpos < outlen)
693 output[outpos] = '%';
694 outpos++;
695 break;
696 }
697 fmt = parse_c_type(fmt, &c_size, &c_type, outfmt + 1);
698 /*
699 * Output c types if no trace types has been
700 * specified.
701 */
702 if (!trace_size)
703 trace_size = c_size;
704 if (trace_type == LTT_TYPE_NONE)
705 trace_type = c_type;
706 if (c_type == LTT_TYPE_STRING)
707 trace_type = LTT_TYPE_STRING;
708
709 /* perform trace printf */
710 len = serialize_printf_data(buf, &msgpos, trace_size,
711 trace_type, c_size, c_type,
712 output + outpos,
713 outlen - outpos, outfmt);
714 outpos += len;
715 trace_size = 0;
716 c_size = 0;
717 trace_type = LTT_TYPE_NONE;
718 c_size = LTT_TYPE_NONE;
719 attributes = 0;
720 break;
721 default:
722 if (outpos < outlen)
723 output[outpos] = *fmt;
724 outpos++;
725 break;
726 }
727 }
728 if (msg_size)
729 *msg_size = (size_t)(msgpos - buf_offset);
730 /*
731 * Make sure we end output with terminating \0 when truncated.
732 */
733 if (outpos >= outlen + 1)
734 output[outlen] = '\0';
735 return outpos;
736}
737EXPORT_SYMBOL_GPL(ltt_serialize_printf);
738
739#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
740
741unsigned int ltt_fmt_largest_align(size_t align_drift, const char *fmt)
742{
743 char trace_size = 0, c_size = 0;
744 enum ltt_type trace_type = LTT_TYPE_NONE, c_type = LTT_TYPE_NONE;
745 unsigned long attributes = 0;
746 int largest_align = 1;
747
748 for (; *fmt ; ++fmt) {
749 switch (*fmt) {
750 case '#':
751 /* tracetypes (#) */
752 ++fmt; /* skip first '#' */
753 if (*fmt == '#') /* Escaped ## */
754 break;
755 attributes = 0;
756 fmt = parse_trace_type(fmt, &trace_size, &trace_type,
757 &attributes);
758
759 largest_align = max_t(int, largest_align, trace_size);
760 if (largest_align >= ltt_get_alignment())
761 goto exit;
762 break;
763 case '%':
764 /* c types (%) */
765 ++fmt; /* skip first '%' */
766 if (*fmt == '%') /* Escaped %% */
767 break;
768 fmt = parse_c_type(fmt, &c_size, &c_type, NULL);
769 /*
770 * Output c types if no trace types has been
771 * specified.
772 */
773 if (!trace_size)
774 trace_size = c_size;
775 if (trace_type == LTT_TYPE_NONE)
776 trace_type = c_type;
777 if (c_type == LTT_TYPE_STRING)
778 trace_type = LTT_TYPE_STRING;
779
780 largest_align = max_t(int, largest_align, trace_size);
781 if (largest_align >= ltt_get_alignment())
782 goto exit;
783
784 trace_size = 0;
785 c_size = 0;
786 trace_type = LTT_TYPE_NONE;
787 c_size = LTT_TYPE_NONE;
788 break;
789 }
790 }
791
792exit:
793 largest_align = min_t(int, largest_align, ltt_get_alignment());
794 return (largest_align - align_drift) & (largest_align - 1);
795}
796EXPORT_SYMBOL_GPL(ltt_fmt_largest_align);
797
798#endif
799
800/*
801 * Calculate data size
802 * Assume that the padding for alignment starts at a sizeof(void *) address.
803 */
804static notrace
805size_t ltt_get_data_size(struct ltt_serialize_closure *closure,
806 void *serialize_private, unsigned int stack_pos_ctx,
807 int *largest_align, const char *fmt, va_list *args)
808{
809 ltt_serialize_cb cb = closure->callbacks[0];
810 closure->cb_idx = 0;
811 return (size_t)cb(NULL, 0, closure, serialize_private, stack_pos_ctx,
812 largest_align, fmt, args);
813}
814
815static notrace
816void ltt_write_event_data(struct ltt_chanbuf *buf, size_t buf_offset,
817 struct ltt_serialize_closure *closure,
818 void *serialize_private, unsigned int stack_pos_ctx,
819 int largest_align, const char *fmt, va_list *args)
820{
821 ltt_serialize_cb cb = closure->callbacks[0];
822 closure->cb_idx = 0;
823 buf_offset += ltt_align(buf_offset, largest_align);
824 cb(buf, buf_offset, closure, serialize_private, stack_pos_ctx, NULL,
825 fmt, args);
826}
827
828
829notrace
830void ltt_vtrace(const struct marker *mdata, void *probe_data, void *call_data,
831 const char *fmt, va_list *args)
832{
833 int largest_align, ret;
834 struct ltt_active_marker *pdata;
835 uint16_t eID;
836 size_t data_size, slot_size;
837 unsigned int chan_index;
838 struct ltt_chanbuf *buf;
839 struct ltt_chan *chan;
840 struct ltt_trace *trace, *dest_trace = NULL;
841 uint64_t tsc;
842 long buf_offset;
843 va_list args_copy;
844 struct ltt_serialize_closure closure;
845 struct ltt_probe_private_data *private_data = call_data;
846 void *serialize_private = NULL;
847 int cpu;
848 unsigned int rflags;
849 unsigned int stack_pos_ctx;
850
851 /*
852 * This test is useful for quickly exiting static tracing when no trace
853 * is active. We expect to have an active trace when we get here.
854 */
855 if (unlikely(ltt_traces.num_active_traces == 0))
856 return;
857
858 rcu_read_lock_sched_notrace();
859 cpu = smp_processor_id();
860 __get_cpu_var(ltt_nesting)++;
861 stack_pos_ctx = __get_cpu_var(tracer_stack_pos);
862 /*
863 * asm volatile and "memory" clobber prevent the compiler from moving
864 * instructions out of the ltt nesting count. This is required to ensure
865 * that probe side-effects which can cause recursion (e.g. unforeseen
866 * traps, divisions by 0, ...) are triggered within the incremented
867 * nesting count section.
868 */
869 barrier();
870 pdata = (struct ltt_active_marker *)probe_data;
871 eID = mdata->event_id;
872 chan_index = mdata->channel_id;
873 closure.callbacks = pdata->probe->callbacks;
874
875 if (unlikely(private_data)) {
876 dest_trace = private_data->trace;
877 if (private_data->serializer)
878 closure.callbacks = &private_data->serializer;
879 serialize_private = private_data->serialize_private;
880 }
881
882 va_copy(args_copy, *args);
883 /*
884 * Assumes event payload to start on largest_align alignment.
885 */
886 largest_align = 1; /* must be non-zero for ltt_align */
887 data_size = ltt_get_data_size(&closure, serialize_private,
888 stack_pos_ctx, &largest_align,
889 fmt, &args_copy);
890 largest_align = min_t(int, largest_align, sizeof(void *));
891 va_end(args_copy);
892
893 /* Iterate on each trace */
894 list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
895 /*
896 * Expect the filter to filter out events. If we get here,
897 * we went through tracepoint activation as a first step.
898 */
899 if (unlikely(dest_trace && trace != dest_trace))
900 continue;
901 if (unlikely(!trace->active))
902 continue;
903 if (unlikely(!ltt_run_filter(trace, eID)))
904 continue;
2e6246b4 905#ifdef LTT_DEBUG_EVENT_SIZE
1c8284eb
MD
906 rflags = LTT_RFLAG_ID_SIZE;
907#else
908 if (unlikely(eID >= LTT_FREE_EVENTS))
909 rflags = LTT_RFLAG_ID;
910 else
911 rflags = 0;
912#endif
913 /*
914 * Skip channels added after trace creation.
915 */
916 if (unlikely(chan_index >= trace->nr_channels))
917 continue;
918 chan = &trace->channels[chan_index];
919 if (!chan->active)
920 continue;
921
922 /* reserve space : header and data */
923 ret = ltt_reserve_slot(chan, trace, data_size, largest_align,
924 cpu, &buf, &slot_size, &buf_offset,
925 &tsc, &rflags);
926 if (unlikely(ret < 0))
927 continue; /* buffer full */
928
929 va_copy(args_copy, *args);
930 /* Out-of-order write : header and data */
931 buf_offset = ltt_write_event_header(&buf->a, &chan->a,
932 buf_offset, eID, data_size,
933 tsc, rflags);
934 ltt_write_event_data(buf, buf_offset, &closure,
935 serialize_private, stack_pos_ctx,
936 largest_align, fmt, &args_copy);
937 va_end(args_copy);
938 /* Out-of-order commit */
939 ltt_commit_slot(buf, chan, buf_offset, data_size, slot_size);
940 }
941 /*
942 * asm volatile and "memory" clobber prevent the compiler from moving
943 * instructions out of the ltt nesting count. This is required to ensure
944 * that probe side-effects which can cause recursion (e.g. unforeseen
945 * traps, divisions by 0, ...) are triggered within the incremented
946 * nesting count section.
947 */
948 barrier();
949 __get_cpu_var(tracer_stack_pos) = stack_pos_ctx;
950 __get_cpu_var(ltt_nesting)--;
951 rcu_read_unlock_sched_notrace();
952}
953EXPORT_SYMBOL_GPL(ltt_vtrace);
954
955notrace
956void ltt_trace(const struct marker *mdata, void *probe_data, void *call_data,
957 const char *fmt, ...)
958{
959 va_list args;
960
961 va_start(args, fmt);
962 ltt_vtrace(mdata, probe_data, call_data, fmt, &args);
963 va_end(args);
964}
965EXPORT_SYMBOL_GPL(ltt_trace);
966
967MODULE_LICENSE("GPL and additional rights");
968MODULE_AUTHOR("Mathieu Desnoyers");
969MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Serializer");
This page took 0.057352 seconds and 4 git commands to generate.