data-convert-bt.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * CTF writing support via babeltrace.
  4. *
  5. * Copyright (C) 2014, Jiri Olsa <jolsa@redhat.com>
  6. * Copyright (C) 2014, Sebastian Andrzej Siewior <bigeasy@linutronix.de>
  7. */
  8. #include <errno.h>
  9. #include <inttypes.h>
  10. #include <linux/compiler.h>
  11. #include <linux/kernel.h>
  12. #include <linux/zalloc.h>
  13. #include <babeltrace/ctf-writer/writer.h>
  14. #include <babeltrace/ctf-writer/clock.h>
  15. #include <babeltrace/ctf-writer/stream.h>
  16. #include <babeltrace/ctf-writer/event.h>
  17. #include <babeltrace/ctf-writer/event-types.h>
  18. #include <babeltrace/ctf-writer/event-fields.h>
  19. #include <babeltrace/ctf-ir/utils.h>
  20. #include <babeltrace/ctf/events.h>
  21. #include "asm/bug.h"
  22. #include "data-convert.h"
  23. #include "session.h"
  24. #include "debug.h"
  25. #include "tool.h"
  26. #include "evlist.h"
  27. #include "evsel.h"
  28. #include "machine.h"
  29. #include "config.h"
  30. #include <linux/ctype.h>
  31. #include <linux/err.h>
  32. #include <linux/time64.h>
  33. #include "util.h"
  34. #include "clockid.h"
  35. #include "util/sample.h"
  36. #include "util/time-utils.h"
  37. #include "header.h"
  38. #ifdef HAVE_LIBTRACEEVENT
  39. #include <event-parse.h>
  40. #endif
  41. #define pr_N(n, fmt, ...) \
  42. eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__)
  43. #define pr(fmt, ...) pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
  44. #define pr2(fmt, ...) pr_N(2, pr_fmt(fmt), ##__VA_ARGS__)
  45. #define pr_time2(t, fmt, ...) pr_time_N(2, debug_data_convert, t, pr_fmt(fmt), ##__VA_ARGS__)
  46. struct evsel_priv {
  47. struct bt_ctf_event_class *event_class;
  48. };
  49. #define MAX_CPUS 4096
  50. struct ctf_stream {
  51. struct bt_ctf_stream *stream;
  52. int cpu;
  53. u32 count;
  54. };
  55. struct ctf_writer {
  56. /* writer primitives */
  57. struct bt_ctf_writer *writer;
  58. struct ctf_stream **stream;
  59. int stream_cnt;
  60. struct bt_ctf_stream_class *stream_class;
  61. struct bt_ctf_clock *clock;
  62. /* data types */
  63. union {
  64. struct {
  65. struct bt_ctf_field_type *s64;
  66. struct bt_ctf_field_type *u64;
  67. struct bt_ctf_field_type *s32;
  68. struct bt_ctf_field_type *u32;
  69. struct bt_ctf_field_type *string;
  70. struct bt_ctf_field_type *u32_hex;
  71. struct bt_ctf_field_type *u64_hex;
  72. };
  73. struct bt_ctf_field_type *array[6];
  74. } data;
  75. struct bt_ctf_event_class *comm_class;
  76. struct bt_ctf_event_class *exit_class;
  77. struct bt_ctf_event_class *fork_class;
  78. struct bt_ctf_event_class *mmap_class;
  79. struct bt_ctf_event_class *mmap2_class;
  80. };
  81. struct convert {
  82. struct perf_tool tool;
  83. struct ctf_writer writer;
  84. struct perf_time_interval *ptime_range;
  85. int range_size;
  86. int range_num;
  87. u64 events_size;
  88. u64 events_count;
  89. u64 non_sample_count;
  90. u64 skipped;
  91. /* Ordered events configured queue size. */
  92. u64 queue_size;
  93. };
  94. static int value_set(struct bt_ctf_field_type *type,
  95. struct bt_ctf_event *event,
  96. const char *name, u64 val)
  97. {
  98. struct bt_ctf_field *field;
  99. bool sign = bt_ctf_field_type_integer_get_signed(type);
  100. int ret;
  101. field = bt_ctf_field_create(type);
  102. if (!field) {
  103. pr_err("failed to create a field %s\n", name);
  104. return -1;
  105. }
  106. if (sign) {
  107. ret = bt_ctf_field_signed_integer_set_value(field, val);
  108. if (ret) {
  109. pr_err("failed to set field value %s\n", name);
  110. goto err;
  111. }
  112. } else {
  113. ret = bt_ctf_field_unsigned_integer_set_value(field, val);
  114. if (ret) {
  115. pr_err("failed to set field value %s\n", name);
  116. goto err;
  117. }
  118. }
  119. ret = bt_ctf_event_set_payload(event, name, field);
  120. if (ret) {
  121. pr_err("failed to set payload %s\n", name);
  122. goto err;
  123. }
  124. pr2(" SET [%s = %" PRIu64 "]\n", name, val);
  125. err:
  126. bt_ctf_field_put(field);
  127. return ret;
  128. }
  129. #define __FUNC_VALUE_SET(_name, _val_type) \
  130. static __maybe_unused int value_set_##_name(struct ctf_writer *cw, \
  131. struct bt_ctf_event *event, \
  132. const char *name, \
  133. _val_type val) \
  134. { \
  135. struct bt_ctf_field_type *type = cw->data._name; \
  136. return value_set(type, event, name, (u64) val); \
  137. }
  138. #define FUNC_VALUE_SET(_name) __FUNC_VALUE_SET(_name, _name)
  139. FUNC_VALUE_SET(s32)
  140. FUNC_VALUE_SET(u32)
  141. FUNC_VALUE_SET(s64)
  142. FUNC_VALUE_SET(u64)
  143. __FUNC_VALUE_SET(u64_hex, u64)
  144. static int string_set_value(struct bt_ctf_field *field, const char *string);
  145. static __maybe_unused int
  146. value_set_string(struct ctf_writer *cw, struct bt_ctf_event *event,
  147. const char *name, const char *string)
  148. {
  149. struct bt_ctf_field_type *type = cw->data.string;
  150. struct bt_ctf_field *field;
  151. int ret = 0;
  152. field = bt_ctf_field_create(type);
  153. if (!field) {
  154. pr_err("failed to create a field %s\n", name);
  155. return -1;
  156. }
  157. ret = string_set_value(field, string);
  158. if (ret) {
  159. pr_err("failed to set value %s\n", name);
  160. goto err_put_field;
  161. }
  162. ret = bt_ctf_event_set_payload(event, name, field);
  163. if (ret)
  164. pr_err("failed to set payload %s\n", name);
  165. err_put_field:
  166. bt_ctf_field_put(field);
  167. return ret;
  168. }
  169. static struct bt_ctf_field_type*
  170. get_tracepoint_field_type(struct ctf_writer *cw, struct tep_format_field *field)
  171. {
  172. unsigned long flags = field->flags;
  173. if (flags & TEP_FIELD_IS_STRING)
  174. return cw->data.string;
  175. if (!(flags & TEP_FIELD_IS_SIGNED)) {
  176. /* unsigned long are mostly pointers */
  177. if (flags & TEP_FIELD_IS_LONG || flags & TEP_FIELD_IS_POINTER)
  178. return cw->data.u64_hex;
  179. }
  180. if (flags & TEP_FIELD_IS_SIGNED) {
  181. if (field->size == 8)
  182. return cw->data.s64;
  183. else
  184. return cw->data.s32;
  185. }
  186. if (field->size == 8)
  187. return cw->data.u64;
  188. else
  189. return cw->data.u32;
  190. }
  191. static unsigned long long adjust_signedness(unsigned long long value_int, int size)
  192. {
  193. unsigned long long value_mask;
  194. /*
  195. * value_mask = (1 << (size * 8 - 1)) - 1.
  196. * Directly set value_mask for code readers.
  197. */
  198. switch (size) {
  199. case 1:
  200. value_mask = 0x7fULL;
  201. break;
  202. case 2:
  203. value_mask = 0x7fffULL;
  204. break;
  205. case 4:
  206. value_mask = 0x7fffffffULL;
  207. break;
  208. case 8:
  209. /*
  210. * For 64 bit value, return it self. There is no need
  211. * to fill high bit.
  212. */
  213. /* Fall through */
  214. default:
  215. /* BUG! */
  216. return value_int;
  217. }
  218. /* If it is a positive value, don't adjust. */
  219. if ((value_int & (~0ULL - value_mask)) == 0)
  220. return value_int;
  221. /* Fill upper part of value_int with 1 to make it a negative long long. */
  222. return (value_int & value_mask) | ~value_mask;
  223. }
  224. static int string_set_value(struct bt_ctf_field *field, const char *string)
  225. {
  226. char *buffer = NULL;
  227. size_t len = strlen(string), i, p;
  228. int err;
  229. for (i = p = 0; i < len; i++, p++) {
  230. if (isprint(string[i])) {
  231. if (!buffer)
  232. continue;
  233. buffer[p] = string[i];
  234. } else {
  235. char numstr[5];
  236. snprintf(numstr, sizeof(numstr), "\\x%02x",
  237. (unsigned int)(string[i]) & 0xff);
  238. if (!buffer) {
  239. buffer = zalloc(i + (len - i) * 4 + 2);
  240. if (!buffer) {
  241. pr_err("failed to set unprintable string '%s'\n", string);
  242. return bt_ctf_field_string_set_value(field, "UNPRINTABLE-STRING");
  243. }
  244. if (i > 0)
  245. strncpy(buffer, string, i);
  246. }
  247. memcpy(buffer + p, numstr, 4);
  248. p += 3;
  249. }
  250. }
  251. if (!buffer)
  252. return bt_ctf_field_string_set_value(field, string);
  253. err = bt_ctf_field_string_set_value(field, buffer);
  254. free(buffer);
  255. return err;
  256. }
  257. static int add_tracepoint_field_value(struct ctf_writer *cw,
  258. struct bt_ctf_event_class *event_class,
  259. struct bt_ctf_event *event,
  260. struct perf_sample *sample,
  261. struct tep_format_field *fmtf)
  262. {
  263. struct bt_ctf_field_type *type;
  264. struct bt_ctf_field *array_field;
  265. struct bt_ctf_field *field;
  266. const char *name = fmtf->name;
  267. void *data = sample->raw_data;
  268. unsigned long flags = fmtf->flags;
  269. unsigned int n_items;
  270. unsigned int i;
  271. unsigned int offset;
  272. unsigned int len;
  273. int ret;
  274. name = fmtf->alias;
  275. offset = fmtf->offset;
  276. len = fmtf->size;
  277. if (flags & TEP_FIELD_IS_STRING)
  278. flags &= ~TEP_FIELD_IS_ARRAY;
  279. if (flags & TEP_FIELD_IS_DYNAMIC) {
  280. unsigned long long tmp_val;
  281. tmp_val = tep_read_number(fmtf->event->tep,
  282. data + offset, len);
  283. offset = tmp_val;
  284. len = offset >> 16;
  285. offset &= 0xffff;
  286. if (tep_field_is_relative(flags))
  287. offset += fmtf->offset + fmtf->size;
  288. }
  289. if (flags & TEP_FIELD_IS_ARRAY) {
  290. type = bt_ctf_event_class_get_field_by_name(
  291. event_class, name);
  292. array_field = bt_ctf_field_create(type);
  293. bt_ctf_field_type_put(type);
  294. if (!array_field) {
  295. pr_err("Failed to create array type %s\n", name);
  296. return -1;
  297. }
  298. len = fmtf->size / fmtf->arraylen;
  299. n_items = fmtf->arraylen;
  300. } else {
  301. n_items = 1;
  302. array_field = NULL;
  303. }
  304. type = get_tracepoint_field_type(cw, fmtf);
  305. for (i = 0; i < n_items; i++) {
  306. if (flags & TEP_FIELD_IS_ARRAY)
  307. field = bt_ctf_field_array_get_field(array_field, i);
  308. else
  309. field = bt_ctf_field_create(type);
  310. if (!field) {
  311. pr_err("failed to create a field %s\n", name);
  312. return -1;
  313. }
  314. if (flags & TEP_FIELD_IS_STRING)
  315. ret = string_set_value(field, data + offset + i * len);
  316. else {
  317. unsigned long long value_int;
  318. value_int = tep_read_number(
  319. fmtf->event->tep,
  320. data + offset + i * len, len);
  321. if (!(flags & TEP_FIELD_IS_SIGNED))
  322. ret = bt_ctf_field_unsigned_integer_set_value(
  323. field, value_int);
  324. else
  325. ret = bt_ctf_field_signed_integer_set_value(
  326. field, adjust_signedness(value_int, len));
  327. }
  328. if (ret) {
  329. pr_err("failed to set file value %s\n", name);
  330. goto err_put_field;
  331. }
  332. if (!(flags & TEP_FIELD_IS_ARRAY)) {
  333. ret = bt_ctf_event_set_payload(event, name, field);
  334. if (ret) {
  335. pr_err("failed to set payload %s\n", name);
  336. goto err_put_field;
  337. }
  338. }
  339. bt_ctf_field_put(field);
  340. }
  341. if (flags & TEP_FIELD_IS_ARRAY) {
  342. ret = bt_ctf_event_set_payload(event, name, array_field);
  343. if (ret) {
  344. pr_err("Failed add payload array %s\n", name);
  345. return -1;
  346. }
  347. bt_ctf_field_put(array_field);
  348. }
  349. return 0;
  350. err_put_field:
  351. bt_ctf_field_put(field);
  352. return -1;
  353. }
  354. static int add_tracepoint_fields_values(struct ctf_writer *cw,
  355. struct bt_ctf_event_class *event_class,
  356. struct bt_ctf_event *event,
  357. struct tep_format_field *fields,
  358. struct perf_sample *sample)
  359. {
  360. struct tep_format_field *field;
  361. int ret;
  362. for (field = fields; field; field = field->next) {
  363. ret = add_tracepoint_field_value(cw, event_class, event, sample,
  364. field);
  365. if (ret)
  366. return -1;
  367. }
  368. return 0;
  369. }
  370. static int add_tracepoint_values(struct ctf_writer *cw,
  371. struct bt_ctf_event_class *event_class,
  372. struct bt_ctf_event *event,
  373. struct evsel *evsel,
  374. struct perf_sample *sample)
  375. {
  376. const struct tep_event *tp_format = evsel__tp_format(evsel);
  377. struct tep_format_field *common_fields = tp_format->format.common_fields;
  378. struct tep_format_field *fields = tp_format->format.fields;
  379. int ret;
  380. ret = add_tracepoint_fields_values(cw, event_class, event,
  381. common_fields, sample);
  382. if (!ret)
  383. ret = add_tracepoint_fields_values(cw, event_class, event,
  384. fields, sample);
  385. return ret;
  386. }
  387. static int
  388. add_bpf_output_values(struct bt_ctf_event_class *event_class,
  389. struct bt_ctf_event *event,
  390. struct perf_sample *sample)
  391. {
  392. struct bt_ctf_field_type *len_type, *seq_type;
  393. struct bt_ctf_field *len_field, *seq_field;
  394. unsigned int raw_size = sample->raw_size;
  395. unsigned int nr_elements = raw_size / sizeof(u32);
  396. unsigned int i;
  397. int ret;
  398. if (nr_elements * sizeof(u32) != raw_size)
  399. pr_warning("Incorrect raw_size (%u) in bpf output event, skip %zu bytes\n",
  400. raw_size, nr_elements * sizeof(u32) - raw_size);
  401. len_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_len");
  402. len_field = bt_ctf_field_create(len_type);
  403. if (!len_field) {
  404. pr_err("failed to create 'raw_len' for bpf output event\n");
  405. ret = -1;
  406. goto put_len_type;
  407. }
  408. ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
  409. if (ret) {
  410. pr_err("failed to set field value for raw_len\n");
  411. goto put_len_field;
  412. }
  413. ret = bt_ctf_event_set_payload(event, "raw_len", len_field);
  414. if (ret) {
  415. pr_err("failed to set payload to raw_len\n");
  416. goto put_len_field;
  417. }
  418. seq_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_data");
  419. seq_field = bt_ctf_field_create(seq_type);
  420. if (!seq_field) {
  421. pr_err("failed to create 'raw_data' for bpf output event\n");
  422. ret = -1;
  423. goto put_seq_type;
  424. }
  425. ret = bt_ctf_field_sequence_set_length(seq_field, len_field);
  426. if (ret) {
  427. pr_err("failed to set length of 'raw_data'\n");
  428. goto put_seq_field;
  429. }
  430. for (i = 0; i < nr_elements; i++) {
  431. struct bt_ctf_field *elem_field =
  432. bt_ctf_field_sequence_get_field(seq_field, i);
  433. ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
  434. ((u32 *)(sample->raw_data))[i]);
  435. bt_ctf_field_put(elem_field);
  436. if (ret) {
  437. pr_err("failed to set raw_data[%d]\n", i);
  438. goto put_seq_field;
  439. }
  440. }
  441. ret = bt_ctf_event_set_payload(event, "raw_data", seq_field);
  442. if (ret)
  443. pr_err("failed to set payload for raw_data\n");
  444. put_seq_field:
  445. bt_ctf_field_put(seq_field);
  446. put_seq_type:
  447. bt_ctf_field_type_put(seq_type);
  448. put_len_field:
  449. bt_ctf_field_put(len_field);
  450. put_len_type:
  451. bt_ctf_field_type_put(len_type);
  452. return ret;
  453. }
  454. static int
  455. add_callchain_output_values(struct bt_ctf_event_class *event_class,
  456. struct bt_ctf_event *event,
  457. struct ip_callchain *callchain)
  458. {
  459. struct bt_ctf_field_type *len_type, *seq_type;
  460. struct bt_ctf_field *len_field, *seq_field;
  461. unsigned int nr_elements = callchain->nr;
  462. unsigned int i;
  463. int ret;
  464. len_type = bt_ctf_event_class_get_field_by_name(
  465. event_class, "perf_callchain_size");
  466. len_field = bt_ctf_field_create(len_type);
  467. if (!len_field) {
  468. pr_err("failed to create 'perf_callchain_size' for callchain output event\n");
  469. ret = -1;
  470. goto put_len_type;
  471. }
  472. ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
  473. if (ret) {
  474. pr_err("failed to set field value for perf_callchain_size\n");
  475. goto put_len_field;
  476. }
  477. ret = bt_ctf_event_set_payload(event, "perf_callchain_size", len_field);
  478. if (ret) {
  479. pr_err("failed to set payload to perf_callchain_size\n");
  480. goto put_len_field;
  481. }
  482. seq_type = bt_ctf_event_class_get_field_by_name(
  483. event_class, "perf_callchain");
  484. seq_field = bt_ctf_field_create(seq_type);
  485. if (!seq_field) {
  486. pr_err("failed to create 'perf_callchain' for callchain output event\n");
  487. ret = -1;
  488. goto put_seq_type;
  489. }
  490. ret = bt_ctf_field_sequence_set_length(seq_field, len_field);
  491. if (ret) {
  492. pr_err("failed to set length of 'perf_callchain'\n");
  493. goto put_seq_field;
  494. }
  495. for (i = 0; i < nr_elements; i++) {
  496. struct bt_ctf_field *elem_field =
  497. bt_ctf_field_sequence_get_field(seq_field, i);
  498. ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
  499. ((u64 *)(callchain->ips))[i]);
  500. bt_ctf_field_put(elem_field);
  501. if (ret) {
  502. pr_err("failed to set callchain[%d]\n", i);
  503. goto put_seq_field;
  504. }
  505. }
  506. ret = bt_ctf_event_set_payload(event, "perf_callchain", seq_field);
  507. if (ret)
  508. pr_err("failed to set payload for raw_data\n");
  509. put_seq_field:
  510. bt_ctf_field_put(seq_field);
  511. put_seq_type:
  512. bt_ctf_field_type_put(seq_type);
  513. put_len_field:
  514. bt_ctf_field_put(len_field);
  515. put_len_type:
  516. bt_ctf_field_type_put(len_type);
  517. return ret;
  518. }
  519. static int add_generic_values(struct ctf_writer *cw,
  520. struct bt_ctf_event *event,
  521. struct evsel *evsel,
  522. struct perf_sample *sample)
  523. {
  524. u64 type = evsel->core.attr.sample_type;
  525. int ret;
  526. /*
  527. * missing:
  528. * PERF_SAMPLE_TIME - not needed as we have it in
  529. * ctf event header
  530. * PERF_SAMPLE_READ - TODO
  531. * PERF_SAMPLE_RAW - tracepoint fields are handled separately
  532. * PERF_SAMPLE_BRANCH_STACK - TODO
  533. * PERF_SAMPLE_REGS_USER - TODO
  534. * PERF_SAMPLE_STACK_USER - TODO
  535. */
  536. if (type & PERF_SAMPLE_IP) {
  537. ret = value_set_u64_hex(cw, event, "perf_ip", sample->ip);
  538. if (ret)
  539. return -1;
  540. }
  541. if (type & PERF_SAMPLE_TID) {
  542. ret = value_set_s32(cw, event, "perf_tid", sample->tid);
  543. if (ret)
  544. return -1;
  545. ret = value_set_s32(cw, event, "perf_pid", sample->pid);
  546. if (ret)
  547. return -1;
  548. }
  549. if ((type & PERF_SAMPLE_ID) ||
  550. (type & PERF_SAMPLE_IDENTIFIER)) {
  551. ret = value_set_u64(cw, event, "perf_id", sample->id);
  552. if (ret)
  553. return -1;
  554. }
  555. if (type & PERF_SAMPLE_STREAM_ID) {
  556. ret = value_set_u64(cw, event, "perf_stream_id", sample->stream_id);
  557. if (ret)
  558. return -1;
  559. }
  560. if (type & PERF_SAMPLE_PERIOD) {
  561. ret = value_set_u64(cw, event, "perf_period", sample->period);
  562. if (ret)
  563. return -1;
  564. }
  565. if (type & PERF_SAMPLE_WEIGHT) {
  566. ret = value_set_u64(cw, event, "perf_weight", sample->weight);
  567. if (ret)
  568. return -1;
  569. }
  570. if (type & PERF_SAMPLE_DATA_SRC) {
  571. ret = value_set_u64(cw, event, "perf_data_src",
  572. sample->data_src);
  573. if (ret)
  574. return -1;
  575. }
  576. if (type & PERF_SAMPLE_TRANSACTION) {
  577. ret = value_set_u64(cw, event, "perf_transaction",
  578. sample->transaction);
  579. if (ret)
  580. return -1;
  581. }
  582. return 0;
  583. }
  584. static int ctf_stream__flush(struct ctf_stream *cs)
  585. {
  586. int err = 0;
  587. if (cs) {
  588. err = bt_ctf_stream_flush(cs->stream);
  589. if (err)
  590. pr_err("CTF stream %d flush failed\n", cs->cpu);
  591. pr("Flush stream for cpu %d (%u samples)\n",
  592. cs->cpu, cs->count);
  593. cs->count = 0;
  594. }
  595. return err;
  596. }
  597. static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
  598. {
  599. struct ctf_stream *cs;
  600. struct bt_ctf_field *pkt_ctx = NULL;
  601. struct bt_ctf_field *cpu_field = NULL;
  602. struct bt_ctf_stream *stream = NULL;
  603. int ret;
  604. cs = zalloc(sizeof(*cs));
  605. if (!cs) {
  606. pr_err("Failed to allocate ctf stream\n");
  607. return NULL;
  608. }
  609. stream = bt_ctf_writer_create_stream(cw->writer, cw->stream_class);
  610. if (!stream) {
  611. pr_err("Failed to create CTF stream\n");
  612. goto out;
  613. }
  614. pkt_ctx = bt_ctf_stream_get_packet_context(stream);
  615. if (!pkt_ctx) {
  616. pr_err("Failed to obtain packet context\n");
  617. goto out;
  618. }
  619. cpu_field = bt_ctf_field_structure_get_field(pkt_ctx, "cpu_id");
  620. bt_ctf_field_put(pkt_ctx);
  621. if (!cpu_field) {
  622. pr_err("Failed to obtain cpu field\n");
  623. goto out;
  624. }
  625. ret = bt_ctf_field_unsigned_integer_set_value(cpu_field, (u32) cpu);
  626. if (ret) {
  627. pr_err("Failed to update CPU number\n");
  628. goto out;
  629. }
  630. bt_ctf_field_put(cpu_field);
  631. cs->cpu = cpu;
  632. cs->stream = stream;
  633. return cs;
  634. out:
  635. if (cpu_field)
  636. bt_ctf_field_put(cpu_field);
  637. if (stream)
  638. bt_ctf_stream_put(stream);
  639. free(cs);
  640. return NULL;
  641. }
  642. static void ctf_stream__delete(struct ctf_stream *cs)
  643. {
  644. if (cs) {
  645. bt_ctf_stream_put(cs->stream);
  646. free(cs);
  647. }
  648. }
  649. static struct ctf_stream *ctf_stream(struct ctf_writer *cw, int cpu)
  650. {
  651. struct ctf_stream *cs = cw->stream[cpu];
  652. if (!cs) {
  653. cs = ctf_stream__create(cw, cpu);
  654. cw->stream[cpu] = cs;
  655. }
  656. return cs;
  657. }
  658. static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample,
  659. struct evsel *evsel)
  660. {
  661. int cpu = 0;
  662. if (evsel->core.attr.sample_type & PERF_SAMPLE_CPU)
  663. cpu = sample->cpu;
  664. if (cpu > cw->stream_cnt) {
  665. pr_err("Event was recorded for CPU %d, limit is at %d.\n",
  666. cpu, cw->stream_cnt);
  667. cpu = 0;
  668. }
  669. return cpu;
  670. }
  671. #define STREAM_FLUSH_COUNT 100000
  672. /*
  673. * Currently we have no other way to determine the
  674. * time for the stream flush other than keep track
  675. * of the number of events and check it against
  676. * threshold.
  677. */
  678. static bool is_flush_needed(struct ctf_stream *cs)
  679. {
  680. return cs->count >= STREAM_FLUSH_COUNT;
  681. }
  682. static int process_sample_event(const struct perf_tool *tool,
  683. union perf_event *_event,
  684. struct perf_sample *sample,
  685. struct evsel *evsel,
  686. struct machine *machine __maybe_unused)
  687. {
  688. struct convert *c = container_of(tool, struct convert, tool);
  689. struct evsel_priv *priv = evsel->priv;
  690. struct ctf_writer *cw = &c->writer;
  691. struct ctf_stream *cs;
  692. struct bt_ctf_event_class *event_class;
  693. struct bt_ctf_event *event;
  694. int ret;
  695. unsigned long type = evsel->core.attr.sample_type;
  696. if (WARN_ONCE(!priv, "Failed to setup all events.\n"))
  697. return 0;
  698. if (perf_time__ranges_skip_sample(c->ptime_range, c->range_num, sample->time)) {
  699. ++c->skipped;
  700. return 0;
  701. }
  702. event_class = priv->event_class;
  703. /* update stats */
  704. c->events_count++;
  705. c->events_size += _event->header.size;
  706. pr_time2(sample->time, "sample %" PRIu64 "\n", c->events_count);
  707. event = bt_ctf_event_create(event_class);
  708. if (!event) {
  709. pr_err("Failed to create an CTF event\n");
  710. return -1;
  711. }
  712. bt_ctf_clock_set_time(cw->clock, sample->time);
  713. ret = add_generic_values(cw, event, evsel, sample);
  714. if (ret)
  715. return -1;
  716. if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
  717. ret = add_tracepoint_values(cw, event_class, event,
  718. evsel, sample);
  719. if (ret)
  720. return -1;
  721. }
  722. if (type & PERF_SAMPLE_CALLCHAIN) {
  723. ret = add_callchain_output_values(event_class,
  724. event, sample->callchain);
  725. if (ret)
  726. return -1;
  727. }
  728. if (evsel__is_bpf_output(evsel)) {
  729. ret = add_bpf_output_values(event_class, event, sample);
  730. if (ret)
  731. return -1;
  732. }
  733. cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel));
  734. if (cs) {
  735. if (is_flush_needed(cs))
  736. ctf_stream__flush(cs);
  737. cs->count++;
  738. bt_ctf_stream_append_event(cs->stream, event);
  739. }
  740. bt_ctf_event_put(event);
  741. return cs ? 0 : -1;
  742. }
  743. #define __NON_SAMPLE_SET_FIELD(_name, _type, _field) \
  744. do { \
  745. ret = value_set_##_type(cw, event, #_field, _event->_name._field);\
  746. if (ret) \
  747. return -1; \
  748. } while(0)
  749. #define __FUNC_PROCESS_NON_SAMPLE(_name, body) \
  750. static int process_##_name##_event(const struct perf_tool *tool, \
  751. union perf_event *_event, \
  752. struct perf_sample *sample, \
  753. struct machine *machine) \
  754. { \
  755. struct convert *c = container_of(tool, struct convert, tool);\
  756. struct ctf_writer *cw = &c->writer; \
  757. struct bt_ctf_event_class *event_class = cw->_name##_class;\
  758. struct bt_ctf_event *event; \
  759. struct ctf_stream *cs; \
  760. int ret; \
  761. \
  762. c->non_sample_count++; \
  763. c->events_size += _event->header.size; \
  764. event = bt_ctf_event_create(event_class); \
  765. if (!event) { \
  766. pr_err("Failed to create an CTF event\n"); \
  767. return -1; \
  768. } \
  769. \
  770. bt_ctf_clock_set_time(cw->clock, sample->time); \
  771. body \
  772. cs = ctf_stream(cw, 0); \
  773. if (cs) { \
  774. if (is_flush_needed(cs)) \
  775. ctf_stream__flush(cs); \
  776. \
  777. cs->count++; \
  778. bt_ctf_stream_append_event(cs->stream, event); \
  779. } \
  780. bt_ctf_event_put(event); \
  781. \
  782. return perf_event__process_##_name(tool, _event, sample, machine);\
  783. }
  784. __FUNC_PROCESS_NON_SAMPLE(comm,
  785. __NON_SAMPLE_SET_FIELD(comm, u32, pid);
  786. __NON_SAMPLE_SET_FIELD(comm, u32, tid);
  787. __NON_SAMPLE_SET_FIELD(comm, string, comm);
  788. )
  789. __FUNC_PROCESS_NON_SAMPLE(fork,
  790. __NON_SAMPLE_SET_FIELD(fork, u32, pid);
  791. __NON_SAMPLE_SET_FIELD(fork, u32, ppid);
  792. __NON_SAMPLE_SET_FIELD(fork, u32, tid);
  793. __NON_SAMPLE_SET_FIELD(fork, u32, ptid);
  794. __NON_SAMPLE_SET_FIELD(fork, u64, time);
  795. )
  796. __FUNC_PROCESS_NON_SAMPLE(exit,
  797. __NON_SAMPLE_SET_FIELD(fork, u32, pid);
  798. __NON_SAMPLE_SET_FIELD(fork, u32, ppid);
  799. __NON_SAMPLE_SET_FIELD(fork, u32, tid);
  800. __NON_SAMPLE_SET_FIELD(fork, u32, ptid);
  801. __NON_SAMPLE_SET_FIELD(fork, u64, time);
  802. )
  803. __FUNC_PROCESS_NON_SAMPLE(mmap,
  804. __NON_SAMPLE_SET_FIELD(mmap, u32, pid);
  805. __NON_SAMPLE_SET_FIELD(mmap, u32, tid);
  806. __NON_SAMPLE_SET_FIELD(mmap, u64_hex, start);
  807. __NON_SAMPLE_SET_FIELD(mmap, string, filename);
  808. )
  809. __FUNC_PROCESS_NON_SAMPLE(mmap2,
  810. __NON_SAMPLE_SET_FIELD(mmap2, u32, pid);
  811. __NON_SAMPLE_SET_FIELD(mmap2, u32, tid);
  812. __NON_SAMPLE_SET_FIELD(mmap2, u64_hex, start);
  813. __NON_SAMPLE_SET_FIELD(mmap2, string, filename);
  814. )
  815. #undef __NON_SAMPLE_SET_FIELD
  816. #undef __FUNC_PROCESS_NON_SAMPLE
  817. /* If dup < 0, add a prefix. Else, add _dupl_X suffix. */
  818. static char *change_name(char *name, char *orig_name, int dup)
  819. {
  820. char *new_name = NULL;
  821. size_t len;
  822. if (!name)
  823. name = orig_name;
  824. if (dup >= 10)
  825. goto out;
  826. /*
  827. * Add '_' prefix to potential keywork. According to
  828. * Mathieu Desnoyers (https://lore.kernel.org/lkml/1074266107.40857.1422045946295.JavaMail.zimbra@efficios.com),
  829. * further CTF spec updating may require us to use '$'.
  830. */
  831. if (dup < 0)
  832. len = strlen(name) + sizeof("_");
  833. else
  834. len = strlen(orig_name) + sizeof("_dupl_X");
  835. new_name = malloc(len);
  836. if (!new_name)
  837. goto out;
  838. if (dup < 0)
  839. snprintf(new_name, len, "_%s", name);
  840. else
  841. snprintf(new_name, len, "%s_dupl_%d", orig_name, dup);
  842. out:
  843. if (name != orig_name)
  844. free(name);
  845. return new_name;
  846. }
  847. static int event_class_add_field(struct bt_ctf_event_class *event_class,
  848. struct bt_ctf_field_type *type,
  849. struct tep_format_field *field)
  850. {
  851. struct bt_ctf_field_type *t = NULL;
  852. char *name;
  853. int dup = 1;
  854. int ret;
  855. /* alias was already assigned */
  856. if (field->alias != field->name)
  857. return bt_ctf_event_class_add_field(event_class, type,
  858. (char *)field->alias);
  859. name = field->name;
  860. /* If 'name' is a keywork, add prefix. */
  861. if (bt_ctf_validate_identifier(name))
  862. name = change_name(name, field->name, -1);
  863. if (!name) {
  864. pr_err("Failed to fix invalid identifier.");
  865. return -1;
  866. }
  867. while ((t = bt_ctf_event_class_get_field_by_name(event_class, name))) {
  868. bt_ctf_field_type_put(t);
  869. name = change_name(name, field->name, dup++);
  870. if (!name) {
  871. pr_err("Failed to create dup name for '%s'\n", field->name);
  872. return -1;
  873. }
  874. }
  875. ret = bt_ctf_event_class_add_field(event_class, type, name);
  876. if (!ret)
  877. field->alias = name;
  878. return ret;
  879. }
  880. static int add_tracepoint_fields_types(struct ctf_writer *cw,
  881. struct tep_format_field *fields,
  882. struct bt_ctf_event_class *event_class)
  883. {
  884. struct tep_format_field *field;
  885. int ret;
  886. for (field = fields; field; field = field->next) {
  887. struct bt_ctf_field_type *type;
  888. unsigned long flags = field->flags;
  889. pr2(" field '%s'\n", field->name);
  890. type = get_tracepoint_field_type(cw, field);
  891. if (!type)
  892. return -1;
  893. /*
  894. * A string is an array of chars. For this we use the string
  895. * type and don't care that it is an array. What we don't
  896. * support is an array of strings.
  897. */
  898. if (flags & TEP_FIELD_IS_STRING)
  899. flags &= ~TEP_FIELD_IS_ARRAY;
  900. if (flags & TEP_FIELD_IS_ARRAY)
  901. type = bt_ctf_field_type_array_create(type, field->arraylen);
  902. ret = event_class_add_field(event_class, type, field);
  903. if (flags & TEP_FIELD_IS_ARRAY)
  904. bt_ctf_field_type_put(type);
  905. if (ret) {
  906. pr_err("Failed to add field '%s': %d\n",
  907. field->name, ret);
  908. return -1;
  909. }
  910. }
  911. return 0;
  912. }
  913. static int add_tracepoint_types(struct ctf_writer *cw,
  914. struct evsel *evsel,
  915. struct bt_ctf_event_class *class)
  916. {
  917. const struct tep_event *tp_format = evsel__tp_format(evsel);
  918. struct tep_format_field *common_fields = tp_format ? tp_format->format.common_fields : NULL;
  919. struct tep_format_field *fields = tp_format ? tp_format->format.fields : NULL;
  920. int ret;
  921. ret = add_tracepoint_fields_types(cw, common_fields, class);
  922. if (!ret)
  923. ret = add_tracepoint_fields_types(cw, fields, class);
  924. return ret;
  925. }
  926. static int add_bpf_output_types(struct ctf_writer *cw,
  927. struct bt_ctf_event_class *class)
  928. {
  929. struct bt_ctf_field_type *len_type = cw->data.u32;
  930. struct bt_ctf_field_type *seq_base_type = cw->data.u32_hex;
  931. struct bt_ctf_field_type *seq_type;
  932. int ret;
  933. ret = bt_ctf_event_class_add_field(class, len_type, "raw_len");
  934. if (ret)
  935. return ret;
  936. seq_type = bt_ctf_field_type_sequence_create(seq_base_type, "raw_len");
  937. if (!seq_type)
  938. return -1;
  939. return bt_ctf_event_class_add_field(class, seq_type, "raw_data");
  940. }
  941. static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel,
  942. struct bt_ctf_event_class *event_class)
  943. {
  944. u64 type = evsel->core.attr.sample_type;
  945. /*
  946. * missing:
  947. * PERF_SAMPLE_TIME - not needed as we have it in
  948. * ctf event header
  949. * PERF_SAMPLE_READ - TODO
  950. * PERF_SAMPLE_CALLCHAIN - TODO
  951. * PERF_SAMPLE_RAW - tracepoint fields and BPF output
  952. * are handled separately
  953. * PERF_SAMPLE_BRANCH_STACK - TODO
  954. * PERF_SAMPLE_REGS_USER - TODO
  955. * PERF_SAMPLE_STACK_USER - TODO
  956. */
  957. #define ADD_FIELD(cl, t, n) \
  958. do { \
  959. pr2(" field '%s'\n", n); \
  960. if (bt_ctf_event_class_add_field(cl, t, n)) { \
  961. pr_err("Failed to add field '%s';\n", n); \
  962. return -1; \
  963. } \
  964. } while (0)
  965. if (type & PERF_SAMPLE_IP)
  966. ADD_FIELD(event_class, cw->data.u64_hex, "perf_ip");
  967. if (type & PERF_SAMPLE_TID) {
  968. ADD_FIELD(event_class, cw->data.s32, "perf_tid");
  969. ADD_FIELD(event_class, cw->data.s32, "perf_pid");
  970. }
  971. if ((type & PERF_SAMPLE_ID) ||
  972. (type & PERF_SAMPLE_IDENTIFIER))
  973. ADD_FIELD(event_class, cw->data.u64, "perf_id");
  974. if (type & PERF_SAMPLE_STREAM_ID)
  975. ADD_FIELD(event_class, cw->data.u64, "perf_stream_id");
  976. if (type & PERF_SAMPLE_PERIOD)
  977. ADD_FIELD(event_class, cw->data.u64, "perf_period");
  978. if (type & PERF_SAMPLE_WEIGHT)
  979. ADD_FIELD(event_class, cw->data.u64, "perf_weight");
  980. if (type & PERF_SAMPLE_DATA_SRC)
  981. ADD_FIELD(event_class, cw->data.u64, "perf_data_src");
  982. if (type & PERF_SAMPLE_TRANSACTION)
  983. ADD_FIELD(event_class, cw->data.u64, "perf_transaction");
  984. if (type & PERF_SAMPLE_CALLCHAIN) {
  985. ADD_FIELD(event_class, cw->data.u32, "perf_callchain_size");
  986. ADD_FIELD(event_class,
  987. bt_ctf_field_type_sequence_create(
  988. cw->data.u64_hex, "perf_callchain_size"),
  989. "perf_callchain");
  990. }
  991. #undef ADD_FIELD
  992. return 0;
  993. }
  994. static int add_event(struct ctf_writer *cw, struct evsel *evsel)
  995. {
  996. struct bt_ctf_event_class *event_class;
  997. struct evsel_priv *priv;
  998. const char *name = evsel__name(evsel);
  999. int ret;
  1000. pr("Adding event '%s' (type %d)\n", name, evsel->core.attr.type);
  1001. event_class = bt_ctf_event_class_create(name);
  1002. if (!event_class)
  1003. return -1;
  1004. ret = add_generic_types(cw, evsel, event_class);
  1005. if (ret)
  1006. goto err;
  1007. if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
  1008. ret = add_tracepoint_types(cw, evsel, event_class);
  1009. if (ret)
  1010. goto err;
  1011. }
  1012. if (evsel__is_bpf_output(evsel)) {
  1013. ret = add_bpf_output_types(cw, event_class);
  1014. if (ret)
  1015. goto err;
  1016. }
  1017. ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);
  1018. if (ret) {
  1019. pr("Failed to add event class into stream.\n");
  1020. goto err;
  1021. }
  1022. priv = malloc(sizeof(*priv));
  1023. if (!priv)
  1024. goto err;
  1025. priv->event_class = event_class;
  1026. evsel->priv = priv;
  1027. return 0;
  1028. err:
  1029. bt_ctf_event_class_put(event_class);
  1030. pr_err("Failed to add event '%s'.\n", name);
  1031. return -1;
  1032. }
  1033. static int setup_events(struct ctf_writer *cw, struct perf_session *session)
  1034. {
  1035. struct evlist *evlist = session->evlist;
  1036. struct evsel *evsel;
  1037. int ret;
  1038. evlist__for_each_entry(evlist, evsel) {
  1039. ret = add_event(cw, evsel);
  1040. if (ret)
  1041. return ret;
  1042. }
  1043. return 0;
  1044. }
  1045. #define __NON_SAMPLE_ADD_FIELD(t, n) \
  1046. do { \
  1047. pr2(" field '%s'\n", #n); \
  1048. if (bt_ctf_event_class_add_field(event_class, cw->data.t, #n)) {\
  1049. pr_err("Failed to add field '%s';\n", #n);\
  1050. return -1; \
  1051. } \
  1052. } while(0)
  1053. #define __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(_name, body) \
  1054. static int add_##_name##_event(struct ctf_writer *cw) \
  1055. { \
  1056. struct bt_ctf_event_class *event_class; \
  1057. int ret; \
  1058. \
  1059. pr("Adding "#_name" event\n"); \
  1060. event_class = bt_ctf_event_class_create("perf_" #_name);\
  1061. if (!event_class) \
  1062. return -1; \
  1063. body \
  1064. \
  1065. ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);\
  1066. if (ret) { \
  1067. pr("Failed to add event class '"#_name"' into stream.\n");\
  1068. return ret; \
  1069. } \
  1070. \
  1071. cw->_name##_class = event_class; \
  1072. bt_ctf_event_class_put(event_class); \
  1073. return 0; \
  1074. }
  1075. __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(comm,
  1076. __NON_SAMPLE_ADD_FIELD(u32, pid);
  1077. __NON_SAMPLE_ADD_FIELD(u32, tid);
  1078. __NON_SAMPLE_ADD_FIELD(string, comm);
  1079. )
  1080. __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(fork,
  1081. __NON_SAMPLE_ADD_FIELD(u32, pid);
  1082. __NON_SAMPLE_ADD_FIELD(u32, ppid);
  1083. __NON_SAMPLE_ADD_FIELD(u32, tid);
  1084. __NON_SAMPLE_ADD_FIELD(u32, ptid);
  1085. __NON_SAMPLE_ADD_FIELD(u64, time);
  1086. )
  1087. __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(exit,
  1088. __NON_SAMPLE_ADD_FIELD(u32, pid);
  1089. __NON_SAMPLE_ADD_FIELD(u32, ppid);
  1090. __NON_SAMPLE_ADD_FIELD(u32, tid);
  1091. __NON_SAMPLE_ADD_FIELD(u32, ptid);
  1092. __NON_SAMPLE_ADD_FIELD(u64, time);
  1093. )
  1094. __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap,
  1095. __NON_SAMPLE_ADD_FIELD(u32, pid);
  1096. __NON_SAMPLE_ADD_FIELD(u32, tid);
  1097. __NON_SAMPLE_ADD_FIELD(u64_hex, start);
  1098. __NON_SAMPLE_ADD_FIELD(string, filename);
  1099. )
  1100. __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap2,
  1101. __NON_SAMPLE_ADD_FIELD(u32, pid);
  1102. __NON_SAMPLE_ADD_FIELD(u32, tid);
  1103. __NON_SAMPLE_ADD_FIELD(u64_hex, start);
  1104. __NON_SAMPLE_ADD_FIELD(string, filename);
  1105. )
  1106. #undef __NON_SAMPLE_ADD_FIELD
  1107. #undef __FUNC_ADD_NON_SAMPLE_EVENT_CLASS
  1108. static int setup_non_sample_events(struct ctf_writer *cw,
  1109. struct perf_session *session __maybe_unused)
  1110. {
  1111. int ret;
  1112. ret = add_comm_event(cw);
  1113. if (ret)
  1114. return ret;
  1115. ret = add_exit_event(cw);
  1116. if (ret)
  1117. return ret;
  1118. ret = add_fork_event(cw);
  1119. if (ret)
  1120. return ret;
  1121. ret = add_mmap_event(cw);
  1122. if (ret)
  1123. return ret;
  1124. ret = add_mmap2_event(cw);
  1125. if (ret)
  1126. return ret;
  1127. return 0;
  1128. }
  1129. static void cleanup_events(struct perf_session *session)
  1130. {
  1131. struct evlist *evlist = session->evlist;
  1132. struct evsel *evsel;
  1133. evlist__for_each_entry(evlist, evsel) {
  1134. struct evsel_priv *priv;
  1135. priv = evsel->priv;
  1136. if (priv)
  1137. bt_ctf_event_class_put(priv->event_class);
  1138. zfree(&evsel->priv);
  1139. }
  1140. evlist__delete(evlist);
  1141. session->evlist = NULL;
  1142. }
  1143. static int setup_streams(struct ctf_writer *cw, struct perf_session *session)
  1144. {
  1145. struct ctf_stream **stream;
  1146. struct perf_env *env = perf_session__env(session);
  1147. int ncpus;
  1148. /*
  1149. * Try to get the number of cpus used in the data file,
  1150. * if not present fallback to the MAX_CPUS.
  1151. */
  1152. ncpus = env->nr_cpus_avail ?: MAX_CPUS;
  1153. stream = zalloc(sizeof(*stream) * ncpus);
  1154. if (!stream) {
  1155. pr_err("Failed to allocate streams.\n");
  1156. return -ENOMEM;
  1157. }
  1158. cw->stream = stream;
  1159. cw->stream_cnt = ncpus;
  1160. return 0;
  1161. }
  1162. static void free_streams(struct ctf_writer *cw)
  1163. {
  1164. int cpu;
  1165. for (cpu = 0; cpu < cw->stream_cnt; cpu++)
  1166. ctf_stream__delete(cw->stream[cpu]);
  1167. zfree(&cw->stream);
  1168. }
  1169. static int ctf_writer__setup_env(struct ctf_writer *cw,
  1170. struct perf_session *session)
  1171. {
  1172. struct perf_env *env = perf_session__env(session);
  1173. struct bt_ctf_writer *writer = cw->writer;
  1174. #define ADD(__n, __v) \
  1175. do { \
  1176. if (__v && bt_ctf_writer_add_environment_field(writer, __n, __v)) \
  1177. return -1; \
  1178. } while (0)
  1179. ADD("host", env->hostname);
  1180. ADD("sysname", "Linux");
  1181. ADD("release", env->os_release);
  1182. ADD("version", env->version);
  1183. ADD("machine", env->arch);
  1184. ADD("domain", "kernel");
  1185. ADD("tracer_name", "perf");
  1186. #undef ADD
  1187. return 0;
  1188. }
  1189. static int process_feature_event(const struct perf_tool *tool,
  1190. struct perf_session *session,
  1191. union perf_event *event)
  1192. {
  1193. struct convert *c = container_of(tool, struct convert, tool);
  1194. struct ctf_writer *cw = &c->writer;
  1195. struct perf_record_header_feature *fe = &event->feat;
  1196. if (event->feat.feat_id < HEADER_LAST_FEATURE) {
  1197. int ret = perf_event__process_feature(session, event);
  1198. if (ret)
  1199. return ret;
  1200. }
  1201. switch (fe->feat_id) {
  1202. case HEADER_HOSTNAME:
  1203. if (session->header.env.hostname) {
  1204. return bt_ctf_writer_add_environment_field(cw->writer, "host",
  1205. session->header.env.hostname);
  1206. }
  1207. break;
  1208. case HEADER_OSRELEASE:
  1209. if (session->header.env.os_release) {
  1210. return bt_ctf_writer_add_environment_field(cw->writer, "release",
  1211. session->header.env.os_release);
  1212. }
  1213. break;
  1214. case HEADER_VERSION:
  1215. if (session->header.env.version) {
  1216. return bt_ctf_writer_add_environment_field(cw->writer, "version",
  1217. session->header.env.version);
  1218. }
  1219. break;
  1220. case HEADER_ARCH:
  1221. if (session->header.env.arch) {
  1222. return bt_ctf_writer_add_environment_field(cw->writer, "machine",
  1223. session->header.env.arch);
  1224. }
  1225. break;
  1226. default:
  1227. break;
  1228. }
  1229. return 0;
  1230. }
  1231. static int ctf_writer__setup_clock(struct ctf_writer *cw,
  1232. struct perf_session *session,
  1233. bool tod)
  1234. {
  1235. struct bt_ctf_clock *clock = cw->clock;
  1236. const char *desc = "perf clock";
  1237. int64_t offset = 0;
  1238. if (tod) {
  1239. struct perf_env *env = perf_session__env(session);
  1240. if (!env->clock.enabled) {
  1241. pr_err("Can't provide --tod time, missing clock data. "
  1242. "Please record with -k/--clockid option.\n");
  1243. return -1;
  1244. }
  1245. desc = clockid_name(env->clock.clockid);
  1246. offset = env->clock.tod_ns - env->clock.clockid_ns;
  1247. }
  1248. #define SET(__n, __v) \
  1249. do { \
  1250. if (bt_ctf_clock_set_##__n(clock, __v)) \
  1251. return -1; \
  1252. } while (0)
  1253. SET(frequency, 1000000000);
  1254. SET(offset, offset);
  1255. SET(description, desc);
  1256. SET(precision, 10);
  1257. SET(is_absolute, 0);
  1258. #undef SET
  1259. return 0;
  1260. }
  1261. static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex)
  1262. {
  1263. struct bt_ctf_field_type *type;
  1264. type = bt_ctf_field_type_integer_create(size);
  1265. if (!type)
  1266. return NULL;
  1267. if (sign &&
  1268. bt_ctf_field_type_integer_set_signed(type, 1))
  1269. goto err;
  1270. if (hex &&
  1271. bt_ctf_field_type_integer_set_base(type, BT_CTF_INTEGER_BASE_HEXADECIMAL))
  1272. goto err;
  1273. #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  1274. bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_BIG_ENDIAN);
  1275. #else
  1276. bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
  1277. #endif
  1278. pr2("Created type: INTEGER %d-bit %ssigned %s\n",
  1279. size, sign ? "un" : "", hex ? "hex" : "");
  1280. return type;
  1281. err:
  1282. bt_ctf_field_type_put(type);
  1283. return NULL;
  1284. }
  1285. static void ctf_writer__cleanup_data(struct ctf_writer *cw)
  1286. {
  1287. unsigned int i;
  1288. for (i = 0; i < ARRAY_SIZE(cw->data.array); i++)
  1289. bt_ctf_field_type_put(cw->data.array[i]);
  1290. }
  1291. static int ctf_writer__init_data(struct ctf_writer *cw)
  1292. {
  1293. #define CREATE_INT_TYPE(type, size, sign, hex) \
  1294. do { \
  1295. (type) = create_int_type(size, sign, hex); \
  1296. if (!(type)) \
  1297. goto err; \
  1298. } while (0)
  1299. CREATE_INT_TYPE(cw->data.s64, 64, true, false);
  1300. CREATE_INT_TYPE(cw->data.u64, 64, false, false);
  1301. CREATE_INT_TYPE(cw->data.s32, 32, true, false);
  1302. CREATE_INT_TYPE(cw->data.u32, 32, false, false);
  1303. CREATE_INT_TYPE(cw->data.u32_hex, 32, false, true);
  1304. CREATE_INT_TYPE(cw->data.u64_hex, 64, false, true);
  1305. cw->data.string = bt_ctf_field_type_string_create();
  1306. if (cw->data.string)
  1307. return 0;
  1308. err:
  1309. ctf_writer__cleanup_data(cw);
  1310. pr_err("Failed to create data types.\n");
  1311. return -1;
  1312. }
  1313. static void ctf_writer__cleanup(struct ctf_writer *cw)
  1314. {
  1315. ctf_writer__cleanup_data(cw);
  1316. bt_ctf_clock_put(cw->clock);
  1317. free_streams(cw);
  1318. bt_ctf_stream_class_put(cw->stream_class);
  1319. bt_ctf_writer_put(cw->writer);
  1320. /* and NULL all the pointers */
  1321. memset(cw, 0, sizeof(*cw));
  1322. }
  1323. static int ctf_writer__init(struct ctf_writer *cw, const char *path,
  1324. struct perf_session *session, bool tod)
  1325. {
  1326. struct bt_ctf_writer *writer;
  1327. struct bt_ctf_stream_class *stream_class;
  1328. struct bt_ctf_clock *clock;
  1329. struct bt_ctf_field_type *pkt_ctx_type;
  1330. int ret;
  1331. /* CTF writer */
  1332. writer = bt_ctf_writer_create(path);
  1333. if (!writer)
  1334. goto err;
  1335. cw->writer = writer;
  1336. /* CTF clock */
  1337. clock = bt_ctf_clock_create("perf_clock");
  1338. if (!clock) {
  1339. pr("Failed to create CTF clock.\n");
  1340. goto err_cleanup;
  1341. }
  1342. cw->clock = clock;
  1343. if (ctf_writer__setup_clock(cw, session, tod)) {
  1344. pr("Failed to setup CTF clock.\n");
  1345. goto err_cleanup;
  1346. }
  1347. /* CTF stream class */
  1348. stream_class = bt_ctf_stream_class_create("perf_stream");
  1349. if (!stream_class) {
  1350. pr("Failed to create CTF stream class.\n");
  1351. goto err_cleanup;
  1352. }
  1353. cw->stream_class = stream_class;
  1354. /* CTF clock stream setup */
  1355. if (bt_ctf_stream_class_set_clock(stream_class, clock)) {
  1356. pr("Failed to assign CTF clock to stream class.\n");
  1357. goto err_cleanup;
  1358. }
  1359. if (ctf_writer__init_data(cw))
  1360. goto err_cleanup;
  1361. /* Add cpu_id for packet context */
  1362. pkt_ctx_type = bt_ctf_stream_class_get_packet_context_type(stream_class);
  1363. if (!pkt_ctx_type)
  1364. goto err_cleanup;
  1365. ret = bt_ctf_field_type_structure_add_field(pkt_ctx_type, cw->data.u32, "cpu_id");
  1366. bt_ctf_field_type_put(pkt_ctx_type);
  1367. if (ret)
  1368. goto err_cleanup;
  1369. /* CTF clock writer setup */
  1370. if (bt_ctf_writer_add_clock(writer, clock)) {
  1371. pr("Failed to assign CTF clock to writer.\n");
  1372. goto err_cleanup;
  1373. }
  1374. return 0;
  1375. err_cleanup:
  1376. ctf_writer__cleanup(cw);
  1377. err:
  1378. pr_err("Failed to setup CTF writer.\n");
  1379. return -1;
  1380. }
  1381. static int ctf_writer__flush_streams(struct ctf_writer *cw)
  1382. {
  1383. int cpu, ret = 0;
  1384. for (cpu = 0; cpu < cw->stream_cnt && !ret; cpu++)
  1385. ret = ctf_stream__flush(cw->stream[cpu]);
  1386. return ret;
  1387. }
  1388. static int convert__config(const char *var, const char *value, void *cb)
  1389. {
  1390. struct convert *c = cb;
  1391. if (!strcmp(var, "convert.queue-size"))
  1392. return perf_config_u64(&c->queue_size, var, value);
  1393. return 0;
  1394. }
  1395. int bt_convert__perf2ctf(const char *input, const char *path,
  1396. struct perf_data_convert_opts *opts)
  1397. {
  1398. struct perf_session *session;
  1399. struct perf_data data = {
  1400. .path = input,
  1401. .mode = PERF_DATA_MODE_READ,
  1402. .force = opts->force,
  1403. };
  1404. struct convert c = {};
  1405. struct ctf_writer *cw = &c.writer;
  1406. int err;
  1407. perf_tool__init(&c.tool, /*ordered_events=*/true);
  1408. c.tool.sample = process_sample_event;
  1409. c.tool.mmap = perf_event__process_mmap;
  1410. c.tool.mmap2 = perf_event__process_mmap2;
  1411. c.tool.comm = perf_event__process_comm;
  1412. c.tool.exit = perf_event__process_exit;
  1413. c.tool.fork = perf_event__process_fork;
  1414. c.tool.lost = perf_event__process_lost;
  1415. c.tool.tracing_data = perf_event__process_tracing_data;
  1416. c.tool.build_id = perf_event__process_build_id;
  1417. c.tool.namespaces = perf_event__process_namespaces;
  1418. c.tool.attr = perf_event__process_attr;
  1419. c.tool.feature = process_feature_event;
  1420. c.tool.ordering_requires_timestamps = true;
  1421. if (opts->all) {
  1422. c.tool.comm = process_comm_event;
  1423. c.tool.exit = process_exit_event;
  1424. c.tool.fork = process_fork_event;
  1425. c.tool.mmap = process_mmap_event;
  1426. c.tool.mmap2 = process_mmap2_event;
  1427. }
  1428. err = perf_config(convert__config, &c);
  1429. if (err)
  1430. return err;
  1431. err = -1;
  1432. /* perf.data session */
  1433. session = perf_session__new(&data, &c.tool);
  1434. if (IS_ERR(session))
  1435. return PTR_ERR(session);
  1436. if (opts->time_str) {
  1437. err = perf_time__parse_for_ranges(opts->time_str, session,
  1438. &c.ptime_range,
  1439. &c.range_size,
  1440. &c.range_num);
  1441. if (err < 0)
  1442. goto free_session;
  1443. }
  1444. /* CTF writer */
  1445. if (ctf_writer__init(cw, path, session, opts->tod))
  1446. goto free_session;
  1447. if (c.queue_size) {
  1448. ordered_events__set_alloc_size(&session->ordered_events,
  1449. c.queue_size);
  1450. }
  1451. /* CTF writer env/clock setup */
  1452. if (ctf_writer__setup_env(cw, session))
  1453. goto free_writer;
  1454. /* CTF events setup */
  1455. if (setup_events(cw, session))
  1456. goto free_writer;
  1457. if (opts->all && setup_non_sample_events(cw, session))
  1458. goto free_writer;
  1459. if (setup_streams(cw, session))
  1460. goto free_writer;
  1461. err = perf_session__process_events(session);
  1462. if (!err)
  1463. err = ctf_writer__flush_streams(cw);
  1464. else
  1465. pr_err("Error during conversion.\n");
  1466. fprintf(stderr, "[ perf data convert: Converted '%s' into CTF data '%s' ]\n",
  1467. data.path, path);
  1468. fprintf(stderr, "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples",
  1469. (double) c.events_size / 1024.0 / 1024.0,
  1470. c.events_count);
  1471. if (!c.non_sample_count)
  1472. fprintf(stderr, ") ]\n");
  1473. else
  1474. fprintf(stderr, ", %" PRIu64 " non-samples) ]\n", c.non_sample_count);
  1475. if (c.skipped) {
  1476. fprintf(stderr, "[ perf data convert: Skipped %" PRIu64 " samples ]\n",
  1477. c.skipped);
  1478. }
  1479. if (c.ptime_range)
  1480. zfree(&c.ptime_range);
  1481. cleanup_events(session);
  1482. perf_session__delete(session);
  1483. ctf_writer__cleanup(cw);
  1484. return err;
  1485. free_writer:
  1486. ctf_writer__cleanup(cw);
  1487. free_session:
  1488. if (c.ptime_range)
  1489. zfree(&c.ptime_range);
  1490. perf_session__delete(session);
  1491. pr_err("Error during conversion setup.\n");
  1492. return err;
  1493. }