1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2020 Marvell International Ltd.
8 #include <rte_byteorder.h>
9 #include <rte_common.h>
11 #include <rte_trace.h>
12 #include <rte_version.h>
14 #include "eal_trace.h"
16 __rte_format_printf(2, 0)
18 metadata_printf(char **str, const char *fmt, ...)
25 rc = vasprintf(str, fmt, ap);
32 meta_copy(char **meta, int *offset, char *str, int rc)
40 ptr = realloc(ptr, count + rc + 1);
44 memcpy(RTE_PTR_ADD(ptr, count), str, rc);
45 ptr[count + rc] = '\0';
61 meta_data_type_emit(char **meta, int *offset)
66 rc = metadata_printf(&str,
68 "typealias integer {size = 8; base = x;}:= uint8_t;\n"
69 "typealias integer {size = 16; base = x;} := uint16_t;\n"
70 "typealias integer {size = 32; base = x;} := uint32_t;\n"
71 "typealias integer {size = 64; base = x;} := uint64_t;\n"
72 "typealias integer {size = 8; signed = true;} := int8_t;\n"
73 "typealias integer {size = 16; signed = true;} := int16_t;\n"
74 "typealias integer {size = 32; signed = true;} := int32_t;\n"
75 "typealias integer {size = 64; signed = true;} := int64_t;\n"
77 "typealias integer {size = 64; base = x;} := uintptr_t;\n"
79 "typealias integer {size = 32; base = x;} := uintptr_t;\n"
82 "typealias integer {size = 64; base = x;} := long;\n"
84 "typealias integer {size = 32; base = x;} := long;\n"
86 "typealias integer {size = 8; signed = false; encoding = ASCII; } := string_bounded_t;\n\n"
88 "typealias integer {size = 64; base = x;} := size_t;\n"
90 "typealias integer {size = 32; base = x;} := size_t;\n"
92 "typealias floating_point {\n"
96 "typealias floating_point {\n"
101 return meta_copy(meta, offset, str, rc);
107 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
115 meta_header_emit(char **meta, int *offset)
117 struct trace *trace = trace_obj_get();
118 char uustr[RTE_UUID_STRLEN];
122 rte_uuid_unparse(trace->uuid, uustr, RTE_UUID_STRLEN);
123 rc = metadata_printf(&str,
128 " byte_order = %s;\n"
129 " packet.header := struct {\n"
131 " uint8_t uuid[16];\n"
133 "};\n\n", uustr, is_be() ? "be" : "le");
134 return meta_copy(meta, offset, str, rc);
138 meta_env_emit(char **meta, int *offset)
143 rc = metadata_printf(&str,
145 " dpdk_version = \"%s\";\n"
146 " tracer_name = \"dpdk\";\n"
147 "};\n\n", rte_version());
148 return meta_copy(meta, offset, str, rc);
152 meta_clock_pass1_emit(char **meta, int *offset)
157 rc = metadata_printf(&str,
159 " name = \"dpdk\";\n"
161 return meta_copy(meta, offset, str, rc);
165 meta_clock_pass2_emit(char **meta, int *offset)
170 rc = metadata_printf(&str,
173 return meta_copy(meta, offset, str, rc);
177 meta_clock_pass3_emit(char **meta, int *offset)
182 rc = metadata_printf(&str,
185 return meta_copy(meta, offset, str, rc);
189 meta_clock_pass4_emit(char **meta, int *offset)
194 rc = metadata_printf(&str,
195 "%20"PRIu64";\n};\n\n"
196 "typealias integer {\n"
197 " size = 48; align = 1; signed = false;\n"
198 " map = clock.dpdk.value;\n"
199 "} := uint48_clock_dpdk_t;\n\n", 0);
201 return meta_copy(meta, offset, str, rc);
205 meta_stream_emit(char **meta, int *offset)
210 rc = metadata_printf(&str,
212 " packet.context := struct {\n"
213 " uint32_t cpu_id;\n"
214 " string_bounded_t name[32];\n"
216 " event.header := struct {\n"
217 " uint48_clock_dpdk_t timestamp;\n"
221 return meta_copy(meta, offset, str, rc);
225 meta_event_emit(char **meta, int *offset, struct trace_point *tp)
230 rc = metadata_printf(&str,
234 " fields := struct {\n"
237 "};\n\n", trace_id_get(tp->handle), tp->name,
238 tp->ctf_field != NULL ? tp->ctf_field : "");
239 return meta_copy(meta, offset, str, rc);
243 trace_metadata_create(void)
245 struct trace_point_head *tp_list = trace_list_head_get();
246 struct trace *trace = trace_obj_get();
247 struct trace_point *tp;
251 rc = meta_data_type_emit(&meta, &offset);
255 rc = meta_header_emit(&meta, &offset);
259 rc = meta_env_emit(&meta, &offset);
263 rc = meta_clock_pass1_emit(&meta, &offset);
266 trace->ctf_meta_offset_freq = offset;
268 rc = meta_clock_pass2_emit(&meta, &offset);
271 trace->ctf_meta_offset_freq_off_s = offset;
273 rc = meta_clock_pass3_emit(&meta, &offset);
276 trace->ctf_meta_offset_freq_off = offset;
278 rc = meta_clock_pass4_emit(&meta, &offset);
282 rc = meta_stream_emit(&meta, &offset);
286 STAILQ_FOREACH(tp, tp_list, next)
287 if (meta_event_emit(&meta, &offset, tp) < 0)
290 trace->ctf_meta = meta;
300 trace_metadata_destroy(void)
302 struct trace *trace = trace_obj_get();
304 if (trace->ctf_meta) {
305 free(trace->ctf_meta);
306 trace->ctf_meta = NULL;
311 meta_fix_freq(struct trace *trace, char *meta)
316 str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq);
317 rc = sprintf(str, "%20"PRIu64"", rte_get_timer_hz());
322 meta_fix_freq_offset(struct trace *trace, char *meta)
324 uint64_t uptime_tickes_floor, uptime_ticks, freq, uptime_sec;
325 uint64_t offset, offset_s;
329 uptime_ticks = trace->uptime_ticks &
330 ((1ULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT) - 1);
331 freq = rte_get_tsc_hz();
332 uptime_tickes_floor = RTE_ALIGN_MUL_FLOOR(uptime_ticks, freq);
334 uptime_sec = uptime_tickes_floor / freq;
335 offset_s = trace->epoch_sec - uptime_sec;
337 offset = uptime_ticks - uptime_tickes_floor;
338 offset += trace->epoch_nsec * (freq / NSEC_PER_SEC);
340 str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off_s);
341 rc = sprintf(str, "%20"PRIu64"", offset_s);
343 str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off);
344 rc = sprintf(str, "%20"PRIu64"", offset);
349 meta_fixup(struct trace *trace, char *meta)
351 meta_fix_freq(trace, meta);
352 meta_fix_freq_offset(trace, meta);
356 rte_trace_metadata_dump(FILE *f)
358 struct trace *trace = trace_obj_get();
359 char *ctf_meta = trace->ctf_meta;
362 if (!rte_trace_is_enabled())
365 if (ctf_meta == NULL)
368 if (!__atomic_load_n(&trace->ctf_fixup_done, __ATOMIC_SEQ_CST) &&
369 rte_get_timer_hz()) {
370 meta_fixup(trace, ctf_meta);
371 __atomic_store_n(&trace->ctf_fixup_done, 1, __ATOMIC_SEQ_CST);
374 rc = fprintf(f, "%s", ctf_meta);
375 return rc < 0 ? rc : 0;
378 char *trace_metadata_fixup_field(const char *field)
380 const char *ctf_reserved_words[] = {
388 /* reserved keywords */
389 for (i = 0; i < RTE_DIM(ctf_reserved_words); i++) {
390 if (strcmp(field, ctf_reserved_words[i]) != 0)
392 if (asprintf(&out, "_%s", ctf_reserved_words[i]) == -1)
397 /* nothing to replace, return early */
398 if (strstr(field, ".") == NULL && strstr(field, "->") == NULL)
405 while ((p = strstr(p, ".")) != NULL) {
410 while ((p = strstr(p, "->")) != NULL) {
413 memmove(p, p + 1, strlen(p));