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);
44 memcpy(RTE_PTR_ADD(ptr, count), str, rc);
60 meta_data_type_emit(char **meta, int *offset)
65 rc = metadata_printf(&str,
67 "typealias integer {size = 8; base = x;}:= uint8_t;\n"
68 "typealias integer {size = 16; base = x;} := uint16_t;\n"
69 "typealias integer {size = 32; base = x;} := uint32_t;\n"
70 "typealias integer {size = 64; base = x;} := uint64_t;\n"
71 "typealias integer {size = 8; signed = true;} := int8_t;\n"
72 "typealias integer {size = 16; signed = true;} := int16_t;\n"
73 "typealias integer {size = 32; signed = true;} := int32_t;\n"
74 "typealias integer {size = 64; signed = true;} := int64_t;\n"
76 "typealias integer {size = 64; base = x;} := uintptr_t;\n"
78 "typealias integer {size = 32; base = x;} := uintptr_t;\n"
81 "typealias integer {size = 64; base = x;} := long;\n"
83 "typealias integer {size = 32; base = x;} := long;\n"
85 "typealias integer {size = 8; signed = false; encoding = ASCII; } := string_bounded_t;\n\n"
86 "typealias floating_point {\n"
90 "typealias floating_point {\n"
95 return meta_copy(meta, offset, str, rc);
101 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
109 meta_header_emit(char **meta, int *offset)
111 struct trace *trace = trace_obj_get();
112 char uustr[RTE_UUID_STRLEN];
116 rte_uuid_unparse(trace->uuid, uustr, RTE_UUID_STRLEN);
117 rc = metadata_printf(&str,
122 " byte_order = %s;\n"
123 " packet.header := struct {\n"
125 " uint8_t uuid[16];\n"
127 "};\n\n", uustr, is_be() ? "be" : "le");
128 return meta_copy(meta, offset, str, rc);
132 meta_env_emit(char **meta, int *offset)
137 rc = metadata_printf(&str,
139 " dpdk_version = \"%s\";\n"
140 " tracer_name = \"dpdk\";\n"
141 "};\n\n", rte_version());
142 return meta_copy(meta, offset, str, rc);
146 meta_clock_pass1_emit(char **meta, int *offset)
151 rc = metadata_printf(&str,
153 " name = \"dpdk\";\n"
155 return meta_copy(meta, offset, str, rc);
159 meta_clock_pass2_emit(char **meta, int *offset)
164 rc = metadata_printf(&str,
167 return meta_copy(meta, offset, str, rc);
171 meta_clock_pass3_emit(char **meta, int *offset)
176 rc = metadata_printf(&str,
179 return meta_copy(meta, offset, str, rc);
183 meta_clock_pass4_emit(char **meta, int *offset)
188 rc = metadata_printf(&str,
189 "%20"PRIu64";\n};\n\n"
190 "typealias integer {\n"
191 " size = 48; align = 1; signed = false;\n"
192 " map = clock.dpdk.value;\n"
193 "} := uint48_clock_dpdk_t;\n\n", 0);
195 return meta_copy(meta, offset, str, rc);
199 meta_stream_emit(char **meta, int *offset)
204 rc = metadata_printf(&str,
206 " packet.context := struct {\n"
207 " uint32_t cpu_id;\n"
208 " string_bounded_t name[32];\n"
210 " event.header := struct {\n"
211 " uint48_clock_dpdk_t timestamp;\n"
215 return meta_copy(meta, offset, str, rc);
219 string_fixed_replace(char *input, const char *search, const char *replace)
224 found = strstr(input, search);
228 if (strlen(found) != strlen(search))
231 len = strlen(replace);
232 memcpy(found, replace, len);
237 ctf_fixup_align(char *str)
239 string_fixed_replace(str, "align", "_align");
243 ctf_fixup_arrow_deref(char *str)
245 const char *replace = "_";
246 const char *search = "->";
250 found = strstr(str, search);
255 memcpy(found, replace, strlen(replace));
256 len = strlen(found + 2);
257 memcpy(found + 1, found + 2, len);
258 found[len + 1] = '\0';
259 found = strstr(str, search);
260 } while (found != NULL);
264 ctf_fixup_dot_deref(char *str)
266 const char *replace = "_";
267 const char *search = ".";
271 found = strstr(str, search);
275 len = strlen(replace);
277 memcpy(found, replace, len);
278 found = strstr(str, search);
279 } while (found != NULL);
283 ctf_fixup_event(char *str)
285 string_fixed_replace(str, "event", "_event");
289 ctf_fixup_keyword(char *str)
291 char dup_str[TRACE_CTF_FIELD_SIZE];
292 char input[TRACE_CTF_FIELD_SIZE];
293 const char *delim = ";";
301 if (len >= TRACE_CTF_FIELD_SIZE) {
302 trace_err("ctf_field reached its maximum limit");
306 /* Create duplicate string */
307 strcpy(dup_str, str);
310 from = strtok(dup_str, delim);
311 while (from != NULL) {
313 ctf_fixup_align(input);
314 ctf_fixup_dot_deref(input);
315 ctf_fixup_arrow_deref(input);
316 ctf_fixup_event(input);
318 strcpy(&input[strlen(input)], delim);
319 if ((len + strlen(input)) >= TRACE_CTF_FIELD_SIZE) {
320 trace_err("ctf_field reached its maximum limit");
324 strcpy(str + len, input);
325 len += strlen(input);
326 from = strtok(NULL, delim);
333 meta_event_emit(char **meta, int *offset, struct trace_point *tp)
338 /* Fixup ctf field string in case it using reserved ctf keywords */
339 rc = ctf_fixup_keyword(tp->ctf_field);
343 rc = metadata_printf(&str,
347 " fields := struct {\n"
350 "};\n\n", trace_id_get(tp->handle), tp->name, tp->ctf_field);
351 return meta_copy(meta, offset, str, rc);
355 trace_metadata_create(void)
357 struct trace_point_head *tp_list = trace_list_head_get();
358 struct trace *trace = trace_obj_get();
359 struct trace_point *tp;
363 rc = meta_data_type_emit(&meta, &offset);
367 rc = meta_header_emit(&meta, &offset);
371 rc = meta_env_emit(&meta, &offset);
375 rc = meta_clock_pass1_emit(&meta, &offset);
378 trace->ctf_meta_offset_freq = offset;
380 rc = meta_clock_pass2_emit(&meta, &offset);
383 trace->ctf_meta_offset_freq_off_s = offset;
385 rc = meta_clock_pass3_emit(&meta, &offset);
388 trace->ctf_meta_offset_freq_off = offset;
390 rc = meta_clock_pass4_emit(&meta, &offset);
394 rc = meta_stream_emit(&meta, &offset);
398 STAILQ_FOREACH(tp, tp_list, next)
399 if (meta_event_emit(&meta, &offset, tp) < 0)
402 trace->ctf_meta = meta;
412 trace_metadata_destroy(void)
414 struct trace *trace = trace_obj_get();
416 if (trace->ctf_meta) {
417 free(trace->ctf_meta);
418 trace->ctf_meta = NULL;
423 meta_fix_freq(struct trace *trace, char *meta)
428 str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq);
429 rc = sprintf(str, "%20"PRIu64"", rte_get_timer_hz());
434 meta_fix_freq_offset(struct trace *trace, char *meta)
436 uint64_t uptime_tickes_floor, uptime_ticks, freq, uptime_sec;
437 uint64_t offset, offset_s;
441 uptime_ticks = trace->uptime_ticks &
442 ((1ULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT) - 1);
443 freq = rte_get_tsc_hz();
444 uptime_tickes_floor = RTE_ALIGN_MUL_FLOOR(uptime_ticks, freq);
446 uptime_sec = uptime_tickes_floor / freq;
447 offset_s = trace->epoch_sec - uptime_sec;
449 offset = uptime_ticks - uptime_tickes_floor;
450 offset += trace->epoch_nsec * (freq / NSEC_PER_SEC);
452 str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off_s);
453 rc = sprintf(str, "%20"PRIu64"", offset_s);
455 str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off);
456 rc = sprintf(str, "%20"PRIu64"", offset);
461 meta_fixup(struct trace *trace, char *meta)
463 meta_fix_freq(trace, meta);
464 meta_fix_freq_offset(trace, meta);
468 rte_trace_metadata_dump(FILE *f)
470 struct trace *trace = trace_obj_get();
471 char *ctf_meta = trace->ctf_meta;
474 if (!rte_trace_is_enabled())
477 if (ctf_meta == NULL)
480 if (!__atomic_load_n(&trace->ctf_fixup_done, __ATOMIC_SEQ_CST) &&
481 rte_get_timer_hz()) {
482 meta_fixup(trace, ctf_meta);
483 __atomic_store_n(&trace->ctf_fixup_done, 1, __ATOMIC_SEQ_CST);
486 rc = fprintf(f, "%s", ctf_meta);
487 return rc < 0 ? rc : 0;