builtin-inject.c 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * builtin-inject.c
  4. *
  5. * Builtin inject command: Examine the live mode (stdin) event stream
  6. * and repipe it to stdout while optionally injecting additional
  7. * events into it.
  8. */
  9. #include "builtin.h"
  10. #include "util/color.h"
  11. #include "util/dso.h"
  12. #include "util/vdso.h"
  13. #include "util/evlist.h"
  14. #include "util/evsel.h"
  15. #include "util/map.h"
  16. #include "util/session.h"
  17. #include "util/tool.h"
  18. #include "util/debug.h"
  19. #include "util/build-id.h"
  20. #include "util/data.h"
  21. #include "util/auxtrace.h"
  22. #include "util/jit.h"
  23. #include "util/string2.h"
  24. #include "util/symbol.h"
  25. #include "util/synthetic-events.h"
  26. #include "util/thread.h"
  27. #include "util/namespaces.h"
  28. #include "util/util.h"
  29. #include "util/tsc.h"
  30. #include <internal/lib.h>
  31. #include <linux/err.h>
  32. #include <subcmd/parse-options.h>
  33. #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
  34. #include <linux/list.h>
  35. #include <linux/string.h>
  36. #include <linux/zalloc.h>
  37. #include <linux/hash.h>
  38. #include <ctype.h>
  39. #include <errno.h>
  40. #include <signal.h>
  41. #include <inttypes.h>
  42. struct guest_event {
  43. struct perf_sample sample;
  44. union perf_event *event;
  45. char event_buf[PERF_SAMPLE_MAX_SIZE];
  46. };
  47. struct guest_id {
  48. /* hlist_node must be first, see free_hlist() */
  49. struct hlist_node node;
  50. u64 id;
  51. u64 host_id;
  52. u32 vcpu;
  53. };
  54. struct guest_tid {
  55. /* hlist_node must be first, see free_hlist() */
  56. struct hlist_node node;
  57. /* Thread ID of QEMU thread */
  58. u32 tid;
  59. u32 vcpu;
  60. };
  61. struct guest_vcpu {
  62. /* Current host CPU */
  63. u32 cpu;
  64. /* Thread ID of QEMU thread */
  65. u32 tid;
  66. };
  67. struct guest_session {
  68. char *perf_data_file;
  69. u32 machine_pid;
  70. u64 time_offset;
  71. double time_scale;
  72. struct perf_tool tool;
  73. struct perf_data data;
  74. struct perf_session *session;
  75. char *tmp_file_name;
  76. int tmp_fd;
  77. struct perf_tsc_conversion host_tc;
  78. struct perf_tsc_conversion guest_tc;
  79. bool copy_kcore_dir;
  80. bool have_tc;
  81. bool fetched;
  82. bool ready;
  83. u16 dflt_id_hdr_size;
  84. u64 dflt_id;
  85. u64 highest_id;
  86. /* Array of guest_vcpu */
  87. struct guest_vcpu *vcpu;
  88. size_t vcpu_cnt;
  89. /* Hash table for guest_id */
  90. struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
  91. /* Hash table for guest_tid */
  92. struct hlist_head tids[PERF_EVLIST__HLIST_SIZE];
  93. /* Place to stash next guest event */
  94. struct guest_event ev;
  95. };
  96. struct perf_inject {
  97. struct perf_tool tool;
  98. struct perf_session *session;
  99. bool build_ids;
  100. bool build_id_all;
  101. bool sched_stat;
  102. bool have_auxtrace;
  103. bool strip;
  104. bool jit_mode;
  105. bool in_place_update;
  106. bool in_place_update_dry_run;
  107. bool is_pipe;
  108. bool copy_kcore_dir;
  109. const char *input_name;
  110. struct perf_data output;
  111. u64 bytes_written;
  112. u64 aux_id;
  113. struct list_head samples;
  114. struct itrace_synth_opts itrace_synth_opts;
  115. char event_copy[PERF_SAMPLE_MAX_SIZE];
  116. struct perf_file_section secs[HEADER_FEAT_BITS];
  117. struct guest_session guest_session;
  118. struct strlist *known_build_ids;
  119. };
  120. struct event_entry {
  121. struct list_head node;
  122. u32 tid;
  123. union perf_event event[];
  124. };
  125. static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
  126. struct machine *machine, u8 cpumode, u32 flags);
  127. static int output_bytes(struct perf_inject *inject, void *buf, size_t sz)
  128. {
  129. ssize_t size;
  130. size = perf_data__write(&inject->output, buf, sz);
  131. if (size < 0)
  132. return -errno;
  133. inject->bytes_written += size;
  134. return 0;
  135. }
  136. static int perf_event__repipe_synth(struct perf_tool *tool,
  137. union perf_event *event)
  138. {
  139. struct perf_inject *inject = container_of(tool, struct perf_inject,
  140. tool);
  141. return output_bytes(inject, event, event->header.size);
  142. }
  143. static int perf_event__repipe_oe_synth(struct perf_tool *tool,
  144. union perf_event *event,
  145. struct ordered_events *oe __maybe_unused)
  146. {
  147. return perf_event__repipe_synth(tool, event);
  148. }
  149. #ifdef HAVE_JITDUMP
  150. static int perf_event__drop_oe(struct perf_tool *tool __maybe_unused,
  151. union perf_event *event __maybe_unused,
  152. struct ordered_events *oe __maybe_unused)
  153. {
  154. return 0;
  155. }
  156. #endif
  157. static int perf_event__repipe_op2_synth(struct perf_session *session,
  158. union perf_event *event)
  159. {
  160. return perf_event__repipe_synth(session->tool, event);
  161. }
  162. static int perf_event__repipe_op4_synth(struct perf_session *session,
  163. union perf_event *event,
  164. u64 data __maybe_unused,
  165. const char *str __maybe_unused)
  166. {
  167. return perf_event__repipe_synth(session->tool, event);
  168. }
  169. static int perf_event__repipe_attr(struct perf_tool *tool,
  170. union perf_event *event,
  171. struct evlist **pevlist)
  172. {
  173. struct perf_inject *inject = container_of(tool, struct perf_inject,
  174. tool);
  175. int ret;
  176. ret = perf_event__process_attr(tool, event, pevlist);
  177. if (ret)
  178. return ret;
  179. if (!inject->is_pipe)
  180. return 0;
  181. return perf_event__repipe_synth(tool, event);
  182. }
  183. static int perf_event__repipe_event_update(struct perf_tool *tool,
  184. union perf_event *event,
  185. struct evlist **pevlist __maybe_unused)
  186. {
  187. return perf_event__repipe_synth(tool, event);
  188. }
  189. #ifdef HAVE_AUXTRACE_SUPPORT
  190. static int copy_bytes(struct perf_inject *inject, struct perf_data *data, off_t size)
  191. {
  192. char buf[4096];
  193. ssize_t ssz;
  194. int ret;
  195. while (size > 0) {
  196. ssz = perf_data__read(data, buf, min(size, (off_t)sizeof(buf)));
  197. if (ssz < 0)
  198. return -errno;
  199. ret = output_bytes(inject, buf, ssz);
  200. if (ret)
  201. return ret;
  202. size -= ssz;
  203. }
  204. return 0;
  205. }
  206. static s64 perf_event__repipe_auxtrace(struct perf_session *session,
  207. union perf_event *event)
  208. {
  209. struct perf_tool *tool = session->tool;
  210. struct perf_inject *inject = container_of(tool, struct perf_inject,
  211. tool);
  212. int ret;
  213. inject->have_auxtrace = true;
  214. if (!inject->output.is_pipe) {
  215. off_t offset;
  216. offset = lseek(inject->output.file.fd, 0, SEEK_CUR);
  217. if (offset == -1)
  218. return -errno;
  219. ret = auxtrace_index__auxtrace_event(&session->auxtrace_index,
  220. event, offset);
  221. if (ret < 0)
  222. return ret;
  223. }
  224. if (perf_data__is_pipe(session->data) || !session->one_mmap) {
  225. ret = output_bytes(inject, event, event->header.size);
  226. if (ret < 0)
  227. return ret;
  228. ret = copy_bytes(inject, session->data,
  229. event->auxtrace.size);
  230. } else {
  231. ret = output_bytes(inject, event,
  232. event->header.size + event->auxtrace.size);
  233. }
  234. if (ret < 0)
  235. return ret;
  236. return event->auxtrace.size;
  237. }
  238. #else
  239. static s64
  240. perf_event__repipe_auxtrace(struct perf_session *session __maybe_unused,
  241. union perf_event *event __maybe_unused)
  242. {
  243. pr_err("AUX area tracing not supported\n");
  244. return -EINVAL;
  245. }
  246. #endif
  247. static int perf_event__repipe(struct perf_tool *tool,
  248. union perf_event *event,
  249. struct perf_sample *sample __maybe_unused,
  250. struct machine *machine __maybe_unused)
  251. {
  252. return perf_event__repipe_synth(tool, event);
  253. }
  254. static int perf_event__drop(struct perf_tool *tool __maybe_unused,
  255. union perf_event *event __maybe_unused,
  256. struct perf_sample *sample __maybe_unused,
  257. struct machine *machine __maybe_unused)
  258. {
  259. return 0;
  260. }
  261. static int perf_event__drop_aux(struct perf_tool *tool,
  262. union perf_event *event __maybe_unused,
  263. struct perf_sample *sample,
  264. struct machine *machine __maybe_unused)
  265. {
  266. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  267. if (!inject->aux_id)
  268. inject->aux_id = sample->id;
  269. return 0;
  270. }
  271. static union perf_event *
  272. perf_inject__cut_auxtrace_sample(struct perf_inject *inject,
  273. union perf_event *event,
  274. struct perf_sample *sample)
  275. {
  276. size_t sz1 = sample->aux_sample.data - (void *)event;
  277. size_t sz2 = event->header.size - sample->aux_sample.size - sz1;
  278. union perf_event *ev = (union perf_event *)inject->event_copy;
  279. if (sz1 > event->header.size || sz2 > event->header.size ||
  280. sz1 + sz2 > event->header.size ||
  281. sz1 < sizeof(struct perf_event_header) + sizeof(u64))
  282. return event;
  283. memcpy(ev, event, sz1);
  284. memcpy((void *)ev + sz1, (void *)event + event->header.size - sz2, sz2);
  285. ev->header.size = sz1 + sz2;
  286. ((u64 *)((void *)ev + sz1))[-1] = 0;
  287. return ev;
  288. }
  289. typedef int (*inject_handler)(struct perf_tool *tool,
  290. union perf_event *event,
  291. struct perf_sample *sample,
  292. struct evsel *evsel,
  293. struct machine *machine);
  294. static int perf_event__repipe_sample(struct perf_tool *tool,
  295. union perf_event *event,
  296. struct perf_sample *sample,
  297. struct evsel *evsel,
  298. struct machine *machine)
  299. {
  300. struct perf_inject *inject = container_of(tool, struct perf_inject,
  301. tool);
  302. if (evsel && evsel->handler) {
  303. inject_handler f = evsel->handler;
  304. return f(tool, event, sample, evsel, machine);
  305. }
  306. build_id__mark_dso_hit(tool, event, sample, evsel, machine);
  307. if (inject->itrace_synth_opts.set && sample->aux_sample.size)
  308. event = perf_inject__cut_auxtrace_sample(inject, event, sample);
  309. return perf_event__repipe_synth(tool, event);
  310. }
  311. static int perf_event__repipe_mmap(struct perf_tool *tool,
  312. union perf_event *event,
  313. struct perf_sample *sample,
  314. struct machine *machine)
  315. {
  316. int err;
  317. err = perf_event__process_mmap(tool, event, sample, machine);
  318. perf_event__repipe(tool, event, sample, machine);
  319. return err;
  320. }
  321. #ifdef HAVE_JITDUMP
  322. static int perf_event__jit_repipe_mmap(struct perf_tool *tool,
  323. union perf_event *event,
  324. struct perf_sample *sample,
  325. struct machine *machine)
  326. {
  327. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  328. u64 n = 0;
  329. int ret;
  330. /*
  331. * if jit marker, then inject jit mmaps and generate ELF images
  332. */
  333. ret = jit_process(inject->session, &inject->output, machine,
  334. event->mmap.filename, event->mmap.pid, event->mmap.tid, &n);
  335. if (ret < 0)
  336. return ret;
  337. if (ret) {
  338. inject->bytes_written += n;
  339. return 0;
  340. }
  341. return perf_event__repipe_mmap(tool, event, sample, machine);
  342. }
  343. #endif
  344. static struct dso *findnew_dso(int pid, int tid, const char *filename,
  345. struct dso_id *id, struct machine *machine)
  346. {
  347. struct thread *thread;
  348. struct nsinfo *nsi = NULL;
  349. struct nsinfo *nnsi;
  350. struct dso *dso;
  351. bool vdso;
  352. thread = machine__findnew_thread(machine, pid, tid);
  353. if (thread == NULL) {
  354. pr_err("cannot find or create a task %d/%d.\n", tid, pid);
  355. return NULL;
  356. }
  357. vdso = is_vdso_map(filename);
  358. nsi = nsinfo__get(thread->nsinfo);
  359. if (vdso) {
  360. /* The vdso maps are always on the host and not the
  361. * container. Ensure that we don't use setns to look
  362. * them up.
  363. */
  364. nnsi = nsinfo__copy(nsi);
  365. if (nnsi) {
  366. nsinfo__put(nsi);
  367. nsinfo__clear_need_setns(nnsi);
  368. nsi = nnsi;
  369. }
  370. dso = machine__findnew_vdso(machine, thread);
  371. } else {
  372. dso = machine__findnew_dso_id(machine, filename, id);
  373. }
  374. if (dso) {
  375. mutex_lock(&dso->lock);
  376. nsinfo__put(dso->nsinfo);
  377. dso->nsinfo = nsi;
  378. mutex_unlock(&dso->lock);
  379. } else
  380. nsinfo__put(nsi);
  381. thread__put(thread);
  382. return dso;
  383. }
  384. static int perf_event__repipe_buildid_mmap(struct perf_tool *tool,
  385. union perf_event *event,
  386. struct perf_sample *sample,
  387. struct machine *machine)
  388. {
  389. struct dso *dso;
  390. dso = findnew_dso(event->mmap.pid, event->mmap.tid,
  391. event->mmap.filename, NULL, machine);
  392. if (dso && !dso->hit) {
  393. dso->hit = 1;
  394. dso__inject_build_id(dso, tool, machine, sample->cpumode, 0);
  395. }
  396. dso__put(dso);
  397. return perf_event__repipe(tool, event, sample, machine);
  398. }
  399. static int perf_event__repipe_mmap2(struct perf_tool *tool,
  400. union perf_event *event,
  401. struct perf_sample *sample,
  402. struct machine *machine)
  403. {
  404. int err;
  405. err = perf_event__process_mmap2(tool, event, sample, machine);
  406. perf_event__repipe(tool, event, sample, machine);
  407. if (event->header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) {
  408. struct dso *dso;
  409. dso = findnew_dso(event->mmap2.pid, event->mmap2.tid,
  410. event->mmap2.filename, NULL, machine);
  411. if (dso) {
  412. /* mark it not to inject build-id */
  413. dso->hit = 1;
  414. }
  415. dso__put(dso);
  416. }
  417. return err;
  418. }
  419. #ifdef HAVE_JITDUMP
  420. static int perf_event__jit_repipe_mmap2(struct perf_tool *tool,
  421. union perf_event *event,
  422. struct perf_sample *sample,
  423. struct machine *machine)
  424. {
  425. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  426. u64 n = 0;
  427. int ret;
  428. /*
  429. * if jit marker, then inject jit mmaps and generate ELF images
  430. */
  431. ret = jit_process(inject->session, &inject->output, machine,
  432. event->mmap2.filename, event->mmap2.pid, event->mmap2.tid, &n);
  433. if (ret < 0)
  434. return ret;
  435. if (ret) {
  436. inject->bytes_written += n;
  437. return 0;
  438. }
  439. return perf_event__repipe_mmap2(tool, event, sample, machine);
  440. }
  441. #endif
  442. static int perf_event__repipe_buildid_mmap2(struct perf_tool *tool,
  443. union perf_event *event,
  444. struct perf_sample *sample,
  445. struct machine *machine)
  446. {
  447. struct dso_id dso_id = {
  448. .maj = event->mmap2.maj,
  449. .min = event->mmap2.min,
  450. .ino = event->mmap2.ino,
  451. .ino_generation = event->mmap2.ino_generation,
  452. };
  453. struct dso *dso;
  454. if (event->header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) {
  455. /* cannot use dso_id since it'd have invalid info */
  456. dso = findnew_dso(event->mmap2.pid, event->mmap2.tid,
  457. event->mmap2.filename, NULL, machine);
  458. if (dso) {
  459. /* mark it not to inject build-id */
  460. dso->hit = 1;
  461. }
  462. dso__put(dso);
  463. perf_event__repipe(tool, event, sample, machine);
  464. return 0;
  465. }
  466. dso = findnew_dso(event->mmap2.pid, event->mmap2.tid,
  467. event->mmap2.filename, &dso_id, machine);
  468. if (dso && !dso->hit) {
  469. dso->hit = 1;
  470. dso__inject_build_id(dso, tool, machine, sample->cpumode,
  471. event->mmap2.flags);
  472. }
  473. dso__put(dso);
  474. perf_event__repipe(tool, event, sample, machine);
  475. return 0;
  476. }
  477. static int perf_event__repipe_fork(struct perf_tool *tool,
  478. union perf_event *event,
  479. struct perf_sample *sample,
  480. struct machine *machine)
  481. {
  482. int err;
  483. err = perf_event__process_fork(tool, event, sample, machine);
  484. perf_event__repipe(tool, event, sample, machine);
  485. return err;
  486. }
  487. static int perf_event__repipe_comm(struct perf_tool *tool,
  488. union perf_event *event,
  489. struct perf_sample *sample,
  490. struct machine *machine)
  491. {
  492. int err;
  493. err = perf_event__process_comm(tool, event, sample, machine);
  494. perf_event__repipe(tool, event, sample, machine);
  495. return err;
  496. }
  497. static int perf_event__repipe_namespaces(struct perf_tool *tool,
  498. union perf_event *event,
  499. struct perf_sample *sample,
  500. struct machine *machine)
  501. {
  502. int err = perf_event__process_namespaces(tool, event, sample, machine);
  503. perf_event__repipe(tool, event, sample, machine);
  504. return err;
  505. }
  506. static int perf_event__repipe_exit(struct perf_tool *tool,
  507. union perf_event *event,
  508. struct perf_sample *sample,
  509. struct machine *machine)
  510. {
  511. int err;
  512. err = perf_event__process_exit(tool, event, sample, machine);
  513. perf_event__repipe(tool, event, sample, machine);
  514. return err;
  515. }
  516. static int perf_event__repipe_tracing_data(struct perf_session *session,
  517. union perf_event *event)
  518. {
  519. perf_event__repipe_synth(session->tool, event);
  520. return perf_event__process_tracing_data(session, event);
  521. }
  522. static int dso__read_build_id(struct dso *dso)
  523. {
  524. struct nscookie nsc;
  525. if (dso->has_build_id)
  526. return 0;
  527. mutex_lock(&dso->lock);
  528. nsinfo__mountns_enter(dso->nsinfo, &nsc);
  529. if (filename__read_build_id(dso->long_name, &dso->bid) > 0)
  530. dso->has_build_id = true;
  531. else if (dso->nsinfo) {
  532. char *new_name;
  533. new_name = filename_with_chroot(dso->nsinfo->pid,
  534. dso->long_name);
  535. if (new_name && filename__read_build_id(new_name, &dso->bid) > 0)
  536. dso->has_build_id = true;
  537. free(new_name);
  538. }
  539. nsinfo__mountns_exit(&nsc);
  540. mutex_unlock(&dso->lock);
  541. return dso->has_build_id ? 0 : -1;
  542. }
  543. static struct strlist *perf_inject__parse_known_build_ids(
  544. const char *known_build_ids_string)
  545. {
  546. struct str_node *pos, *tmp;
  547. struct strlist *known_build_ids;
  548. int bid_len;
  549. known_build_ids = strlist__new(known_build_ids_string, NULL);
  550. if (known_build_ids == NULL)
  551. return NULL;
  552. strlist__for_each_entry_safe(pos, tmp, known_build_ids) {
  553. const char *build_id, *dso_name;
  554. build_id = skip_spaces(pos->s);
  555. dso_name = strchr(build_id, ' ');
  556. if (dso_name == NULL) {
  557. strlist__remove(known_build_ids, pos);
  558. continue;
  559. }
  560. bid_len = dso_name - pos->s;
  561. dso_name = skip_spaces(dso_name);
  562. if (bid_len % 2 != 0 || bid_len >= SBUILD_ID_SIZE) {
  563. strlist__remove(known_build_ids, pos);
  564. continue;
  565. }
  566. for (int ix = 0; 2 * ix + 1 < bid_len; ++ix) {
  567. if (!isxdigit(build_id[2 * ix]) ||
  568. !isxdigit(build_id[2 * ix + 1])) {
  569. strlist__remove(known_build_ids, pos);
  570. break;
  571. }
  572. }
  573. }
  574. return known_build_ids;
  575. }
  576. static bool perf_inject__lookup_known_build_id(struct perf_inject *inject,
  577. struct dso *dso)
  578. {
  579. struct str_node *pos;
  580. int bid_len;
  581. strlist__for_each_entry(pos, inject->known_build_ids) {
  582. const char *build_id, *dso_name;
  583. build_id = skip_spaces(pos->s);
  584. dso_name = strchr(build_id, ' ');
  585. bid_len = dso_name - pos->s;
  586. dso_name = skip_spaces(dso_name);
  587. if (strcmp(dso->long_name, dso_name))
  588. continue;
  589. for (int ix = 0; 2 * ix + 1 < bid_len; ++ix) {
  590. dso->bid.data[ix] = (hex(build_id[2 * ix]) << 4 |
  591. hex(build_id[2 * ix + 1]));
  592. }
  593. dso->bid.size = bid_len / 2;
  594. dso->has_build_id = 1;
  595. return true;
  596. }
  597. return false;
  598. }
  599. static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
  600. struct machine *machine, u8 cpumode, u32 flags)
  601. {
  602. struct perf_inject *inject = container_of(tool, struct perf_inject,
  603. tool);
  604. int err;
  605. if (is_anon_memory(dso->long_name) || flags & MAP_HUGETLB)
  606. return 0;
  607. if (is_no_dso_memory(dso->long_name))
  608. return 0;
  609. if (inject->known_build_ids != NULL &&
  610. perf_inject__lookup_known_build_id(inject, dso))
  611. return 1;
  612. if (dso__read_build_id(dso) < 0) {
  613. pr_debug("no build_id found for %s\n", dso->long_name);
  614. return -1;
  615. }
  616. err = perf_event__synthesize_build_id(tool, dso, cpumode,
  617. perf_event__repipe, machine);
  618. if (err) {
  619. pr_err("Can't synthesize build_id event for %s\n", dso->long_name);
  620. return -1;
  621. }
  622. return 0;
  623. }
  624. int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event,
  625. struct perf_sample *sample,
  626. struct evsel *evsel __maybe_unused,
  627. struct machine *machine)
  628. {
  629. struct addr_location al;
  630. struct thread *thread;
  631. thread = machine__findnew_thread(machine, sample->pid, sample->tid);
  632. if (thread == NULL) {
  633. pr_err("problem processing %d event, skipping it.\n",
  634. event->header.type);
  635. goto repipe;
  636. }
  637. if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
  638. if (!al.map->dso->hit) {
  639. al.map->dso->hit = 1;
  640. dso__inject_build_id(al.map->dso, tool, machine,
  641. sample->cpumode, al.map->flags);
  642. }
  643. }
  644. thread__put(thread);
  645. repipe:
  646. perf_event__repipe(tool, event, sample, machine);
  647. return 0;
  648. }
  649. static int perf_inject__sched_process_exit(struct perf_tool *tool,
  650. union perf_event *event __maybe_unused,
  651. struct perf_sample *sample,
  652. struct evsel *evsel __maybe_unused,
  653. struct machine *machine __maybe_unused)
  654. {
  655. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  656. struct event_entry *ent;
  657. list_for_each_entry(ent, &inject->samples, node) {
  658. if (sample->tid == ent->tid) {
  659. list_del_init(&ent->node);
  660. free(ent);
  661. break;
  662. }
  663. }
  664. return 0;
  665. }
  666. static int perf_inject__sched_switch(struct perf_tool *tool,
  667. union perf_event *event,
  668. struct perf_sample *sample,
  669. struct evsel *evsel,
  670. struct machine *machine)
  671. {
  672. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  673. struct event_entry *ent;
  674. perf_inject__sched_process_exit(tool, event, sample, evsel, machine);
  675. ent = malloc(event->header.size + sizeof(struct event_entry));
  676. if (ent == NULL) {
  677. color_fprintf(stderr, PERF_COLOR_RED,
  678. "Not enough memory to process sched switch event!");
  679. return -1;
  680. }
  681. ent->tid = sample->tid;
  682. memcpy(&ent->event, event, event->header.size);
  683. list_add(&ent->node, &inject->samples);
  684. return 0;
  685. }
  686. static int perf_inject__sched_stat(struct perf_tool *tool,
  687. union perf_event *event __maybe_unused,
  688. struct perf_sample *sample,
  689. struct evsel *evsel,
  690. struct machine *machine)
  691. {
  692. struct event_entry *ent;
  693. union perf_event *event_sw;
  694. struct perf_sample sample_sw;
  695. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  696. u32 pid = evsel__intval(evsel, sample, "pid");
  697. list_for_each_entry(ent, &inject->samples, node) {
  698. if (pid == ent->tid)
  699. goto found;
  700. }
  701. return 0;
  702. found:
  703. event_sw = &ent->event[0];
  704. evsel__parse_sample(evsel, event_sw, &sample_sw);
  705. sample_sw.period = sample->period;
  706. sample_sw.time = sample->time;
  707. perf_event__synthesize_sample(event_sw, evsel->core.attr.sample_type,
  708. evsel->core.attr.read_format, &sample_sw);
  709. build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
  710. return perf_event__repipe(tool, event_sw, &sample_sw, machine);
  711. }
  712. static struct guest_vcpu *guest_session__vcpu(struct guest_session *gs, u32 vcpu)
  713. {
  714. if (realloc_array_as_needed(gs->vcpu, gs->vcpu_cnt, vcpu, NULL))
  715. return NULL;
  716. return &gs->vcpu[vcpu];
  717. }
  718. static int guest_session__output_bytes(struct guest_session *gs, void *buf, size_t sz)
  719. {
  720. ssize_t ret = writen(gs->tmp_fd, buf, sz);
  721. return ret < 0 ? ret : 0;
  722. }
  723. static int guest_session__repipe(struct perf_tool *tool,
  724. union perf_event *event,
  725. struct perf_sample *sample __maybe_unused,
  726. struct machine *machine __maybe_unused)
  727. {
  728. struct guest_session *gs = container_of(tool, struct guest_session, tool);
  729. return guest_session__output_bytes(gs, event, event->header.size);
  730. }
  731. static int guest_session__map_tid(struct guest_session *gs, u32 tid, u32 vcpu)
  732. {
  733. struct guest_tid *guest_tid = zalloc(sizeof(*guest_tid));
  734. int hash;
  735. if (!guest_tid)
  736. return -ENOMEM;
  737. guest_tid->tid = tid;
  738. guest_tid->vcpu = vcpu;
  739. hash = hash_32(guest_tid->tid, PERF_EVLIST__HLIST_BITS);
  740. hlist_add_head(&guest_tid->node, &gs->tids[hash]);
  741. return 0;
  742. }
  743. static int host_peek_vm_comms_cb(struct perf_session *session __maybe_unused,
  744. union perf_event *event,
  745. u64 offset __maybe_unused, void *data)
  746. {
  747. struct guest_session *gs = data;
  748. unsigned int vcpu;
  749. struct guest_vcpu *guest_vcpu;
  750. int ret;
  751. if (event->header.type != PERF_RECORD_COMM ||
  752. event->comm.pid != gs->machine_pid)
  753. return 0;
  754. /*
  755. * QEMU option -name debug-threads=on, causes thread names formatted as
  756. * below, although it is not an ABI. Also libvirt seems to use this by
  757. * default. Here we rely on it to tell us which thread is which VCPU.
  758. */
  759. ret = sscanf(event->comm.comm, "CPU %u/KVM", &vcpu);
  760. if (ret <= 0)
  761. return ret;
  762. pr_debug("Found VCPU: tid %u comm %s vcpu %u\n",
  763. event->comm.tid, event->comm.comm, vcpu);
  764. if (vcpu > INT_MAX) {
  765. pr_err("Invalid VCPU %u\n", vcpu);
  766. return -EINVAL;
  767. }
  768. guest_vcpu = guest_session__vcpu(gs, vcpu);
  769. if (!guest_vcpu)
  770. return -ENOMEM;
  771. if (guest_vcpu->tid && guest_vcpu->tid != event->comm.tid) {
  772. pr_err("Fatal error: Two threads found with the same VCPU\n");
  773. return -EINVAL;
  774. }
  775. guest_vcpu->tid = event->comm.tid;
  776. return guest_session__map_tid(gs, event->comm.tid, vcpu);
  777. }
  778. static int host_peek_vm_comms(struct perf_session *session, struct guest_session *gs)
  779. {
  780. return perf_session__peek_events(session, session->header.data_offset,
  781. session->header.data_size,
  782. host_peek_vm_comms_cb, gs);
  783. }
  784. static bool evlist__is_id_used(struct evlist *evlist, u64 id)
  785. {
  786. return evlist__id2sid(evlist, id);
  787. }
  788. static u64 guest_session__allocate_new_id(struct guest_session *gs, struct evlist *host_evlist)
  789. {
  790. do {
  791. gs->highest_id += 1;
  792. } while (!gs->highest_id || evlist__is_id_used(host_evlist, gs->highest_id));
  793. return gs->highest_id;
  794. }
  795. static int guest_session__map_id(struct guest_session *gs, u64 id, u64 host_id, u32 vcpu)
  796. {
  797. struct guest_id *guest_id = zalloc(sizeof(*guest_id));
  798. int hash;
  799. if (!guest_id)
  800. return -ENOMEM;
  801. guest_id->id = id;
  802. guest_id->host_id = host_id;
  803. guest_id->vcpu = vcpu;
  804. hash = hash_64(guest_id->id, PERF_EVLIST__HLIST_BITS);
  805. hlist_add_head(&guest_id->node, &gs->heads[hash]);
  806. return 0;
  807. }
  808. static u64 evlist__find_highest_id(struct evlist *evlist)
  809. {
  810. struct evsel *evsel;
  811. u64 highest_id = 1;
  812. evlist__for_each_entry(evlist, evsel) {
  813. u32 j;
  814. for (j = 0; j < evsel->core.ids; j++) {
  815. u64 id = evsel->core.id[j];
  816. if (id > highest_id)
  817. highest_id = id;
  818. }
  819. }
  820. return highest_id;
  821. }
  822. static int guest_session__map_ids(struct guest_session *gs, struct evlist *host_evlist)
  823. {
  824. struct evlist *evlist = gs->session->evlist;
  825. struct evsel *evsel;
  826. int ret;
  827. evlist__for_each_entry(evlist, evsel) {
  828. u32 j;
  829. for (j = 0; j < evsel->core.ids; j++) {
  830. struct perf_sample_id *sid;
  831. u64 host_id;
  832. u64 id;
  833. id = evsel->core.id[j];
  834. sid = evlist__id2sid(evlist, id);
  835. if (!sid || sid->cpu.cpu == -1)
  836. continue;
  837. host_id = guest_session__allocate_new_id(gs, host_evlist);
  838. ret = guest_session__map_id(gs, id, host_id, sid->cpu.cpu);
  839. if (ret)
  840. return ret;
  841. }
  842. }
  843. return 0;
  844. }
  845. static struct guest_id *guest_session__lookup_id(struct guest_session *gs, u64 id)
  846. {
  847. struct hlist_head *head;
  848. struct guest_id *guest_id;
  849. int hash;
  850. hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
  851. head = &gs->heads[hash];
  852. hlist_for_each_entry(guest_id, head, node)
  853. if (guest_id->id == id)
  854. return guest_id;
  855. return NULL;
  856. }
  857. static int process_attr(struct perf_tool *tool, union perf_event *event,
  858. struct perf_sample *sample __maybe_unused,
  859. struct machine *machine __maybe_unused)
  860. {
  861. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  862. return perf_event__process_attr(tool, event, &inject->session->evlist);
  863. }
  864. static int guest_session__add_attr(struct guest_session *gs, struct evsel *evsel)
  865. {
  866. struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session);
  867. struct perf_event_attr attr = evsel->core.attr;
  868. u64 *id_array;
  869. u32 *vcpu_array;
  870. int ret = -ENOMEM;
  871. u32 i;
  872. id_array = calloc(evsel->core.ids, sizeof(*id_array));
  873. if (!id_array)
  874. return -ENOMEM;
  875. vcpu_array = calloc(evsel->core.ids, sizeof(*vcpu_array));
  876. if (!vcpu_array)
  877. goto out;
  878. for (i = 0; i < evsel->core.ids; i++) {
  879. u64 id = evsel->core.id[i];
  880. struct guest_id *guest_id = guest_session__lookup_id(gs, id);
  881. if (!guest_id) {
  882. pr_err("Failed to find guest id %"PRIu64"\n", id);
  883. ret = -EINVAL;
  884. goto out;
  885. }
  886. id_array[i] = guest_id->host_id;
  887. vcpu_array[i] = guest_id->vcpu;
  888. }
  889. attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
  890. attr.exclude_host = 1;
  891. attr.exclude_guest = 0;
  892. ret = perf_event__synthesize_attr(&inject->tool, &attr, evsel->core.ids,
  893. id_array, process_attr);
  894. if (ret)
  895. pr_err("Failed to add guest attr.\n");
  896. for (i = 0; i < evsel->core.ids; i++) {
  897. struct perf_sample_id *sid;
  898. u32 vcpu = vcpu_array[i];
  899. sid = evlist__id2sid(inject->session->evlist, id_array[i]);
  900. /* Guest event is per-thread from the host point of view */
  901. sid->cpu.cpu = -1;
  902. sid->tid = gs->vcpu[vcpu].tid;
  903. sid->machine_pid = gs->machine_pid;
  904. sid->vcpu.cpu = vcpu;
  905. }
  906. out:
  907. free(vcpu_array);
  908. free(id_array);
  909. return ret;
  910. }
  911. static int guest_session__add_attrs(struct guest_session *gs)
  912. {
  913. struct evlist *evlist = gs->session->evlist;
  914. struct evsel *evsel;
  915. int ret;
  916. evlist__for_each_entry(evlist, evsel) {
  917. ret = guest_session__add_attr(gs, evsel);
  918. if (ret)
  919. return ret;
  920. }
  921. return 0;
  922. }
  923. static int synthesize_id_index(struct perf_inject *inject, size_t new_cnt)
  924. {
  925. struct perf_session *session = inject->session;
  926. struct evlist *evlist = session->evlist;
  927. struct machine *machine = &session->machines.host;
  928. size_t from = evlist->core.nr_entries - new_cnt;
  929. return __perf_event__synthesize_id_index(&inject->tool, perf_event__repipe,
  930. evlist, machine, from);
  931. }
  932. static struct guest_tid *guest_session__lookup_tid(struct guest_session *gs, u32 tid)
  933. {
  934. struct hlist_head *head;
  935. struct guest_tid *guest_tid;
  936. int hash;
  937. hash = hash_32(tid, PERF_EVLIST__HLIST_BITS);
  938. head = &gs->tids[hash];
  939. hlist_for_each_entry(guest_tid, head, node)
  940. if (guest_tid->tid == tid)
  941. return guest_tid;
  942. return NULL;
  943. }
  944. static bool dso__is_in_kernel_space(struct dso *dso)
  945. {
  946. if (dso__is_vdso(dso))
  947. return false;
  948. return dso__is_kcore(dso) ||
  949. dso->kernel ||
  950. is_kernel_module(dso->long_name, PERF_RECORD_MISC_CPUMODE_UNKNOWN);
  951. }
  952. static u64 evlist__first_id(struct evlist *evlist)
  953. {
  954. struct evsel *evsel;
  955. evlist__for_each_entry(evlist, evsel) {
  956. if (evsel->core.ids)
  957. return evsel->core.id[0];
  958. }
  959. return 0;
  960. }
  961. static int process_build_id(struct perf_tool *tool,
  962. union perf_event *event,
  963. struct perf_sample *sample __maybe_unused,
  964. struct machine *machine __maybe_unused)
  965. {
  966. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  967. return perf_event__process_build_id(inject->session, event);
  968. }
  969. static int synthesize_build_id(struct perf_inject *inject, struct dso *dso, pid_t machine_pid)
  970. {
  971. struct machine *machine = perf_session__findnew_machine(inject->session, machine_pid);
  972. u8 cpumode = dso__is_in_kernel_space(dso) ?
  973. PERF_RECORD_MISC_GUEST_KERNEL :
  974. PERF_RECORD_MISC_GUEST_USER;
  975. if (!machine)
  976. return -ENOMEM;
  977. dso->hit = 1;
  978. return perf_event__synthesize_build_id(&inject->tool, dso, cpumode,
  979. process_build_id, machine);
  980. }
  981. static int guest_session__add_build_ids(struct guest_session *gs)
  982. {
  983. struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session);
  984. struct machine *machine = &gs->session->machines.host;
  985. struct dso *dso;
  986. int ret;
  987. /* Build IDs will be put in the Build ID feature section */
  988. perf_header__set_feat(&inject->session->header, HEADER_BUILD_ID);
  989. dsos__for_each_with_build_id(dso, &machine->dsos.head) {
  990. ret = synthesize_build_id(inject, dso, gs->machine_pid);
  991. if (ret)
  992. return ret;
  993. }
  994. return 0;
  995. }
  996. static int guest_session__ksymbol_event(struct perf_tool *tool,
  997. union perf_event *event,
  998. struct perf_sample *sample __maybe_unused,
  999. struct machine *machine __maybe_unused)
  1000. {
  1001. struct guest_session *gs = container_of(tool, struct guest_session, tool);
  1002. /* Only support out-of-line i.e. no BPF support */
  1003. if (event->ksymbol.ksym_type != PERF_RECORD_KSYMBOL_TYPE_OOL)
  1004. return 0;
  1005. return guest_session__output_bytes(gs, event, event->header.size);
  1006. }
  1007. static int guest_session__start(struct guest_session *gs, const char *name, bool force)
  1008. {
  1009. char tmp_file_name[] = "/tmp/perf-inject-guest_session-XXXXXX";
  1010. struct perf_session *session;
  1011. int ret;
  1012. /* Only these events will be injected */
  1013. gs->tool.mmap = guest_session__repipe;
  1014. gs->tool.mmap2 = guest_session__repipe;
  1015. gs->tool.comm = guest_session__repipe;
  1016. gs->tool.fork = guest_session__repipe;
  1017. gs->tool.exit = guest_session__repipe;
  1018. gs->tool.lost = guest_session__repipe;
  1019. gs->tool.context_switch = guest_session__repipe;
  1020. gs->tool.ksymbol = guest_session__ksymbol_event;
  1021. gs->tool.text_poke = guest_session__repipe;
  1022. /*
  1023. * Processing a build ID creates a struct dso with that build ID. Later,
  1024. * all guest dsos are iterated and the build IDs processed into the host
  1025. * session where they will be output to the Build ID feature section
  1026. * when the perf.data file header is written.
  1027. */
  1028. gs->tool.build_id = perf_event__process_build_id;
  1029. /* Process the id index to know what VCPU an ID belongs to */
  1030. gs->tool.id_index = perf_event__process_id_index;
  1031. gs->tool.ordered_events = true;
  1032. gs->tool.ordering_requires_timestamps = true;
  1033. gs->data.path = name;
  1034. gs->data.force = force;
  1035. gs->data.mode = PERF_DATA_MODE_READ;
  1036. session = perf_session__new(&gs->data, &gs->tool);
  1037. if (IS_ERR(session))
  1038. return PTR_ERR(session);
  1039. gs->session = session;
  1040. /*
  1041. * Initial events have zero'd ID samples. Get default ID sample size
  1042. * used for removing them.
  1043. */
  1044. gs->dflt_id_hdr_size = session->machines.host.id_hdr_size;
  1045. /* And default ID for adding back a host-compatible ID sample */
  1046. gs->dflt_id = evlist__first_id(session->evlist);
  1047. if (!gs->dflt_id) {
  1048. pr_err("Guest data has no sample IDs");
  1049. return -EINVAL;
  1050. }
  1051. /* Temporary file for guest events */
  1052. gs->tmp_file_name = strdup(tmp_file_name);
  1053. if (!gs->tmp_file_name)
  1054. return -ENOMEM;
  1055. gs->tmp_fd = mkstemp(gs->tmp_file_name);
  1056. if (gs->tmp_fd < 0)
  1057. return -errno;
  1058. if (zstd_init(&gs->session->zstd_data, 0) < 0)
  1059. pr_warning("Guest session decompression initialization failed.\n");
  1060. /*
  1061. * perf does not support processing 2 sessions simultaneously, so output
  1062. * guest events to a temporary file.
  1063. */
  1064. ret = perf_session__process_events(gs->session);
  1065. if (ret)
  1066. return ret;
  1067. if (lseek(gs->tmp_fd, 0, SEEK_SET))
  1068. return -errno;
  1069. return 0;
  1070. }
  1071. /* Free hlist nodes assuming hlist_node is the first member of hlist entries */
  1072. static void free_hlist(struct hlist_head *heads, size_t hlist_sz)
  1073. {
  1074. struct hlist_node *pos, *n;
  1075. size_t i;
  1076. for (i = 0; i < hlist_sz; ++i) {
  1077. hlist_for_each_safe(pos, n, &heads[i]) {
  1078. hlist_del(pos);
  1079. free(pos);
  1080. }
  1081. }
  1082. }
  1083. static void guest_session__exit(struct guest_session *gs)
  1084. {
  1085. if (gs->session) {
  1086. perf_session__delete(gs->session);
  1087. free_hlist(gs->heads, PERF_EVLIST__HLIST_SIZE);
  1088. free_hlist(gs->tids, PERF_EVLIST__HLIST_SIZE);
  1089. }
  1090. if (gs->tmp_file_name) {
  1091. if (gs->tmp_fd >= 0)
  1092. close(gs->tmp_fd);
  1093. unlink(gs->tmp_file_name);
  1094. free(gs->tmp_file_name);
  1095. }
  1096. free(gs->vcpu);
  1097. free(gs->perf_data_file);
  1098. }
  1099. static void get_tsc_conv(struct perf_tsc_conversion *tc, struct perf_record_time_conv *time_conv)
  1100. {
  1101. tc->time_shift = time_conv->time_shift;
  1102. tc->time_mult = time_conv->time_mult;
  1103. tc->time_zero = time_conv->time_zero;
  1104. tc->time_cycles = time_conv->time_cycles;
  1105. tc->time_mask = time_conv->time_mask;
  1106. tc->cap_user_time_zero = time_conv->cap_user_time_zero;
  1107. tc->cap_user_time_short = time_conv->cap_user_time_short;
  1108. }
  1109. static void guest_session__get_tc(struct guest_session *gs)
  1110. {
  1111. struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session);
  1112. get_tsc_conv(&gs->host_tc, &inject->session->time_conv);
  1113. get_tsc_conv(&gs->guest_tc, &gs->session->time_conv);
  1114. }
  1115. static void guest_session__convert_time(struct guest_session *gs, u64 guest_time, u64 *host_time)
  1116. {
  1117. u64 tsc;
  1118. if (!guest_time) {
  1119. *host_time = 0;
  1120. return;
  1121. }
  1122. if (gs->guest_tc.cap_user_time_zero)
  1123. tsc = perf_time_to_tsc(guest_time, &gs->guest_tc);
  1124. else
  1125. tsc = guest_time;
  1126. /*
  1127. * This is the correct order of operations for x86 if the TSC Offset and
  1128. * Multiplier values are used.
  1129. */
  1130. tsc -= gs->time_offset;
  1131. tsc /= gs->time_scale;
  1132. if (gs->host_tc.cap_user_time_zero)
  1133. *host_time = tsc_to_perf_time(tsc, &gs->host_tc);
  1134. else
  1135. *host_time = tsc;
  1136. }
  1137. static int guest_session__fetch(struct guest_session *gs)
  1138. {
  1139. void *buf = gs->ev.event_buf;
  1140. struct perf_event_header *hdr = buf;
  1141. size_t hdr_sz = sizeof(*hdr);
  1142. ssize_t ret;
  1143. ret = readn(gs->tmp_fd, buf, hdr_sz);
  1144. if (ret < 0)
  1145. return ret;
  1146. if (!ret) {
  1147. /* Zero size means EOF */
  1148. hdr->size = 0;
  1149. return 0;
  1150. }
  1151. buf += hdr_sz;
  1152. ret = readn(gs->tmp_fd, buf, hdr->size - hdr_sz);
  1153. if (ret < 0)
  1154. return ret;
  1155. gs->ev.event = (union perf_event *)gs->ev.event_buf;
  1156. gs->ev.sample.time = 0;
  1157. if (hdr->type >= PERF_RECORD_USER_TYPE_START) {
  1158. pr_err("Unexpected type fetching guest event");
  1159. return 0;
  1160. }
  1161. ret = evlist__parse_sample(gs->session->evlist, gs->ev.event, &gs->ev.sample);
  1162. if (ret) {
  1163. pr_err("Parse failed fetching guest event");
  1164. return ret;
  1165. }
  1166. if (!gs->have_tc) {
  1167. guest_session__get_tc(gs);
  1168. gs->have_tc = true;
  1169. }
  1170. guest_session__convert_time(gs, gs->ev.sample.time, &gs->ev.sample.time);
  1171. return 0;
  1172. }
  1173. static int evlist__append_id_sample(struct evlist *evlist, union perf_event *ev,
  1174. const struct perf_sample *sample)
  1175. {
  1176. struct evsel *evsel;
  1177. void *array;
  1178. int ret;
  1179. evsel = evlist__id2evsel(evlist, sample->id);
  1180. array = ev;
  1181. if (!evsel) {
  1182. pr_err("No evsel for id %"PRIu64"\n", sample->id);
  1183. return -EINVAL;
  1184. }
  1185. array += ev->header.size;
  1186. ret = perf_event__synthesize_id_sample(array, evsel->core.attr.sample_type, sample);
  1187. if (ret < 0)
  1188. return ret;
  1189. if (ret & 7) {
  1190. pr_err("Bad id sample size %d\n", ret);
  1191. return -EINVAL;
  1192. }
  1193. ev->header.size += ret;
  1194. return 0;
  1195. }
  1196. static int guest_session__inject_events(struct guest_session *gs, u64 timestamp)
  1197. {
  1198. struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session);
  1199. int ret;
  1200. if (!gs->ready)
  1201. return 0;
  1202. while (1) {
  1203. struct perf_sample *sample;
  1204. struct guest_id *guest_id;
  1205. union perf_event *ev;
  1206. u16 id_hdr_size;
  1207. u8 cpumode;
  1208. u64 id;
  1209. if (!gs->fetched) {
  1210. ret = guest_session__fetch(gs);
  1211. if (ret)
  1212. return ret;
  1213. gs->fetched = true;
  1214. }
  1215. ev = gs->ev.event;
  1216. sample = &gs->ev.sample;
  1217. if (!ev->header.size)
  1218. return 0; /* EOF */
  1219. if (sample->time > timestamp)
  1220. return 0;
  1221. /* Change cpumode to guest */
  1222. cpumode = ev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
  1223. if (cpumode & PERF_RECORD_MISC_USER)
  1224. cpumode = PERF_RECORD_MISC_GUEST_USER;
  1225. else
  1226. cpumode = PERF_RECORD_MISC_GUEST_KERNEL;
  1227. ev->header.misc &= ~PERF_RECORD_MISC_CPUMODE_MASK;
  1228. ev->header.misc |= cpumode;
  1229. id = sample->id;
  1230. if (!id) {
  1231. id = gs->dflt_id;
  1232. id_hdr_size = gs->dflt_id_hdr_size;
  1233. } else {
  1234. struct evsel *evsel = evlist__id2evsel(gs->session->evlist, id);
  1235. id_hdr_size = evsel__id_hdr_size(evsel);
  1236. }
  1237. if (id_hdr_size & 7) {
  1238. pr_err("Bad id_hdr_size %u\n", id_hdr_size);
  1239. return -EINVAL;
  1240. }
  1241. if (ev->header.size & 7) {
  1242. pr_err("Bad event size %u\n", ev->header.size);
  1243. return -EINVAL;
  1244. }
  1245. /* Remove guest id sample */
  1246. ev->header.size -= id_hdr_size;
  1247. if (ev->header.size & 7) {
  1248. pr_err("Bad raw event size %u\n", ev->header.size);
  1249. return -EINVAL;
  1250. }
  1251. guest_id = guest_session__lookup_id(gs, id);
  1252. if (!guest_id) {
  1253. pr_err("Guest event with unknown id %llu\n",
  1254. (unsigned long long)id);
  1255. return -EINVAL;
  1256. }
  1257. /* Change to host ID to avoid conflicting ID values */
  1258. sample->id = guest_id->host_id;
  1259. sample->stream_id = guest_id->host_id;
  1260. if (sample->cpu != (u32)-1) {
  1261. if (sample->cpu >= gs->vcpu_cnt) {
  1262. pr_err("Guest event with unknown VCPU %u\n",
  1263. sample->cpu);
  1264. return -EINVAL;
  1265. }
  1266. /* Change to host CPU instead of guest VCPU */
  1267. sample->cpu = gs->vcpu[sample->cpu].cpu;
  1268. }
  1269. /* New id sample with new ID and CPU */
  1270. ret = evlist__append_id_sample(inject->session->evlist, ev, sample);
  1271. if (ret)
  1272. return ret;
  1273. if (ev->header.size & 7) {
  1274. pr_err("Bad new event size %u\n", ev->header.size);
  1275. return -EINVAL;
  1276. }
  1277. gs->fetched = false;
  1278. ret = output_bytes(inject, ev, ev->header.size);
  1279. if (ret)
  1280. return ret;
  1281. }
  1282. }
  1283. static int guest_session__flush_events(struct guest_session *gs)
  1284. {
  1285. return guest_session__inject_events(gs, -1);
  1286. }
  1287. static int host__repipe(struct perf_tool *tool,
  1288. union perf_event *event,
  1289. struct perf_sample *sample,
  1290. struct machine *machine)
  1291. {
  1292. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  1293. int ret;
  1294. ret = guest_session__inject_events(&inject->guest_session, sample->time);
  1295. if (ret)
  1296. return ret;
  1297. return perf_event__repipe(tool, event, sample, machine);
  1298. }
  1299. static int host__finished_init(struct perf_session *session, union perf_event *event)
  1300. {
  1301. struct perf_inject *inject = container_of(session->tool, struct perf_inject, tool);
  1302. struct guest_session *gs = &inject->guest_session;
  1303. int ret;
  1304. /*
  1305. * Peek through host COMM events to find QEMU threads and the VCPU they
  1306. * are running.
  1307. */
  1308. ret = host_peek_vm_comms(session, gs);
  1309. if (ret)
  1310. return ret;
  1311. if (!gs->vcpu_cnt) {
  1312. pr_err("No VCPU threads found for pid %u\n", gs->machine_pid);
  1313. return -EINVAL;
  1314. }
  1315. /*
  1316. * Allocate new (unused) host sample IDs and map them to the guest IDs.
  1317. */
  1318. gs->highest_id = evlist__find_highest_id(session->evlist);
  1319. ret = guest_session__map_ids(gs, session->evlist);
  1320. if (ret)
  1321. return ret;
  1322. ret = guest_session__add_attrs(gs);
  1323. if (ret)
  1324. return ret;
  1325. ret = synthesize_id_index(inject, gs->session->evlist->core.nr_entries);
  1326. if (ret) {
  1327. pr_err("Failed to synthesize id_index\n");
  1328. return ret;
  1329. }
  1330. ret = guest_session__add_build_ids(gs);
  1331. if (ret) {
  1332. pr_err("Failed to add guest build IDs\n");
  1333. return ret;
  1334. }
  1335. gs->ready = true;
  1336. ret = guest_session__inject_events(gs, 0);
  1337. if (ret)
  1338. return ret;
  1339. return perf_event__repipe_op2_synth(session, event);
  1340. }
  1341. /*
  1342. * Obey finished-round ordering. The FINISHED_ROUND event is first processed
  1343. * which flushes host events to file up until the last flush time. Then inject
  1344. * guest events up to the same time. Finally write out the FINISHED_ROUND event
  1345. * itself.
  1346. */
  1347. static int host__finished_round(struct perf_tool *tool,
  1348. union perf_event *event,
  1349. struct ordered_events *oe)
  1350. {
  1351. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  1352. int ret = perf_event__process_finished_round(tool, event, oe);
  1353. u64 timestamp = ordered_events__last_flush_time(oe);
  1354. if (ret)
  1355. return ret;
  1356. ret = guest_session__inject_events(&inject->guest_session, timestamp);
  1357. if (ret)
  1358. return ret;
  1359. return perf_event__repipe_oe_synth(tool, event, oe);
  1360. }
  1361. static int host__context_switch(struct perf_tool *tool,
  1362. union perf_event *event,
  1363. struct perf_sample *sample,
  1364. struct machine *machine)
  1365. {
  1366. struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  1367. bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
  1368. struct guest_session *gs = &inject->guest_session;
  1369. u32 pid = event->context_switch.next_prev_pid;
  1370. u32 tid = event->context_switch.next_prev_tid;
  1371. struct guest_tid *guest_tid;
  1372. u32 vcpu;
  1373. if (out || pid != gs->machine_pid)
  1374. goto out;
  1375. guest_tid = guest_session__lookup_tid(gs, tid);
  1376. if (!guest_tid)
  1377. goto out;
  1378. if (sample->cpu == (u32)-1) {
  1379. pr_err("Switch event does not have CPU\n");
  1380. return -EINVAL;
  1381. }
  1382. vcpu = guest_tid->vcpu;
  1383. if (vcpu >= gs->vcpu_cnt)
  1384. return -EINVAL;
  1385. /* Guest is switching in, record which CPU the VCPU is now running on */
  1386. gs->vcpu[vcpu].cpu = sample->cpu;
  1387. out:
  1388. return host__repipe(tool, event, sample, machine);
  1389. }
  1390. static void sig_handler(int sig __maybe_unused)
  1391. {
  1392. session_done = 1;
  1393. }
  1394. static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg)
  1395. {
  1396. struct perf_event_attr *attr = &evsel->core.attr;
  1397. const char *name = evsel__name(evsel);
  1398. if (!(attr->sample_type & sample_type)) {
  1399. pr_err("Samples for %s event do not have %s attribute set.",
  1400. name, sample_msg);
  1401. return -EINVAL;
  1402. }
  1403. return 0;
  1404. }
  1405. static int drop_sample(struct perf_tool *tool __maybe_unused,
  1406. union perf_event *event __maybe_unused,
  1407. struct perf_sample *sample __maybe_unused,
  1408. struct evsel *evsel __maybe_unused,
  1409. struct machine *machine __maybe_unused)
  1410. {
  1411. return 0;
  1412. }
  1413. static void strip_init(struct perf_inject *inject)
  1414. {
  1415. struct evlist *evlist = inject->session->evlist;
  1416. struct evsel *evsel;
  1417. inject->tool.context_switch = perf_event__drop;
  1418. evlist__for_each_entry(evlist, evsel)
  1419. evsel->handler = drop_sample;
  1420. }
  1421. static int parse_vm_time_correlation(const struct option *opt, const char *str, int unset)
  1422. {
  1423. struct perf_inject *inject = opt->value;
  1424. const char *args;
  1425. char *dry_run;
  1426. if (unset)
  1427. return 0;
  1428. inject->itrace_synth_opts.set = true;
  1429. inject->itrace_synth_opts.vm_time_correlation = true;
  1430. inject->in_place_update = true;
  1431. if (!str)
  1432. return 0;
  1433. dry_run = skip_spaces(str);
  1434. if (!strncmp(dry_run, "dry-run", strlen("dry-run"))) {
  1435. inject->itrace_synth_opts.vm_tm_corr_dry_run = true;
  1436. inject->in_place_update_dry_run = true;
  1437. args = dry_run + strlen("dry-run");
  1438. } else {
  1439. args = str;
  1440. }
  1441. inject->itrace_synth_opts.vm_tm_corr_args = strdup(args);
  1442. return inject->itrace_synth_opts.vm_tm_corr_args ? 0 : -ENOMEM;
  1443. }
  1444. static int parse_guest_data(const struct option *opt, const char *str, int unset)
  1445. {
  1446. struct perf_inject *inject = opt->value;
  1447. struct guest_session *gs = &inject->guest_session;
  1448. char *tok;
  1449. char *s;
  1450. if (unset)
  1451. return 0;
  1452. if (!str)
  1453. goto bad_args;
  1454. s = strdup(str);
  1455. if (!s)
  1456. return -ENOMEM;
  1457. gs->perf_data_file = strsep(&s, ",");
  1458. if (!gs->perf_data_file)
  1459. goto bad_args;
  1460. gs->copy_kcore_dir = has_kcore_dir(gs->perf_data_file);
  1461. if (gs->copy_kcore_dir)
  1462. inject->output.is_dir = true;
  1463. tok = strsep(&s, ",");
  1464. if (!tok)
  1465. goto bad_args;
  1466. gs->machine_pid = strtoul(tok, NULL, 0);
  1467. if (!inject->guest_session.machine_pid)
  1468. goto bad_args;
  1469. gs->time_scale = 1;
  1470. tok = strsep(&s, ",");
  1471. if (!tok)
  1472. goto out;
  1473. gs->time_offset = strtoull(tok, NULL, 0);
  1474. tok = strsep(&s, ",");
  1475. if (!tok)
  1476. goto out;
  1477. gs->time_scale = strtod(tok, NULL);
  1478. if (!gs->time_scale)
  1479. goto bad_args;
  1480. out:
  1481. return 0;
  1482. bad_args:
  1483. pr_err("--guest-data option requires guest perf.data file name, "
  1484. "guest machine PID, and optionally guest timestamp offset, "
  1485. "and guest timestamp scale factor, separated by commas.\n");
  1486. return -1;
  1487. }
  1488. static int save_section_info_cb(struct perf_file_section *section,
  1489. struct perf_header *ph __maybe_unused,
  1490. int feat, int fd __maybe_unused, void *data)
  1491. {
  1492. struct perf_inject *inject = data;
  1493. inject->secs[feat] = *section;
  1494. return 0;
  1495. }
  1496. static int save_section_info(struct perf_inject *inject)
  1497. {
  1498. struct perf_header *header = &inject->session->header;
  1499. int fd = perf_data__fd(inject->session->data);
  1500. return perf_header__process_sections(header, fd, inject, save_section_info_cb);
  1501. }
  1502. static bool keep_feat(int feat)
  1503. {
  1504. switch (feat) {
  1505. /* Keep original information that describes the machine or software */
  1506. case HEADER_TRACING_DATA:
  1507. case HEADER_HOSTNAME:
  1508. case HEADER_OSRELEASE:
  1509. case HEADER_VERSION:
  1510. case HEADER_ARCH:
  1511. case HEADER_NRCPUS:
  1512. case HEADER_CPUDESC:
  1513. case HEADER_CPUID:
  1514. case HEADER_TOTAL_MEM:
  1515. case HEADER_CPU_TOPOLOGY:
  1516. case HEADER_NUMA_TOPOLOGY:
  1517. case HEADER_PMU_MAPPINGS:
  1518. case HEADER_CACHE:
  1519. case HEADER_MEM_TOPOLOGY:
  1520. case HEADER_CLOCKID:
  1521. case HEADER_BPF_PROG_INFO:
  1522. case HEADER_BPF_BTF:
  1523. case HEADER_CPU_PMU_CAPS:
  1524. case HEADER_CLOCK_DATA:
  1525. case HEADER_HYBRID_TOPOLOGY:
  1526. case HEADER_PMU_CAPS:
  1527. return true;
  1528. /* Information that can be updated */
  1529. case HEADER_BUILD_ID:
  1530. case HEADER_CMDLINE:
  1531. case HEADER_EVENT_DESC:
  1532. case HEADER_BRANCH_STACK:
  1533. case HEADER_GROUP_DESC:
  1534. case HEADER_AUXTRACE:
  1535. case HEADER_STAT:
  1536. case HEADER_SAMPLE_TIME:
  1537. case HEADER_DIR_FORMAT:
  1538. case HEADER_COMPRESSED:
  1539. default:
  1540. return false;
  1541. };
  1542. }
  1543. static int read_file(int fd, u64 offs, void *buf, size_t sz)
  1544. {
  1545. ssize_t ret = preadn(fd, buf, sz, offs);
  1546. if (ret < 0)
  1547. return -errno;
  1548. if ((size_t)ret != sz)
  1549. return -EINVAL;
  1550. return 0;
  1551. }
  1552. static int feat_copy(struct perf_inject *inject, int feat, struct feat_writer *fw)
  1553. {
  1554. int fd = perf_data__fd(inject->session->data);
  1555. u64 offs = inject->secs[feat].offset;
  1556. size_t sz = inject->secs[feat].size;
  1557. void *buf = malloc(sz);
  1558. int ret;
  1559. if (!buf)
  1560. return -ENOMEM;
  1561. ret = read_file(fd, offs, buf, sz);
  1562. if (ret)
  1563. goto out_free;
  1564. ret = fw->write(fw, buf, sz);
  1565. out_free:
  1566. free(buf);
  1567. return ret;
  1568. }
  1569. struct inject_fc {
  1570. struct feat_copier fc;
  1571. struct perf_inject *inject;
  1572. };
  1573. static int feat_copy_cb(struct feat_copier *fc, int feat, struct feat_writer *fw)
  1574. {
  1575. struct inject_fc *inj_fc = container_of(fc, struct inject_fc, fc);
  1576. struct perf_inject *inject = inj_fc->inject;
  1577. int ret;
  1578. if (!inject->secs[feat].offset ||
  1579. !keep_feat(feat))
  1580. return 0;
  1581. ret = feat_copy(inject, feat, fw);
  1582. if (ret < 0)
  1583. return ret;
  1584. return 1; /* Feature section copied */
  1585. }
  1586. static int copy_kcore_dir(struct perf_inject *inject)
  1587. {
  1588. char *cmd;
  1589. int ret;
  1590. ret = asprintf(&cmd, "cp -r -n %s/kcore_dir* %s >/dev/null 2>&1",
  1591. inject->input_name, inject->output.path);
  1592. if (ret < 0)
  1593. return ret;
  1594. pr_debug("%s\n", cmd);
  1595. ret = system(cmd);
  1596. free(cmd);
  1597. return ret;
  1598. }
  1599. static int guest_session__copy_kcore_dir(struct guest_session *gs)
  1600. {
  1601. struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session);
  1602. char *cmd;
  1603. int ret;
  1604. ret = asprintf(&cmd, "cp -r -n %s/kcore_dir %s/kcore_dir__%u >/dev/null 2>&1",
  1605. gs->perf_data_file, inject->output.path, gs->machine_pid);
  1606. if (ret < 0)
  1607. return ret;
  1608. pr_debug("%s\n", cmd);
  1609. ret = system(cmd);
  1610. free(cmd);
  1611. return ret;
  1612. }
  1613. static int output_fd(struct perf_inject *inject)
  1614. {
  1615. return inject->in_place_update ? -1 : perf_data__fd(&inject->output);
  1616. }
  1617. static int __cmd_inject(struct perf_inject *inject)
  1618. {
  1619. int ret = -EINVAL;
  1620. struct guest_session *gs = &inject->guest_session;
  1621. struct perf_session *session = inject->session;
  1622. int fd = output_fd(inject);
  1623. u64 output_data_offset;
  1624. signal(SIGINT, sig_handler);
  1625. if (inject->build_ids || inject->sched_stat ||
  1626. inject->itrace_synth_opts.set || inject->build_id_all) {
  1627. inject->tool.mmap = perf_event__repipe_mmap;
  1628. inject->tool.mmap2 = perf_event__repipe_mmap2;
  1629. inject->tool.fork = perf_event__repipe_fork;
  1630. inject->tool.tracing_data = perf_event__repipe_tracing_data;
  1631. }
  1632. output_data_offset = perf_session__data_offset(session->evlist);
  1633. if (inject->build_id_all) {
  1634. inject->tool.mmap = perf_event__repipe_buildid_mmap;
  1635. inject->tool.mmap2 = perf_event__repipe_buildid_mmap2;
  1636. } else if (inject->build_ids) {
  1637. inject->tool.sample = perf_event__inject_buildid;
  1638. } else if (inject->sched_stat) {
  1639. struct evsel *evsel;
  1640. evlist__for_each_entry(session->evlist, evsel) {
  1641. const char *name = evsel__name(evsel);
  1642. if (!strcmp(name, "sched:sched_switch")) {
  1643. if (evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
  1644. return -EINVAL;
  1645. evsel->handler = perf_inject__sched_switch;
  1646. } else if (!strcmp(name, "sched:sched_process_exit"))
  1647. evsel->handler = perf_inject__sched_process_exit;
  1648. else if (!strncmp(name, "sched:sched_stat_", 17))
  1649. evsel->handler = perf_inject__sched_stat;
  1650. }
  1651. } else if (inject->itrace_synth_opts.vm_time_correlation) {
  1652. session->itrace_synth_opts = &inject->itrace_synth_opts;
  1653. memset(&inject->tool, 0, sizeof(inject->tool));
  1654. inject->tool.id_index = perf_event__process_id_index;
  1655. inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
  1656. inject->tool.auxtrace = perf_event__process_auxtrace;
  1657. inject->tool.auxtrace_error = perf_event__process_auxtrace_error;
  1658. inject->tool.ordered_events = true;
  1659. inject->tool.ordering_requires_timestamps = true;
  1660. } else if (inject->itrace_synth_opts.set) {
  1661. session->itrace_synth_opts = &inject->itrace_synth_opts;
  1662. inject->itrace_synth_opts.inject = true;
  1663. inject->tool.comm = perf_event__repipe_comm;
  1664. inject->tool.namespaces = perf_event__repipe_namespaces;
  1665. inject->tool.exit = perf_event__repipe_exit;
  1666. inject->tool.id_index = perf_event__process_id_index;
  1667. inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
  1668. inject->tool.auxtrace = perf_event__process_auxtrace;
  1669. inject->tool.aux = perf_event__drop_aux;
  1670. inject->tool.itrace_start = perf_event__drop_aux;
  1671. inject->tool.aux_output_hw_id = perf_event__drop_aux;
  1672. inject->tool.ordered_events = true;
  1673. inject->tool.ordering_requires_timestamps = true;
  1674. /* Allow space in the header for new attributes */
  1675. output_data_offset = roundup(8192 + session->header.data_offset, 4096);
  1676. if (inject->strip)
  1677. strip_init(inject);
  1678. } else if (gs->perf_data_file) {
  1679. char *name = gs->perf_data_file;
  1680. /*
  1681. * Not strictly necessary, but keep these events in order wrt
  1682. * guest events.
  1683. */
  1684. inject->tool.mmap = host__repipe;
  1685. inject->tool.mmap2 = host__repipe;
  1686. inject->tool.comm = host__repipe;
  1687. inject->tool.fork = host__repipe;
  1688. inject->tool.exit = host__repipe;
  1689. inject->tool.lost = host__repipe;
  1690. inject->tool.context_switch = host__repipe;
  1691. inject->tool.ksymbol = host__repipe;
  1692. inject->tool.text_poke = host__repipe;
  1693. /*
  1694. * Once the host session has initialized, set up sample ID
  1695. * mapping and feed in guest attrs, build IDs and initial
  1696. * events.
  1697. */
  1698. inject->tool.finished_init = host__finished_init;
  1699. /* Obey finished round ordering */
  1700. inject->tool.finished_round = host__finished_round,
  1701. /* Keep track of which CPU a VCPU is runnng on */
  1702. inject->tool.context_switch = host__context_switch;
  1703. /*
  1704. * Must order events to be able to obey finished round
  1705. * ordering.
  1706. */
  1707. inject->tool.ordered_events = true;
  1708. inject->tool.ordering_requires_timestamps = true;
  1709. /* Set up a separate session to process guest perf.data file */
  1710. ret = guest_session__start(gs, name, session->data->force);
  1711. if (ret) {
  1712. pr_err("Failed to process %s, error %d\n", name, ret);
  1713. return ret;
  1714. }
  1715. /* Allow space in the header for guest attributes */
  1716. output_data_offset += gs->session->header.data_offset;
  1717. output_data_offset = roundup(output_data_offset, 4096);
  1718. }
  1719. if (!inject->itrace_synth_opts.set)
  1720. auxtrace_index__free(&session->auxtrace_index);
  1721. if (!inject->is_pipe && !inject->in_place_update)
  1722. lseek(fd, output_data_offset, SEEK_SET);
  1723. ret = perf_session__process_events(session);
  1724. if (ret)
  1725. return ret;
  1726. if (gs->session) {
  1727. /*
  1728. * Remaining guest events have later timestamps. Flush them
  1729. * out to file.
  1730. */
  1731. ret = guest_session__flush_events(gs);
  1732. if (ret) {
  1733. pr_err("Failed to flush guest events\n");
  1734. return ret;
  1735. }
  1736. }
  1737. if (!inject->is_pipe && !inject->in_place_update) {
  1738. struct inject_fc inj_fc = {
  1739. .fc.copy = feat_copy_cb,
  1740. .inject = inject,
  1741. };
  1742. if (inject->build_ids)
  1743. perf_header__set_feat(&session->header,
  1744. HEADER_BUILD_ID);
  1745. /*
  1746. * Keep all buildids when there is unprocessed AUX data because
  1747. * it is not known which ones the AUX trace hits.
  1748. */
  1749. if (perf_header__has_feat(&session->header, HEADER_BUILD_ID) &&
  1750. inject->have_auxtrace && !inject->itrace_synth_opts.set)
  1751. dsos__hit_all(session);
  1752. /*
  1753. * The AUX areas have been removed and replaced with
  1754. * synthesized hardware events, so clear the feature flag.
  1755. */
  1756. if (inject->itrace_synth_opts.set) {
  1757. perf_header__clear_feat(&session->header,
  1758. HEADER_AUXTRACE);
  1759. if (inject->itrace_synth_opts.last_branch ||
  1760. inject->itrace_synth_opts.add_last_branch)
  1761. perf_header__set_feat(&session->header,
  1762. HEADER_BRANCH_STACK);
  1763. }
  1764. session->header.data_offset = output_data_offset;
  1765. session->header.data_size = inject->bytes_written;
  1766. perf_session__inject_header(session, session->evlist, fd, &inj_fc.fc);
  1767. if (inject->copy_kcore_dir) {
  1768. ret = copy_kcore_dir(inject);
  1769. if (ret) {
  1770. pr_err("Failed to copy kcore\n");
  1771. return ret;
  1772. }
  1773. }
  1774. if (gs->copy_kcore_dir) {
  1775. ret = guest_session__copy_kcore_dir(gs);
  1776. if (ret) {
  1777. pr_err("Failed to copy guest kcore\n");
  1778. return ret;
  1779. }
  1780. }
  1781. }
  1782. return ret;
  1783. }
  1784. int cmd_inject(int argc, const char **argv)
  1785. {
  1786. struct perf_inject inject = {
  1787. .tool = {
  1788. .sample = perf_event__repipe_sample,
  1789. .read = perf_event__repipe_sample,
  1790. .mmap = perf_event__repipe,
  1791. .mmap2 = perf_event__repipe,
  1792. .comm = perf_event__repipe,
  1793. .namespaces = perf_event__repipe,
  1794. .cgroup = perf_event__repipe,
  1795. .fork = perf_event__repipe,
  1796. .exit = perf_event__repipe,
  1797. .lost = perf_event__repipe,
  1798. .lost_samples = perf_event__repipe,
  1799. .aux = perf_event__repipe,
  1800. .itrace_start = perf_event__repipe,
  1801. .aux_output_hw_id = perf_event__repipe,
  1802. .context_switch = perf_event__repipe,
  1803. .throttle = perf_event__repipe,
  1804. .unthrottle = perf_event__repipe,
  1805. .ksymbol = perf_event__repipe,
  1806. .bpf = perf_event__repipe,
  1807. .text_poke = perf_event__repipe,
  1808. .attr = perf_event__repipe_attr,
  1809. .event_update = perf_event__repipe_event_update,
  1810. .tracing_data = perf_event__repipe_op2_synth,
  1811. .finished_round = perf_event__repipe_oe_synth,
  1812. .build_id = perf_event__repipe_op2_synth,
  1813. .id_index = perf_event__repipe_op2_synth,
  1814. .auxtrace_info = perf_event__repipe_op2_synth,
  1815. .auxtrace_error = perf_event__repipe_op2_synth,
  1816. .time_conv = perf_event__repipe_op2_synth,
  1817. .thread_map = perf_event__repipe_op2_synth,
  1818. .cpu_map = perf_event__repipe_op2_synth,
  1819. .stat_config = perf_event__repipe_op2_synth,
  1820. .stat = perf_event__repipe_op2_synth,
  1821. .stat_round = perf_event__repipe_op2_synth,
  1822. .feature = perf_event__repipe_op2_synth,
  1823. .finished_init = perf_event__repipe_op2_synth,
  1824. .compressed = perf_event__repipe_op4_synth,
  1825. .auxtrace = perf_event__repipe_auxtrace,
  1826. },
  1827. .input_name = "-",
  1828. .samples = LIST_HEAD_INIT(inject.samples),
  1829. .output = {
  1830. .path = "-",
  1831. .mode = PERF_DATA_MODE_WRITE,
  1832. .use_stdio = true,
  1833. },
  1834. };
  1835. struct perf_data data = {
  1836. .mode = PERF_DATA_MODE_READ,
  1837. .use_stdio = true,
  1838. };
  1839. int ret;
  1840. bool repipe = true;
  1841. const char *known_build_ids = NULL;
  1842. struct option options[] = {
  1843. OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
  1844. "Inject build-ids into the output stream"),
  1845. OPT_BOOLEAN(0, "buildid-all", &inject.build_id_all,
  1846. "Inject build-ids of all DSOs into the output stream"),
  1847. OPT_STRING(0, "known-build-ids", &known_build_ids,
  1848. "buildid path [,buildid path...]",
  1849. "build-ids to use for given paths"),
  1850. OPT_STRING('i', "input", &inject.input_name, "file",
  1851. "input file name"),
  1852. OPT_STRING('o', "output", &inject.output.path, "file",
  1853. "output file name"),
  1854. OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
  1855. "Merge sched-stat and sched-switch for getting events "
  1856. "where and how long tasks slept"),
  1857. #ifdef HAVE_JITDUMP
  1858. OPT_BOOLEAN('j', "jit", &inject.jit_mode, "merge jitdump files into perf.data file"),
  1859. #endif
  1860. OPT_INCR('v', "verbose", &verbose,
  1861. "be more verbose (show build ids, etc)"),
  1862. OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
  1863. "file", "vmlinux pathname"),
  1864. OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
  1865. "don't load vmlinux even if found"),
  1866. OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file",
  1867. "kallsyms pathname"),
  1868. OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"),
  1869. OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts,
  1870. NULL, "opts", "Instruction Tracing options\n"
  1871. ITRACE_HELP,
  1872. itrace_parse_synth_opts),
  1873. OPT_BOOLEAN(0, "strip", &inject.strip,
  1874. "strip non-synthesized events (use with --itrace)"),
  1875. OPT_CALLBACK_OPTARG(0, "vm-time-correlation", &inject, NULL, "opts",
  1876. "correlate time between VM guests and the host",
  1877. parse_vm_time_correlation),
  1878. OPT_CALLBACK_OPTARG(0, "guest-data", &inject, NULL, "opts",
  1879. "inject events from a guest perf.data file",
  1880. parse_guest_data),
  1881. OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
  1882. "guest mount directory under which every guest os"
  1883. " instance has a subdir"),
  1884. OPT_END()
  1885. };
  1886. const char * const inject_usage[] = {
  1887. "perf inject [<options>]",
  1888. NULL
  1889. };
  1890. #ifndef HAVE_JITDUMP
  1891. set_option_nobuild(options, 'j', "jit", "NO_LIBELF=1", true);
  1892. #endif
  1893. argc = parse_options(argc, argv, options, inject_usage, 0);
  1894. /*
  1895. * Any (unrecognized) arguments left?
  1896. */
  1897. if (argc)
  1898. usage_with_options(inject_usage, options);
  1899. if (inject.strip && !inject.itrace_synth_opts.set) {
  1900. pr_err("--strip option requires --itrace option\n");
  1901. return -1;
  1902. }
  1903. if (symbol__validate_sym_arguments())
  1904. return -1;
  1905. if (inject.in_place_update) {
  1906. if (!strcmp(inject.input_name, "-")) {
  1907. pr_err("Input file name required for in-place updating\n");
  1908. return -1;
  1909. }
  1910. if (strcmp(inject.output.path, "-")) {
  1911. pr_err("Output file name must not be specified for in-place updating\n");
  1912. return -1;
  1913. }
  1914. if (!data.force && !inject.in_place_update_dry_run) {
  1915. pr_err("The input file would be updated in place, "
  1916. "the --force option is required.\n");
  1917. return -1;
  1918. }
  1919. if (!inject.in_place_update_dry_run)
  1920. data.in_place_update = true;
  1921. } else {
  1922. if (strcmp(inject.output.path, "-") && !inject.strip &&
  1923. has_kcore_dir(inject.input_name)) {
  1924. inject.output.is_dir = true;
  1925. inject.copy_kcore_dir = true;
  1926. }
  1927. if (perf_data__open(&inject.output)) {
  1928. perror("failed to create output file");
  1929. return -1;
  1930. }
  1931. }
  1932. data.path = inject.input_name;
  1933. if (!strcmp(inject.input_name, "-") || inject.output.is_pipe) {
  1934. inject.is_pipe = true;
  1935. /*
  1936. * Do not repipe header when input is a regular file
  1937. * since either it can rewrite the header at the end
  1938. * or write a new pipe header.
  1939. */
  1940. if (strcmp(inject.input_name, "-"))
  1941. repipe = false;
  1942. }
  1943. inject.session = __perf_session__new(&data, repipe,
  1944. output_fd(&inject),
  1945. &inject.tool);
  1946. if (IS_ERR(inject.session)) {
  1947. ret = PTR_ERR(inject.session);
  1948. goto out_close_output;
  1949. }
  1950. if (zstd_init(&(inject.session->zstd_data), 0) < 0)
  1951. pr_warning("Decompression initialization failed.\n");
  1952. /* Save original section info before feature bits change */
  1953. ret = save_section_info(&inject);
  1954. if (ret)
  1955. goto out_delete;
  1956. if (!data.is_pipe && inject.output.is_pipe) {
  1957. ret = perf_header__write_pipe(perf_data__fd(&inject.output));
  1958. if (ret < 0) {
  1959. pr_err("Couldn't write a new pipe header.\n");
  1960. goto out_delete;
  1961. }
  1962. ret = perf_event__synthesize_for_pipe(&inject.tool,
  1963. inject.session,
  1964. &inject.output,
  1965. perf_event__repipe);
  1966. if (ret < 0)
  1967. goto out_delete;
  1968. }
  1969. if (inject.build_ids && !inject.build_id_all) {
  1970. /*
  1971. * to make sure the mmap records are ordered correctly
  1972. * and so that the correct especially due to jitted code
  1973. * mmaps. We cannot generate the buildid hit list and
  1974. * inject the jit mmaps at the same time for now.
  1975. */
  1976. inject.tool.ordered_events = true;
  1977. inject.tool.ordering_requires_timestamps = true;
  1978. if (known_build_ids != NULL) {
  1979. inject.known_build_ids =
  1980. perf_inject__parse_known_build_ids(known_build_ids);
  1981. if (inject.known_build_ids == NULL) {
  1982. pr_err("Couldn't parse known build ids.\n");
  1983. goto out_delete;
  1984. }
  1985. }
  1986. }
  1987. if (inject.sched_stat) {
  1988. inject.tool.ordered_events = true;
  1989. }
  1990. #ifdef HAVE_JITDUMP
  1991. if (inject.jit_mode) {
  1992. inject.tool.mmap2 = perf_event__jit_repipe_mmap2;
  1993. inject.tool.mmap = perf_event__jit_repipe_mmap;
  1994. inject.tool.ordered_events = true;
  1995. inject.tool.ordering_requires_timestamps = true;
  1996. /*
  1997. * JIT MMAP injection injects all MMAP events in one go, so it
  1998. * does not obey finished_round semantics.
  1999. */
  2000. inject.tool.finished_round = perf_event__drop_oe;
  2001. }
  2002. #endif
  2003. ret = symbol__init(&inject.session->header.env);
  2004. if (ret < 0)
  2005. goto out_delete;
  2006. ret = __cmd_inject(&inject);
  2007. guest_session__exit(&inject.guest_session);
  2008. out_delete:
  2009. strlist__delete(inject.known_build_ids);
  2010. zstd_fini(&(inject.session->zstd_data));
  2011. perf_session__delete(inject.session);
  2012. out_close_output:
  2013. if (!inject.in_place_update)
  2014. perf_data__close(&inject.output);
  2015. free(inject.itrace_synth_opts.vm_tm_corr_args);
  2016. return ret;
  2017. }