data-convert-bt.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. /*
  2. * CTF writing support via babeltrace.
  3. *
  4. * Copyright (C) 2014, Jiri Olsa <jolsa@redhat.com>
  5. * Copyright (C) 2014, Sebastian Andrzej Siewior <bigeasy@linutronix.de>
  6. *
  7. * Released under the GPL v2. (and only v2, not any later version)
  8. */
  9. #include <linux/compiler.h>
  10. #include <babeltrace/ctf-writer/writer.h>
  11. #include <babeltrace/ctf-writer/clock.h>
  12. #include <babeltrace/ctf-writer/stream.h>
  13. #include <babeltrace/ctf-writer/event.h>
  14. #include <babeltrace/ctf-writer/event-types.h>
  15. #include <babeltrace/ctf-writer/event-fields.h>
  16. #include <babeltrace/ctf-ir/utils.h>
  17. #include <babeltrace/ctf/events.h>
  18. #include <traceevent/event-parse.h>
  19. #include "asm/bug.h"
  20. #include "data-convert-bt.h"
  21. #include "session.h"
  22. #include "util.h"
  23. #include "debug.h"
  24. #include "tool.h"
  25. #include "evlist.h"
  26. #include "evsel.h"
  27. #include "machine.h"
  28. #define pr_N(n, fmt, ...) \
  29. eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__)
  30. #define pr(fmt, ...) pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
  31. #define pr2(fmt, ...) pr_N(2, pr_fmt(fmt), ##__VA_ARGS__)
  32. #define pr_time2(t, fmt, ...) pr_time_N(2, debug_data_convert, t, pr_fmt(fmt), ##__VA_ARGS__)
  33. struct evsel_priv {
  34. struct bt_ctf_event_class *event_class;
  35. };
  36. #define MAX_CPUS 4096
  37. struct ctf_stream {
  38. struct bt_ctf_stream *stream;
  39. int cpu;
  40. u32 count;
  41. };
  42. struct ctf_writer {
  43. /* writer primitives */
  44. struct bt_ctf_writer *writer;
  45. struct ctf_stream **stream;
  46. int stream_cnt;
  47. struct bt_ctf_stream_class *stream_class;
  48. struct bt_ctf_clock *clock;
  49. /* data types */
  50. union {
  51. struct {
  52. struct bt_ctf_field_type *s64;
  53. struct bt_ctf_field_type *u64;
  54. struct bt_ctf_field_type *s32;
  55. struct bt_ctf_field_type *u32;
  56. struct bt_ctf_field_type *string;
  57. struct bt_ctf_field_type *u32_hex;
  58. struct bt_ctf_field_type *u64_hex;
  59. };
  60. struct bt_ctf_field_type *array[6];
  61. } data;
  62. };
  63. struct convert {
  64. struct perf_tool tool;
  65. struct ctf_writer writer;
  66. u64 events_size;
  67. u64 events_count;
  68. /* Ordered events configured queue size. */
  69. u64 queue_size;
  70. };
  71. static int value_set(struct bt_ctf_field_type *type,
  72. struct bt_ctf_event *event,
  73. const char *name, u64 val)
  74. {
  75. struct bt_ctf_field *field;
  76. bool sign = bt_ctf_field_type_integer_get_signed(type);
  77. int ret;
  78. field = bt_ctf_field_create(type);
  79. if (!field) {
  80. pr_err("failed to create a field %s\n", name);
  81. return -1;
  82. }
  83. if (sign) {
  84. ret = bt_ctf_field_signed_integer_set_value(field, val);
  85. if (ret) {
  86. pr_err("failed to set field value %s\n", name);
  87. goto err;
  88. }
  89. } else {
  90. ret = bt_ctf_field_unsigned_integer_set_value(field, val);
  91. if (ret) {
  92. pr_err("failed to set field value %s\n", name);
  93. goto err;
  94. }
  95. }
  96. ret = bt_ctf_event_set_payload(event, name, field);
  97. if (ret) {
  98. pr_err("failed to set payload %s\n", name);
  99. goto err;
  100. }
  101. pr2(" SET [%s = %" PRIu64 "]\n", name, val);
  102. err:
  103. bt_ctf_field_put(field);
  104. return ret;
  105. }
  106. #define __FUNC_VALUE_SET(_name, _val_type) \
  107. static __maybe_unused int value_set_##_name(struct ctf_writer *cw, \
  108. struct bt_ctf_event *event, \
  109. const char *name, \
  110. _val_type val) \
  111. { \
  112. struct bt_ctf_field_type *type = cw->data._name; \
  113. return value_set(type, event, name, (u64) val); \
  114. }
  115. #define FUNC_VALUE_SET(_name) __FUNC_VALUE_SET(_name, _name)
  116. FUNC_VALUE_SET(s32)
  117. FUNC_VALUE_SET(u32)
  118. FUNC_VALUE_SET(s64)
  119. FUNC_VALUE_SET(u64)
  120. __FUNC_VALUE_SET(u64_hex, u64)
  121. static struct bt_ctf_field_type*
  122. get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
  123. {
  124. unsigned long flags = field->flags;
  125. if (flags & FIELD_IS_STRING)
  126. return cw->data.string;
  127. if (!(flags & FIELD_IS_SIGNED)) {
  128. /* unsigned long are mostly pointers */
  129. if (flags & FIELD_IS_LONG || flags & FIELD_IS_POINTER)
  130. return cw->data.u64_hex;
  131. }
  132. if (flags & FIELD_IS_SIGNED) {
  133. if (field->size == 8)
  134. return cw->data.s64;
  135. else
  136. return cw->data.s32;
  137. }
  138. if (field->size == 8)
  139. return cw->data.u64;
  140. else
  141. return cw->data.u32;
  142. }
  143. static unsigned long long adjust_signedness(unsigned long long value_int, int size)
  144. {
  145. unsigned long long value_mask;
  146. /*
  147. * value_mask = (1 << (size * 8 - 1)) - 1.
  148. * Directly set value_mask for code readers.
  149. */
  150. switch (size) {
  151. case 1:
  152. value_mask = 0x7fULL;
  153. break;
  154. case 2:
  155. value_mask = 0x7fffULL;
  156. break;
  157. case 4:
  158. value_mask = 0x7fffffffULL;
  159. break;
  160. case 8:
  161. /*
  162. * For 64 bit value, return it self. There is no need
  163. * to fill high bit.
  164. */
  165. /* Fall through */
  166. default:
  167. /* BUG! */
  168. return value_int;
  169. }
  170. /* If it is a positive value, don't adjust. */
  171. if ((value_int & (~0ULL - value_mask)) == 0)
  172. return value_int;
  173. /* Fill upper part of value_int with 1 to make it a negative long long. */
  174. return (value_int & value_mask) | ~value_mask;
  175. }
  176. static int add_tracepoint_field_value(struct ctf_writer *cw,
  177. struct bt_ctf_event_class *event_class,
  178. struct bt_ctf_event *event,
  179. struct perf_sample *sample,
  180. struct format_field *fmtf)
  181. {
  182. struct bt_ctf_field_type *type;
  183. struct bt_ctf_field *array_field;
  184. struct bt_ctf_field *field;
  185. const char *name = fmtf->name;
  186. void *data = sample->raw_data;
  187. unsigned long flags = fmtf->flags;
  188. unsigned int n_items;
  189. unsigned int i;
  190. unsigned int offset;
  191. unsigned int len;
  192. int ret;
  193. name = fmtf->alias;
  194. offset = fmtf->offset;
  195. len = fmtf->size;
  196. if (flags & FIELD_IS_STRING)
  197. flags &= ~FIELD_IS_ARRAY;
  198. if (flags & FIELD_IS_DYNAMIC) {
  199. unsigned long long tmp_val;
  200. tmp_val = pevent_read_number(fmtf->event->pevent,
  201. data + offset, len);
  202. offset = tmp_val;
  203. len = offset >> 16;
  204. offset &= 0xffff;
  205. }
  206. if (flags & FIELD_IS_ARRAY) {
  207. type = bt_ctf_event_class_get_field_by_name(
  208. event_class, name);
  209. array_field = bt_ctf_field_create(type);
  210. bt_ctf_field_type_put(type);
  211. if (!array_field) {
  212. pr_err("Failed to create array type %s\n", name);
  213. return -1;
  214. }
  215. len = fmtf->size / fmtf->arraylen;
  216. n_items = fmtf->arraylen;
  217. } else {
  218. n_items = 1;
  219. array_field = NULL;
  220. }
  221. type = get_tracepoint_field_type(cw, fmtf);
  222. for (i = 0; i < n_items; i++) {
  223. if (flags & FIELD_IS_ARRAY)
  224. field = bt_ctf_field_array_get_field(array_field, i);
  225. else
  226. field = bt_ctf_field_create(type);
  227. if (!field) {
  228. pr_err("failed to create a field %s\n", name);
  229. return -1;
  230. }
  231. if (flags & FIELD_IS_STRING)
  232. ret = bt_ctf_field_string_set_value(field,
  233. data + offset + i * len);
  234. else {
  235. unsigned long long value_int;
  236. value_int = pevent_read_number(
  237. fmtf->event->pevent,
  238. data + offset + i * len, len);
  239. if (!(flags & FIELD_IS_SIGNED))
  240. ret = bt_ctf_field_unsigned_integer_set_value(
  241. field, value_int);
  242. else
  243. ret = bt_ctf_field_signed_integer_set_value(
  244. field, adjust_signedness(value_int, len));
  245. }
  246. if (ret) {
  247. pr_err("failed to set file value %s\n", name);
  248. goto err_put_field;
  249. }
  250. if (!(flags & FIELD_IS_ARRAY)) {
  251. ret = bt_ctf_event_set_payload(event, name, field);
  252. if (ret) {
  253. pr_err("failed to set payload %s\n", name);
  254. goto err_put_field;
  255. }
  256. }
  257. bt_ctf_field_put(field);
  258. }
  259. if (flags & FIELD_IS_ARRAY) {
  260. ret = bt_ctf_event_set_payload(event, name, array_field);
  261. if (ret) {
  262. pr_err("Failed add payload array %s\n", name);
  263. return -1;
  264. }
  265. bt_ctf_field_put(array_field);
  266. }
  267. return 0;
  268. err_put_field:
  269. bt_ctf_field_put(field);
  270. return -1;
  271. }
  272. static int add_tracepoint_fields_values(struct ctf_writer *cw,
  273. struct bt_ctf_event_class *event_class,
  274. struct bt_ctf_event *event,
  275. struct format_field *fields,
  276. struct perf_sample *sample)
  277. {
  278. struct format_field *field;
  279. int ret;
  280. for (field = fields; field; field = field->next) {
  281. ret = add_tracepoint_field_value(cw, event_class, event, sample,
  282. field);
  283. if (ret)
  284. return -1;
  285. }
  286. return 0;
  287. }
  288. static int add_tracepoint_values(struct ctf_writer *cw,
  289. struct bt_ctf_event_class *event_class,
  290. struct bt_ctf_event *event,
  291. struct perf_evsel *evsel,
  292. struct perf_sample *sample)
  293. {
  294. struct format_field *common_fields = evsel->tp_format->format.common_fields;
  295. struct format_field *fields = evsel->tp_format->format.fields;
  296. int ret;
  297. ret = add_tracepoint_fields_values(cw, event_class, event,
  298. common_fields, sample);
  299. if (!ret)
  300. ret = add_tracepoint_fields_values(cw, event_class, event,
  301. fields, sample);
  302. return ret;
  303. }
  304. static int add_generic_values(struct ctf_writer *cw,
  305. struct bt_ctf_event *event,
  306. struct perf_evsel *evsel,
  307. struct perf_sample *sample)
  308. {
  309. u64 type = evsel->attr.sample_type;
  310. int ret;
  311. /*
  312. * missing:
  313. * PERF_SAMPLE_TIME - not needed as we have it in
  314. * ctf event header
  315. * PERF_SAMPLE_READ - TODO
  316. * PERF_SAMPLE_CALLCHAIN - TODO
  317. * PERF_SAMPLE_RAW - tracepoint fields are handled separately
  318. * PERF_SAMPLE_BRANCH_STACK - TODO
  319. * PERF_SAMPLE_REGS_USER - TODO
  320. * PERF_SAMPLE_STACK_USER - TODO
  321. */
  322. if (type & PERF_SAMPLE_IP) {
  323. ret = value_set_u64_hex(cw, event, "perf_ip", sample->ip);
  324. if (ret)
  325. return -1;
  326. }
  327. if (type & PERF_SAMPLE_TID) {
  328. ret = value_set_s32(cw, event, "perf_tid", sample->tid);
  329. if (ret)
  330. return -1;
  331. ret = value_set_s32(cw, event, "perf_pid", sample->pid);
  332. if (ret)
  333. return -1;
  334. }
  335. if ((type & PERF_SAMPLE_ID) ||
  336. (type & PERF_SAMPLE_IDENTIFIER)) {
  337. ret = value_set_u64(cw, event, "perf_id", sample->id);
  338. if (ret)
  339. return -1;
  340. }
  341. if (type & PERF_SAMPLE_STREAM_ID) {
  342. ret = value_set_u64(cw, event, "perf_stream_id", sample->stream_id);
  343. if (ret)
  344. return -1;
  345. }
  346. if (type & PERF_SAMPLE_PERIOD) {
  347. ret = value_set_u64(cw, event, "perf_period", sample->period);
  348. if (ret)
  349. return -1;
  350. }
  351. if (type & PERF_SAMPLE_WEIGHT) {
  352. ret = value_set_u64(cw, event, "perf_weight", sample->weight);
  353. if (ret)
  354. return -1;
  355. }
  356. if (type & PERF_SAMPLE_DATA_SRC) {
  357. ret = value_set_u64(cw, event, "perf_data_src",
  358. sample->data_src);
  359. if (ret)
  360. return -1;
  361. }
  362. if (type & PERF_SAMPLE_TRANSACTION) {
  363. ret = value_set_u64(cw, event, "perf_transaction",
  364. sample->transaction);
  365. if (ret)
  366. return -1;
  367. }
  368. return 0;
  369. }
  370. static int ctf_stream__flush(struct ctf_stream *cs)
  371. {
  372. int err = 0;
  373. if (cs) {
  374. err = bt_ctf_stream_flush(cs->stream);
  375. if (err)
  376. pr_err("CTF stream %d flush failed\n", cs->cpu);
  377. pr("Flush stream for cpu %d (%u samples)\n",
  378. cs->cpu, cs->count);
  379. cs->count = 0;
  380. }
  381. return err;
  382. }
  383. static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
  384. {
  385. struct ctf_stream *cs;
  386. struct bt_ctf_field *pkt_ctx = NULL;
  387. struct bt_ctf_field *cpu_field = NULL;
  388. struct bt_ctf_stream *stream = NULL;
  389. int ret;
  390. cs = zalloc(sizeof(*cs));
  391. if (!cs) {
  392. pr_err("Failed to allocate ctf stream\n");
  393. return NULL;
  394. }
  395. stream = bt_ctf_writer_create_stream(cw->writer, cw->stream_class);
  396. if (!stream) {
  397. pr_err("Failed to create CTF stream\n");
  398. goto out;
  399. }
  400. pkt_ctx = bt_ctf_stream_get_packet_context(stream);
  401. if (!pkt_ctx) {
  402. pr_err("Failed to obtain packet context\n");
  403. goto out;
  404. }
  405. cpu_field = bt_ctf_field_structure_get_field(pkt_ctx, "cpu_id");
  406. bt_ctf_field_put(pkt_ctx);
  407. if (!cpu_field) {
  408. pr_err("Failed to obtain cpu field\n");
  409. goto out;
  410. }
  411. ret = bt_ctf_field_unsigned_integer_set_value(cpu_field, (u32) cpu);
  412. if (ret) {
  413. pr_err("Failed to update CPU number\n");
  414. goto out;
  415. }
  416. bt_ctf_field_put(cpu_field);
  417. cs->cpu = cpu;
  418. cs->stream = stream;
  419. return cs;
  420. out:
  421. if (cpu_field)
  422. bt_ctf_field_put(cpu_field);
  423. if (stream)
  424. bt_ctf_stream_put(stream);
  425. free(cs);
  426. return NULL;
  427. }
  428. static void ctf_stream__delete(struct ctf_stream *cs)
  429. {
  430. if (cs) {
  431. bt_ctf_stream_put(cs->stream);
  432. free(cs);
  433. }
  434. }
  435. static struct ctf_stream *ctf_stream(struct ctf_writer *cw, int cpu)
  436. {
  437. struct ctf_stream *cs = cw->stream[cpu];
  438. if (!cs) {
  439. cs = ctf_stream__create(cw, cpu);
  440. cw->stream[cpu] = cs;
  441. }
  442. return cs;
  443. }
  444. static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample,
  445. struct perf_evsel *evsel)
  446. {
  447. int cpu = 0;
  448. if (evsel->attr.sample_type & PERF_SAMPLE_CPU)
  449. cpu = sample->cpu;
  450. if (cpu > cw->stream_cnt) {
  451. pr_err("Event was recorded for CPU %d, limit is at %d.\n",
  452. cpu, cw->stream_cnt);
  453. cpu = 0;
  454. }
  455. return cpu;
  456. }
  457. #define STREAM_FLUSH_COUNT 100000
  458. /*
  459. * Currently we have no other way to determine the
  460. * time for the stream flush other than keep track
  461. * of the number of events and check it against
  462. * threshold.
  463. */
  464. static bool is_flush_needed(struct ctf_stream *cs)
  465. {
  466. return cs->count >= STREAM_FLUSH_COUNT;
  467. }
  468. static int process_sample_event(struct perf_tool *tool,
  469. union perf_event *_event __maybe_unused,
  470. struct perf_sample *sample,
  471. struct perf_evsel *evsel,
  472. struct machine *machine __maybe_unused)
  473. {
  474. struct convert *c = container_of(tool, struct convert, tool);
  475. struct evsel_priv *priv = evsel->priv;
  476. struct ctf_writer *cw = &c->writer;
  477. struct ctf_stream *cs;
  478. struct bt_ctf_event_class *event_class;
  479. struct bt_ctf_event *event;
  480. int ret;
  481. if (WARN_ONCE(!priv, "Failed to setup all events.\n"))
  482. return 0;
  483. event_class = priv->event_class;
  484. /* update stats */
  485. c->events_count++;
  486. c->events_size += _event->header.size;
  487. pr_time2(sample->time, "sample %" PRIu64 "\n", c->events_count);
  488. event = bt_ctf_event_create(event_class);
  489. if (!event) {
  490. pr_err("Failed to create an CTF event\n");
  491. return -1;
  492. }
  493. bt_ctf_clock_set_time(cw->clock, sample->time);
  494. ret = add_generic_values(cw, event, evsel, sample);
  495. if (ret)
  496. return -1;
  497. if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
  498. ret = add_tracepoint_values(cw, event_class, event,
  499. evsel, sample);
  500. if (ret)
  501. return -1;
  502. }
  503. cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel));
  504. if (cs) {
  505. if (is_flush_needed(cs))
  506. ctf_stream__flush(cs);
  507. cs->count++;
  508. bt_ctf_stream_append_event(cs->stream, event);
  509. }
  510. bt_ctf_event_put(event);
  511. return cs ? 0 : -1;
  512. }
  513. /* If dup < 0, add a prefix. Else, add _dupl_X suffix. */
  514. static char *change_name(char *name, char *orig_name, int dup)
  515. {
  516. char *new_name = NULL;
  517. size_t len;
  518. if (!name)
  519. name = orig_name;
  520. if (dup >= 10)
  521. goto out;
  522. /*
  523. * Add '_' prefix to potential keywork. According to
  524. * Mathieu Desnoyers (https://lkml.org/lkml/2015/1/23/652),
  525. * futher CTF spec updating may require us to use '$'.
  526. */
  527. if (dup < 0)
  528. len = strlen(name) + sizeof("_");
  529. else
  530. len = strlen(orig_name) + sizeof("_dupl_X");
  531. new_name = malloc(len);
  532. if (!new_name)
  533. goto out;
  534. if (dup < 0)
  535. snprintf(new_name, len, "_%s", name);
  536. else
  537. snprintf(new_name, len, "%s_dupl_%d", orig_name, dup);
  538. out:
  539. if (name != orig_name)
  540. free(name);
  541. return new_name;
  542. }
  543. static int event_class_add_field(struct bt_ctf_event_class *event_class,
  544. struct bt_ctf_field_type *type,
  545. struct format_field *field)
  546. {
  547. struct bt_ctf_field_type *t = NULL;
  548. char *name;
  549. int dup = 1;
  550. int ret;
  551. /* alias was already assigned */
  552. if (field->alias != field->name)
  553. return bt_ctf_event_class_add_field(event_class, type,
  554. (char *)field->alias);
  555. name = field->name;
  556. /* If 'name' is a keywork, add prefix. */
  557. if (bt_ctf_validate_identifier(name))
  558. name = change_name(name, field->name, -1);
  559. if (!name) {
  560. pr_err("Failed to fix invalid identifier.");
  561. return -1;
  562. }
  563. while ((t = bt_ctf_event_class_get_field_by_name(event_class, name))) {
  564. bt_ctf_field_type_put(t);
  565. name = change_name(name, field->name, dup++);
  566. if (!name) {
  567. pr_err("Failed to create dup name for '%s'\n", field->name);
  568. return -1;
  569. }
  570. }
  571. ret = bt_ctf_event_class_add_field(event_class, type, name);
  572. if (!ret)
  573. field->alias = name;
  574. return ret;
  575. }
  576. static int add_tracepoint_fields_types(struct ctf_writer *cw,
  577. struct format_field *fields,
  578. struct bt_ctf_event_class *event_class)
  579. {
  580. struct format_field *field;
  581. int ret;
  582. for (field = fields; field; field = field->next) {
  583. struct bt_ctf_field_type *type;
  584. unsigned long flags = field->flags;
  585. pr2(" field '%s'\n", field->name);
  586. type = get_tracepoint_field_type(cw, field);
  587. if (!type)
  588. return -1;
  589. /*
  590. * A string is an array of chars. For this we use the string
  591. * type and don't care that it is an array. What we don't
  592. * support is an array of strings.
  593. */
  594. if (flags & FIELD_IS_STRING)
  595. flags &= ~FIELD_IS_ARRAY;
  596. if (flags & FIELD_IS_ARRAY)
  597. type = bt_ctf_field_type_array_create(type, field->arraylen);
  598. ret = event_class_add_field(event_class, type, field);
  599. if (flags & FIELD_IS_ARRAY)
  600. bt_ctf_field_type_put(type);
  601. if (ret) {
  602. pr_err("Failed to add field '%s': %d\n",
  603. field->name, ret);
  604. return -1;
  605. }
  606. }
  607. return 0;
  608. }
  609. static int add_tracepoint_types(struct ctf_writer *cw,
  610. struct perf_evsel *evsel,
  611. struct bt_ctf_event_class *class)
  612. {
  613. struct format_field *common_fields = evsel->tp_format->format.common_fields;
  614. struct format_field *fields = evsel->tp_format->format.fields;
  615. int ret;
  616. ret = add_tracepoint_fields_types(cw, common_fields, class);
  617. if (!ret)
  618. ret = add_tracepoint_fields_types(cw, fields, class);
  619. return ret;
  620. }
  621. static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel,
  622. struct bt_ctf_event_class *event_class)
  623. {
  624. u64 type = evsel->attr.sample_type;
  625. /*
  626. * missing:
  627. * PERF_SAMPLE_TIME - not needed as we have it in
  628. * ctf event header
  629. * PERF_SAMPLE_READ - TODO
  630. * PERF_SAMPLE_CALLCHAIN - TODO
  631. * PERF_SAMPLE_RAW - tracepoint fields are handled separately
  632. * PERF_SAMPLE_BRANCH_STACK - TODO
  633. * PERF_SAMPLE_REGS_USER - TODO
  634. * PERF_SAMPLE_STACK_USER - TODO
  635. */
  636. #define ADD_FIELD(cl, t, n) \
  637. do { \
  638. pr2(" field '%s'\n", n); \
  639. if (bt_ctf_event_class_add_field(cl, t, n)) { \
  640. pr_err("Failed to add field '%s';\n", n); \
  641. return -1; \
  642. } \
  643. } while (0)
  644. if (type & PERF_SAMPLE_IP)
  645. ADD_FIELD(event_class, cw->data.u64_hex, "perf_ip");
  646. if (type & PERF_SAMPLE_TID) {
  647. ADD_FIELD(event_class, cw->data.s32, "perf_tid");
  648. ADD_FIELD(event_class, cw->data.s32, "perf_pid");
  649. }
  650. if ((type & PERF_SAMPLE_ID) ||
  651. (type & PERF_SAMPLE_IDENTIFIER))
  652. ADD_FIELD(event_class, cw->data.u64, "perf_id");
  653. if (type & PERF_SAMPLE_STREAM_ID)
  654. ADD_FIELD(event_class, cw->data.u64, "perf_stream_id");
  655. if (type & PERF_SAMPLE_PERIOD)
  656. ADD_FIELD(event_class, cw->data.u64, "perf_period");
  657. if (type & PERF_SAMPLE_WEIGHT)
  658. ADD_FIELD(event_class, cw->data.u64, "perf_weight");
  659. if (type & PERF_SAMPLE_DATA_SRC)
  660. ADD_FIELD(event_class, cw->data.u64, "perf_data_src");
  661. if (type & PERF_SAMPLE_TRANSACTION)
  662. ADD_FIELD(event_class, cw->data.u64, "perf_transaction");
  663. #undef ADD_FIELD
  664. return 0;
  665. }
  666. static int add_event(struct ctf_writer *cw, struct perf_evsel *evsel)
  667. {
  668. struct bt_ctf_event_class *event_class;
  669. struct evsel_priv *priv;
  670. const char *name = perf_evsel__name(evsel);
  671. int ret;
  672. pr("Adding event '%s' (type %d)\n", name, evsel->attr.type);
  673. event_class = bt_ctf_event_class_create(name);
  674. if (!event_class)
  675. return -1;
  676. ret = add_generic_types(cw, evsel, event_class);
  677. if (ret)
  678. goto err;
  679. if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
  680. ret = add_tracepoint_types(cw, evsel, event_class);
  681. if (ret)
  682. goto err;
  683. }
  684. ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);
  685. if (ret) {
  686. pr("Failed to add event class into stream.\n");
  687. goto err;
  688. }
  689. priv = malloc(sizeof(*priv));
  690. if (!priv)
  691. goto err;
  692. priv->event_class = event_class;
  693. evsel->priv = priv;
  694. return 0;
  695. err:
  696. bt_ctf_event_class_put(event_class);
  697. pr_err("Failed to add event '%s'.\n", name);
  698. return -1;
  699. }
  700. static int setup_events(struct ctf_writer *cw, struct perf_session *session)
  701. {
  702. struct perf_evlist *evlist = session->evlist;
  703. struct perf_evsel *evsel;
  704. int ret;
  705. evlist__for_each(evlist, evsel) {
  706. ret = add_event(cw, evsel);
  707. if (ret)
  708. return ret;
  709. }
  710. return 0;
  711. }
  712. static int setup_streams(struct ctf_writer *cw, struct perf_session *session)
  713. {
  714. struct ctf_stream **stream;
  715. struct perf_header *ph = &session->header;
  716. int ncpus;
  717. /*
  718. * Try to get the number of cpus used in the data file,
  719. * if not present fallback to the MAX_CPUS.
  720. */
  721. ncpus = ph->env.nr_cpus_avail ?: MAX_CPUS;
  722. stream = zalloc(sizeof(*stream) * ncpus);
  723. if (!stream) {
  724. pr_err("Failed to allocate streams.\n");
  725. return -ENOMEM;
  726. }
  727. cw->stream = stream;
  728. cw->stream_cnt = ncpus;
  729. return 0;
  730. }
  731. static void free_streams(struct ctf_writer *cw)
  732. {
  733. int cpu;
  734. for (cpu = 0; cpu < cw->stream_cnt; cpu++)
  735. ctf_stream__delete(cw->stream[cpu]);
  736. free(cw->stream);
  737. }
  738. static int ctf_writer__setup_env(struct ctf_writer *cw,
  739. struct perf_session *session)
  740. {
  741. struct perf_header *header = &session->header;
  742. struct bt_ctf_writer *writer = cw->writer;
  743. #define ADD(__n, __v) \
  744. do { \
  745. if (bt_ctf_writer_add_environment_field(writer, __n, __v)) \
  746. return -1; \
  747. } while (0)
  748. ADD("host", header->env.hostname);
  749. ADD("sysname", "Linux");
  750. ADD("release", header->env.os_release);
  751. ADD("version", header->env.version);
  752. ADD("machine", header->env.arch);
  753. ADD("domain", "kernel");
  754. ADD("tracer_name", "perf");
  755. #undef ADD
  756. return 0;
  757. }
  758. static int ctf_writer__setup_clock(struct ctf_writer *cw)
  759. {
  760. struct bt_ctf_clock *clock = cw->clock;
  761. bt_ctf_clock_set_description(clock, "perf clock");
  762. #define SET(__n, __v) \
  763. do { \
  764. if (bt_ctf_clock_set_##__n(clock, __v)) \
  765. return -1; \
  766. } while (0)
  767. SET(frequency, 1000000000);
  768. SET(offset_s, 0);
  769. SET(offset, 0);
  770. SET(precision, 10);
  771. SET(is_absolute, 0);
  772. #undef SET
  773. return 0;
  774. }
  775. static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex)
  776. {
  777. struct bt_ctf_field_type *type;
  778. type = bt_ctf_field_type_integer_create(size);
  779. if (!type)
  780. return NULL;
  781. if (sign &&
  782. bt_ctf_field_type_integer_set_signed(type, 1))
  783. goto err;
  784. if (hex &&
  785. bt_ctf_field_type_integer_set_base(type, BT_CTF_INTEGER_BASE_HEXADECIMAL))
  786. goto err;
  787. pr2("Created type: INTEGER %d-bit %ssigned %s\n",
  788. size, sign ? "un" : "", hex ? "hex" : "");
  789. return type;
  790. err:
  791. bt_ctf_field_type_put(type);
  792. return NULL;
  793. }
  794. static void ctf_writer__cleanup_data(struct ctf_writer *cw)
  795. {
  796. unsigned int i;
  797. for (i = 0; i < ARRAY_SIZE(cw->data.array); i++)
  798. bt_ctf_field_type_put(cw->data.array[i]);
  799. }
  800. static int ctf_writer__init_data(struct ctf_writer *cw)
  801. {
  802. #define CREATE_INT_TYPE(type, size, sign, hex) \
  803. do { \
  804. (type) = create_int_type(size, sign, hex); \
  805. if (!(type)) \
  806. goto err; \
  807. } while (0)
  808. CREATE_INT_TYPE(cw->data.s64, 64, true, false);
  809. CREATE_INT_TYPE(cw->data.u64, 64, false, false);
  810. CREATE_INT_TYPE(cw->data.s32, 32, true, false);
  811. CREATE_INT_TYPE(cw->data.u32, 32, false, false);
  812. CREATE_INT_TYPE(cw->data.u32_hex, 32, false, true);
  813. CREATE_INT_TYPE(cw->data.u64_hex, 64, false, true);
  814. cw->data.string = bt_ctf_field_type_string_create();
  815. if (cw->data.string)
  816. return 0;
  817. err:
  818. ctf_writer__cleanup_data(cw);
  819. pr_err("Failed to create data types.\n");
  820. return -1;
  821. }
  822. static void ctf_writer__cleanup(struct ctf_writer *cw)
  823. {
  824. ctf_writer__cleanup_data(cw);
  825. bt_ctf_clock_put(cw->clock);
  826. free_streams(cw);
  827. bt_ctf_stream_class_put(cw->stream_class);
  828. bt_ctf_writer_put(cw->writer);
  829. /* and NULL all the pointers */
  830. memset(cw, 0, sizeof(*cw));
  831. }
  832. static int ctf_writer__init(struct ctf_writer *cw, const char *path)
  833. {
  834. struct bt_ctf_writer *writer;
  835. struct bt_ctf_stream_class *stream_class;
  836. struct bt_ctf_clock *clock;
  837. struct bt_ctf_field_type *pkt_ctx_type;
  838. int ret;
  839. /* CTF writer */
  840. writer = bt_ctf_writer_create(path);
  841. if (!writer)
  842. goto err;
  843. cw->writer = writer;
  844. /* CTF clock */
  845. clock = bt_ctf_clock_create("perf_clock");
  846. if (!clock) {
  847. pr("Failed to create CTF clock.\n");
  848. goto err_cleanup;
  849. }
  850. cw->clock = clock;
  851. if (ctf_writer__setup_clock(cw)) {
  852. pr("Failed to setup CTF clock.\n");
  853. goto err_cleanup;
  854. }
  855. /* CTF stream class */
  856. stream_class = bt_ctf_stream_class_create("perf_stream");
  857. if (!stream_class) {
  858. pr("Failed to create CTF stream class.\n");
  859. goto err_cleanup;
  860. }
  861. cw->stream_class = stream_class;
  862. /* CTF clock stream setup */
  863. if (bt_ctf_stream_class_set_clock(stream_class, clock)) {
  864. pr("Failed to assign CTF clock to stream class.\n");
  865. goto err_cleanup;
  866. }
  867. if (ctf_writer__init_data(cw))
  868. goto err_cleanup;
  869. /* Add cpu_id for packet context */
  870. pkt_ctx_type = bt_ctf_stream_class_get_packet_context_type(stream_class);
  871. if (!pkt_ctx_type)
  872. goto err_cleanup;
  873. ret = bt_ctf_field_type_structure_add_field(pkt_ctx_type, cw->data.u32, "cpu_id");
  874. bt_ctf_field_type_put(pkt_ctx_type);
  875. if (ret)
  876. goto err_cleanup;
  877. /* CTF clock writer setup */
  878. if (bt_ctf_writer_add_clock(writer, clock)) {
  879. pr("Failed to assign CTF clock to writer.\n");
  880. goto err_cleanup;
  881. }
  882. return 0;
  883. err_cleanup:
  884. ctf_writer__cleanup(cw);
  885. err:
  886. pr_err("Failed to setup CTF writer.\n");
  887. return -1;
  888. }
  889. static int ctf_writer__flush_streams(struct ctf_writer *cw)
  890. {
  891. int cpu, ret = 0;
  892. for (cpu = 0; cpu < cw->stream_cnt && !ret; cpu++)
  893. ret = ctf_stream__flush(cw->stream[cpu]);
  894. return ret;
  895. }
  896. static int convert__config(const char *var, const char *value, void *cb)
  897. {
  898. struct convert *c = cb;
  899. if (!strcmp(var, "convert.queue-size")) {
  900. c->queue_size = perf_config_u64(var, value);
  901. return 0;
  902. }
  903. return perf_default_config(var, value, cb);
  904. }
  905. int bt_convert__perf2ctf(const char *input, const char *path, bool force)
  906. {
  907. struct perf_session *session;
  908. struct perf_data_file file = {
  909. .path = input,
  910. .mode = PERF_DATA_MODE_READ,
  911. .force = force,
  912. };
  913. struct convert c = {
  914. .tool = {
  915. .sample = process_sample_event,
  916. .mmap = perf_event__process_mmap,
  917. .mmap2 = perf_event__process_mmap2,
  918. .comm = perf_event__process_comm,
  919. .exit = perf_event__process_exit,
  920. .fork = perf_event__process_fork,
  921. .lost = perf_event__process_lost,
  922. .tracing_data = perf_event__process_tracing_data,
  923. .build_id = perf_event__process_build_id,
  924. .ordered_events = true,
  925. .ordering_requires_timestamps = true,
  926. },
  927. };
  928. struct ctf_writer *cw = &c.writer;
  929. int err = -1;
  930. perf_config(convert__config, &c);
  931. /* CTF writer */
  932. if (ctf_writer__init(cw, path))
  933. return -1;
  934. /* perf.data session */
  935. session = perf_session__new(&file, 0, &c.tool);
  936. if (!session)
  937. goto free_writer;
  938. if (c.queue_size) {
  939. ordered_events__set_alloc_size(&session->ordered_events,
  940. c.queue_size);
  941. }
  942. /* CTF writer env/clock setup */
  943. if (ctf_writer__setup_env(cw, session))
  944. goto free_session;
  945. /* CTF events setup */
  946. if (setup_events(cw, session))
  947. goto free_session;
  948. if (setup_streams(cw, session))
  949. goto free_session;
  950. err = perf_session__process_events(session);
  951. if (!err)
  952. err = ctf_writer__flush_streams(cw);
  953. else
  954. pr_err("Error during conversion.\n");
  955. fprintf(stderr,
  956. "[ perf data convert: Converted '%s' into CTF data '%s' ]\n",
  957. file.path, path);
  958. fprintf(stderr,
  959. "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n",
  960. (double) c.events_size / 1024.0 / 1024.0,
  961. c.events_count);
  962. perf_session__delete(session);
  963. ctf_writer__cleanup(cw);
  964. return err;
  965. free_session:
  966. perf_session__delete(session);
  967. free_writer:
  968. ctf_writer__cleanup(cw);
  969. pr_err("Error during conversion setup.\n");
  970. return err;
  971. }