hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/tools/perf/builtin-inject.c
....@@ -8,10 +8,12 @@
88 */
99 #include "builtin.h"
1010
11
-#include "perf.h"
1211 #include "util/color.h"
12
+#include "util/dso.h"
13
+#include "util/vdso.h"
1314 #include "util/evlist.h"
1415 #include "util/evsel.h"
16
+#include "util/map.h"
1517 #include "util/session.h"
1618 #include "util/tool.h"
1719 #include "util/debug.h"
....@@ -19,9 +21,14 @@
1921 #include "util/data.h"
2022 #include "util/auxtrace.h"
2123 #include "util/jit.h"
24
+#include "util/symbol.h"
25
+#include "util/synthetic-events.h"
2226 #include "util/thread.h"
27
+#include "util/namespaces.h"
2328
29
+#include <linux/err.h>
2430 #include <subcmd/parse-options.h>
31
+#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
2532
2633 #include <linux/list.h>
2734 #include <errno.h>
....@@ -31,6 +38,7 @@
3138 struct perf_tool tool;
3239 struct perf_session *session;
3340 bool build_ids;
41
+ bool build_id_all;
3442 bool sched_stat;
3543 bool have_auxtrace;
3644 bool strip;
....@@ -41,13 +49,17 @@
4149 u64 aux_id;
4250 struct list_head samples;
4351 struct itrace_synth_opts itrace_synth_opts;
52
+ char event_copy[PERF_SAMPLE_MAX_SIZE];
4453 };
4554
4655 struct event_entry {
4756 struct list_head node;
4857 u32 tid;
49
- union perf_event event[0];
58
+ union perf_event event[];
5059 };
60
+
61
+static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
62
+ struct machine *machine, u8 cpumode, u32 flags);
5163
5264 static int output_bytes(struct perf_inject *inject, void *buf, size_t sz)
5365 {
....@@ -86,17 +98,22 @@
8698 }
8799 #endif
88100
89
-static int perf_event__repipe_op2_synth(struct perf_tool *tool,
90
- union perf_event *event,
91
- struct perf_session *session
92
- __maybe_unused)
101
+static int perf_event__repipe_op2_synth(struct perf_session *session,
102
+ union perf_event *event)
93103 {
94
- return perf_event__repipe_synth(tool, event);
104
+ return perf_event__repipe_synth(session->tool, event);
105
+}
106
+
107
+static int perf_event__repipe_op4_synth(struct perf_session *session,
108
+ union perf_event *event,
109
+ u64 data __maybe_unused)
110
+{
111
+ return perf_event__repipe_synth(session->tool, event);
95112 }
96113
97114 static int perf_event__repipe_attr(struct perf_tool *tool,
98115 union perf_event *event,
99
- struct perf_evlist **pevlist)
116
+ struct evlist **pevlist)
100117 {
101118 struct perf_inject *inject = container_of(tool, struct perf_inject,
102119 tool);
....@@ -109,6 +126,13 @@
109126 if (!inject->output.is_pipe)
110127 return 0;
111128
129
+ return perf_event__repipe_synth(tool, event);
130
+}
131
+
132
+static int perf_event__repipe_event_update(struct perf_tool *tool,
133
+ union perf_event *event,
134
+ struct evlist **pevlist __maybe_unused)
135
+{
112136 return perf_event__repipe_synth(tool, event);
113137 }
114138
....@@ -133,10 +157,10 @@
133157 return 0;
134158 }
135159
136
-static s64 perf_event__repipe_auxtrace(struct perf_tool *tool,
137
- union perf_event *event,
138
- struct perf_session *session)
160
+static s64 perf_event__repipe_auxtrace(struct perf_session *session,
161
+ union perf_event *event)
139162 {
163
+ struct perf_tool *tool = session->tool;
140164 struct perf_inject *inject = container_of(tool, struct perf_inject,
141165 tool);
142166 int ret;
....@@ -174,9 +198,8 @@
174198 #else
175199
176200 static s64
177
-perf_event__repipe_auxtrace(struct perf_tool *tool __maybe_unused,
178
- union perf_event *event __maybe_unused,
179
- struct perf_session *session __maybe_unused)
201
+perf_event__repipe_auxtrace(struct perf_session *session __maybe_unused,
202
+ union perf_event *event __maybe_unused)
180203 {
181204 pr_err("AUX area tracing not supported\n");
182205 return -EINVAL;
....@@ -213,24 +236,52 @@
213236 return 0;
214237 }
215238
239
+static union perf_event *
240
+perf_inject__cut_auxtrace_sample(struct perf_inject *inject,
241
+ union perf_event *event,
242
+ struct perf_sample *sample)
243
+{
244
+ size_t sz1 = sample->aux_sample.data - (void *)event;
245
+ size_t sz2 = event->header.size - sample->aux_sample.size - sz1;
246
+ union perf_event *ev = (union perf_event *)inject->event_copy;
247
+
248
+ if (sz1 > event->header.size || sz2 > event->header.size ||
249
+ sz1 + sz2 > event->header.size ||
250
+ sz1 < sizeof(struct perf_event_header) + sizeof(u64))
251
+ return event;
252
+
253
+ memcpy(ev, event, sz1);
254
+ memcpy((void *)ev + sz1, (void *)event + event->header.size - sz2, sz2);
255
+ ev->header.size = sz1 + sz2;
256
+ ((u64 *)((void *)ev + sz1))[-1] = 0;
257
+
258
+ return ev;
259
+}
260
+
216261 typedef int (*inject_handler)(struct perf_tool *tool,
217262 union perf_event *event,
218263 struct perf_sample *sample,
219
- struct perf_evsel *evsel,
264
+ struct evsel *evsel,
220265 struct machine *machine);
221266
222267 static int perf_event__repipe_sample(struct perf_tool *tool,
223268 union perf_event *event,
224269 struct perf_sample *sample,
225
- struct perf_evsel *evsel,
270
+ struct evsel *evsel,
226271 struct machine *machine)
227272 {
228
- if (evsel->handler) {
273
+ struct perf_inject *inject = container_of(tool, struct perf_inject,
274
+ tool);
275
+
276
+ if (evsel && evsel->handler) {
229277 inject_handler f = evsel->handler;
230278 return f(tool, event, sample, evsel, machine);
231279 }
232280
233281 build_id__mark_dso_hit(tool, event, sample, evsel, machine);
282
+
283
+ if (inject->itrace_synth_opts.set && sample->aux_sample.size)
284
+ event = perf_inject__cut_auxtrace_sample(inject, event, sample);
234285
235286 return perf_event__repipe_synth(tool, event);
236287 }
....@@ -262,7 +313,7 @@
262313 * if jit marker, then inject jit mmaps and generate ELF images
263314 */
264315 ret = jit_process(inject->session, &inject->output, machine,
265
- event->mmap.filename, sample->pid, &n);
316
+ event->mmap.filename, event->mmap.pid, &n);
266317 if (ret < 0)
267318 return ret;
268319 if (ret) {
....@@ -272,6 +323,69 @@
272323 return perf_event__repipe_mmap(tool, event, sample, machine);
273324 }
274325 #endif
326
+
327
+static struct dso *findnew_dso(int pid, int tid, const char *filename,
328
+ struct dso_id *id, struct machine *machine)
329
+{
330
+ struct thread *thread;
331
+ struct nsinfo *nsi = NULL;
332
+ struct nsinfo *nnsi;
333
+ struct dso *dso;
334
+ bool vdso;
335
+
336
+ thread = machine__findnew_thread(machine, pid, tid);
337
+ if (thread == NULL) {
338
+ pr_err("cannot find or create a task %d/%d.\n", tid, pid);
339
+ return NULL;
340
+ }
341
+
342
+ vdso = is_vdso_map(filename);
343
+ nsi = nsinfo__get(thread->nsinfo);
344
+
345
+ if (vdso) {
346
+ /* The vdso maps are always on the host and not the
347
+ * container. Ensure that we don't use setns to look
348
+ * them up.
349
+ */
350
+ nnsi = nsinfo__copy(nsi);
351
+ if (nnsi) {
352
+ nsinfo__put(nsi);
353
+ nnsi->need_setns = false;
354
+ nsi = nnsi;
355
+ }
356
+ dso = machine__findnew_vdso(machine, thread);
357
+ } else {
358
+ dso = machine__findnew_dso_id(machine, filename, id);
359
+ }
360
+
361
+ if (dso) {
362
+ nsinfo__put(dso->nsinfo);
363
+ dso->nsinfo = nsi;
364
+ } else
365
+ nsinfo__put(nsi);
366
+
367
+ thread__put(thread);
368
+ return dso;
369
+}
370
+
371
+static int perf_event__repipe_buildid_mmap(struct perf_tool *tool,
372
+ union perf_event *event,
373
+ struct perf_sample *sample,
374
+ struct machine *machine)
375
+{
376
+ struct dso *dso;
377
+
378
+ dso = findnew_dso(event->mmap.pid, event->mmap.tid,
379
+ event->mmap.filename, NULL, machine);
380
+
381
+ if (dso && !dso->hit) {
382
+ dso->hit = 1;
383
+ dso__inject_build_id(dso, tool, machine, sample->cpumode, 0);
384
+ dso__put(dso);
385
+ }
386
+
387
+ return perf_event__repipe(tool, event, sample, machine);
388
+}
275389
276390 static int perf_event__repipe_mmap2(struct perf_tool *tool,
277391 union perf_event *event,
....@@ -300,7 +414,7 @@
300414 * if jit marker, then inject jit mmaps and generate ELF images
301415 */
302416 ret = jit_process(inject->session, &inject->output, machine,
303
- event->mmap2.filename, sample->pid, &n);
417
+ event->mmap2.filename, event->mmap2.pid, &n);
304418 if (ret < 0)
305419 return ret;
306420 if (ret) {
....@@ -310,6 +424,34 @@
310424 return perf_event__repipe_mmap2(tool, event, sample, machine);
311425 }
312426 #endif
427
+
428
+static int perf_event__repipe_buildid_mmap2(struct perf_tool *tool,
429
+ union perf_event *event,
430
+ struct perf_sample *sample,
431
+ struct machine *machine)
432
+{
433
+ struct dso_id dso_id = {
434
+ .maj = event->mmap2.maj,
435
+ .min = event->mmap2.min,
436
+ .ino = event->mmap2.ino,
437
+ .ino_generation = event->mmap2.ino_generation,
438
+ };
439
+ struct dso *dso;
440
+
441
+ dso = findnew_dso(event->mmap2.pid, event->mmap2.tid,
442
+ event->mmap2.filename, &dso_id, machine);
443
+
444
+ if (dso && !dso->hit) {
445
+ dso->hit = 1;
446
+ dso__inject_build_id(dso, tool, machine, sample->cpumode,
447
+ event->mmap2.flags);
448
+ dso__put(dso);
449
+ }
450
+
451
+ perf_event__repipe(tool, event, sample, machine);
452
+
453
+ return 0;
454
+}
313455
314456 static int perf_event__repipe_fork(struct perf_tool *tool,
315457 union perf_event *event,
....@@ -362,60 +504,49 @@
362504 return err;
363505 }
364506
365
-static int perf_event__repipe_tracing_data(struct perf_tool *tool,
366
- union perf_event *event,
367
- struct perf_session *session)
507
+static int perf_event__repipe_tracing_data(struct perf_session *session,
508
+ union perf_event *event)
368509 {
369510 int err;
370511
371
- perf_event__repipe_synth(tool, event);
372
- err = perf_event__process_tracing_data(tool, event, session);
373
-
374
- return err;
375
-}
376
-
377
-static int perf_event__repipe_id_index(struct perf_tool *tool,
378
- union perf_event *event,
379
- struct perf_session *session)
380
-{
381
- int err;
382
-
383
- perf_event__repipe_synth(tool, event);
384
- err = perf_event__process_id_index(tool, event, session);
512
+ perf_event__repipe_synth(session->tool, event);
513
+ err = perf_event__process_tracing_data(session, event);
385514
386515 return err;
387516 }
388517
389518 static int dso__read_build_id(struct dso *dso)
390519 {
520
+ struct nscookie nsc;
521
+
391522 if (dso->has_build_id)
392523 return 0;
393524
394
- if (filename__read_build_id(dso->long_name, dso->build_id,
395
- sizeof(dso->build_id)) > 0) {
525
+ nsinfo__mountns_enter(dso->nsinfo, &nsc);
526
+ if (filename__read_build_id(dso->long_name, &dso->bid) > 0)
396527 dso->has_build_id = true;
397
- return 0;
398
- }
528
+ nsinfo__mountns_exit(&nsc);
399529
400
- return -1;
530
+ return dso->has_build_id ? 0 : -1;
401531 }
402532
403533 static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
404
- struct machine *machine)
534
+ struct machine *machine, u8 cpumode, u32 flags)
405535 {
406
- u16 misc = PERF_RECORD_MISC_USER;
407536 int err;
537
+
538
+ if (is_anon_memory(dso->long_name) || flags & MAP_HUGETLB)
539
+ return 0;
540
+ if (is_no_dso_memory(dso->long_name))
541
+ return 0;
408542
409543 if (dso__read_build_id(dso) < 0) {
410544 pr_debug("no build_id found for %s\n", dso->long_name);
411545 return -1;
412546 }
413547
414
- if (dso->kernel)
415
- misc = PERF_RECORD_MISC_KERNEL;
416
-
417
- err = perf_event__synthesize_build_id(tool, dso, misc, perf_event__repipe,
418
- machine);
548
+ err = perf_event__synthesize_build_id(tool, dso, cpumode,
549
+ perf_event__repipe, machine);
419550 if (err) {
420551 pr_err("Can't synthesize build_id event for %s\n", dso->long_name);
421552 return -1;
....@@ -424,11 +555,10 @@
424555 return 0;
425556 }
426557
427
-static int perf_event__inject_buildid(struct perf_tool *tool,
428
- union perf_event *event,
429
- struct perf_sample *sample,
430
- struct perf_evsel *evsel __maybe_unused,
431
- struct machine *machine)
558
+int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event,
559
+ struct perf_sample *sample,
560
+ struct evsel *evsel __maybe_unused,
561
+ struct machine *machine)
432562 {
433563 struct addr_location al;
434564 struct thread *thread;
....@@ -443,19 +573,8 @@
443573 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
444574 if (!al.map->dso->hit) {
445575 al.map->dso->hit = 1;
446
- if (map__load(al.map) >= 0) {
447
- dso__inject_build_id(al.map->dso, tool, machine);
448
- /*
449
- * If this fails, too bad, let the other side
450
- * account this as unresolved.
451
- */
452
- } else {
453
-#ifdef HAVE_LIBELF_SUPPORT
454
- pr_warning("no symbols found in %s, maybe "
455
- "install a debug package?\n",
456
- al.map->dso->long_name);
457
-#endif
458
- }
576
+ dso__inject_build_id(al.map->dso, tool, machine,
577
+ sample->cpumode, al.map->flags);
459578 }
460579 }
461580
....@@ -468,7 +587,7 @@
468587 static int perf_inject__sched_process_exit(struct perf_tool *tool,
469588 union perf_event *event __maybe_unused,
470589 struct perf_sample *sample,
471
- struct perf_evsel *evsel __maybe_unused,
590
+ struct evsel *evsel __maybe_unused,
472591 struct machine *machine __maybe_unused)
473592 {
474593 struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
....@@ -488,7 +607,7 @@
488607 static int perf_inject__sched_switch(struct perf_tool *tool,
489608 union perf_event *event,
490609 struct perf_sample *sample,
491
- struct perf_evsel *evsel,
610
+ struct evsel *evsel,
492611 struct machine *machine)
493612 {
494613 struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
....@@ -512,14 +631,14 @@
512631 static int perf_inject__sched_stat(struct perf_tool *tool,
513632 union perf_event *event __maybe_unused,
514633 struct perf_sample *sample,
515
- struct perf_evsel *evsel,
634
+ struct evsel *evsel,
516635 struct machine *machine)
517636 {
518637 struct event_entry *ent;
519638 union perf_event *event_sw;
520639 struct perf_sample sample_sw;
521640 struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
522
- u32 pid = perf_evsel__intval(evsel, sample, "pid");
641
+ u32 pid = evsel__intval(evsel, sample, "pid");
523642
524643 list_for_each_entry(ent, &inject->samples, node) {
525644 if (pid == ent->tid)
....@@ -529,12 +648,12 @@
529648 return 0;
530649 found:
531650 event_sw = &ent->event[0];
532
- perf_evsel__parse_sample(evsel, event_sw, &sample_sw);
651
+ evsel__parse_sample(evsel, event_sw, &sample_sw);
533652
534653 sample_sw.period = sample->period;
535654 sample_sw.time = sample->time;
536
- perf_event__synthesize_sample(event_sw, evsel->attr.sample_type,
537
- evsel->attr.read_format, &sample_sw);
655
+ perf_event__synthesize_sample(event_sw, evsel->core.attr.sample_type,
656
+ evsel->core.attr.read_format, &sample_sw);
538657 build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
539658 return perf_event__repipe(tool, event_sw, &sample_sw, machine);
540659 }
....@@ -544,11 +663,10 @@
544663 session_done = 1;
545664 }
546665
547
-static int perf_evsel__check_stype(struct perf_evsel *evsel,
548
- u64 sample_type, const char *sample_msg)
666
+static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg)
549667 {
550
- struct perf_event_attr *attr = &evsel->attr;
551
- const char *name = perf_evsel__name(evsel);
668
+ struct perf_event_attr *attr = &evsel->core.attr;
669
+ const char *name = evsel__name(evsel);
552670
553671 if (!(attr->sample_type & sample_type)) {
554672 pr_err("Samples for %s event do not have %s attribute set.",
....@@ -562,7 +680,7 @@
562680 static int drop_sample(struct perf_tool *tool __maybe_unused,
563681 union perf_event *event __maybe_unused,
564682 struct perf_sample *sample __maybe_unused,
565
- struct perf_evsel *evsel __maybe_unused,
683
+ struct evsel *evsel __maybe_unused,
566684 struct machine *machine __maybe_unused)
567685 {
568686 return 0;
....@@ -570,65 +688,13 @@
570688
571689 static void strip_init(struct perf_inject *inject)
572690 {
573
- struct perf_evlist *evlist = inject->session->evlist;
574
- struct perf_evsel *evsel;
691
+ struct evlist *evlist = inject->session->evlist;
692
+ struct evsel *evsel;
575693
576694 inject->tool.context_switch = perf_event__drop;
577695
578696 evlist__for_each_entry(evlist, evsel)
579697 evsel->handler = drop_sample;
580
-}
581
-
582
-static bool has_tracking(struct perf_evsel *evsel)
583
-{
584
- return evsel->attr.mmap || evsel->attr.mmap2 || evsel->attr.comm ||
585
- evsel->attr.task;
586
-}
587
-
588
-#define COMPAT_MASK (PERF_SAMPLE_ID | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \
589
- PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_IDENTIFIER)
590
-
591
-/*
592
- * In order that the perf.data file is parsable, tracking events like MMAP need
593
- * their selected event to exist, except if there is only 1 selected event left
594
- * and it has a compatible sample type.
595
- */
596
-static bool ok_to_remove(struct perf_evlist *evlist,
597
- struct perf_evsel *evsel_to_remove)
598
-{
599
- struct perf_evsel *evsel;
600
- int cnt = 0;
601
- bool ok = false;
602
-
603
- if (!has_tracking(evsel_to_remove))
604
- return true;
605
-
606
- evlist__for_each_entry(evlist, evsel) {
607
- if (evsel->handler != drop_sample) {
608
- cnt += 1;
609
- if ((evsel->attr.sample_type & COMPAT_MASK) ==
610
- (evsel_to_remove->attr.sample_type & COMPAT_MASK))
611
- ok = true;
612
- }
613
- }
614
-
615
- return ok && cnt == 1;
616
-}
617
-
618
-static void strip_fini(struct perf_inject *inject)
619
-{
620
- struct perf_evlist *evlist = inject->session->evlist;
621
- struct perf_evsel *evsel, *tmp;
622
-
623
- /* Remove non-synthesized evsels if possible */
624
- evlist__for_each_entry_safe(evlist, tmp, evsel) {
625
- if (evsel->handler == drop_sample &&
626
- ok_to_remove(evlist, evsel)) {
627
- pr_debug("Deleting %s\n", perf_evsel__name(evsel));
628
- perf_evlist__remove(evlist, evsel);
629
- perf_evsel__delete(evsel);
630
- }
631
- }
632698 }
633699
634700 static int __cmd_inject(struct perf_inject *inject)
....@@ -642,7 +708,7 @@
642708 signal(SIGINT, sig_handler);
643709
644710 if (inject->build_ids || inject->sched_stat ||
645
- inject->itrace_synth_opts.set) {
711
+ inject->itrace_synth_opts.set || inject->build_id_all) {
646712 inject->tool.mmap = perf_event__repipe_mmap;
647713 inject->tool.mmap2 = perf_event__repipe_mmap2;
648714 inject->tool.fork = perf_event__repipe_fork;
....@@ -651,16 +717,19 @@
651717
652718 output_data_offset = session->header.data_offset;
653719
654
- if (inject->build_ids) {
720
+ if (inject->build_id_all) {
721
+ inject->tool.mmap = perf_event__repipe_buildid_mmap;
722
+ inject->tool.mmap2 = perf_event__repipe_buildid_mmap2;
723
+ } else if (inject->build_ids) {
655724 inject->tool.sample = perf_event__inject_buildid;
656725 } else if (inject->sched_stat) {
657
- struct perf_evsel *evsel;
726
+ struct evsel *evsel;
658727
659728 evlist__for_each_entry(session->evlist, evsel) {
660
- const char *name = perf_evsel__name(evsel);
729
+ const char *name = evsel__name(evsel);
661730
662731 if (!strcmp(name, "sched:sched_switch")) {
663
- if (perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
732
+ if (evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
664733 return -EINVAL;
665734
666735 evsel->handler = perf_inject__sched_switch;
....@@ -675,7 +744,7 @@
675744 inject->tool.comm = perf_event__repipe_comm;
676745 inject->tool.namespaces = perf_event__repipe_namespaces;
677746 inject->tool.exit = perf_event__repipe_exit;
678
- inject->tool.id_index = perf_event__repipe_id_index;
747
+ inject->tool.id_index = perf_event__process_id_index;
679748 inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
680749 inject->tool.auxtrace = perf_event__process_auxtrace;
681750 inject->tool.aux = perf_event__drop_aux;
....@@ -683,7 +752,7 @@
683752 inject->tool.ordered_events = true;
684753 inject->tool.ordering_requires_timestamps = true;
685754 /* Allow space in the header for new attributes */
686
- output_data_offset = 4096;
755
+ output_data_offset = roundup(8192 + session->header.data_offset, 4096);
687756 if (inject->strip)
688757 strip_init(inject);
689758 }
....@@ -711,27 +780,15 @@
711780 dsos__hit_all(session);
712781 /*
713782 * The AUX areas have been removed and replaced with
714
- * synthesized hardware events, so clear the feature flag and
715
- * remove the evsel.
783
+ * synthesized hardware events, so clear the feature flag.
716784 */
717785 if (inject->itrace_synth_opts.set) {
718
- struct perf_evsel *evsel;
719
-
720786 perf_header__clear_feat(&session->header,
721787 HEADER_AUXTRACE);
722
- if (inject->itrace_synth_opts.last_branch)
788
+ if (inject->itrace_synth_opts.last_branch ||
789
+ inject->itrace_synth_opts.add_last_branch)
723790 perf_header__set_feat(&session->header,
724791 HEADER_BRANCH_STACK);
725
- evsel = perf_evlist__id2evsel_strict(session->evlist,
726
- inject->aux_id);
727
- if (evsel) {
728
- pr_debug("Deleting %s\n",
729
- perf_evsel__name(evsel));
730
- perf_evlist__remove(session->evlist, evsel);
731
- perf_evsel__delete(evsel);
732
- }
733
- if (inject->strip)
734
- strip_fini(inject);
735792 }
736793 session->header.data_offset = output_data_offset;
737794 session->header.data_size = inject->bytes_written;
....@@ -746,9 +803,12 @@
746803 struct perf_inject inject = {
747804 .tool = {
748805 .sample = perf_event__repipe_sample,
806
+ .read = perf_event__repipe_sample,
749807 .mmap = perf_event__repipe,
750808 .mmap2 = perf_event__repipe,
751809 .comm = perf_event__repipe,
810
+ .namespaces = perf_event__repipe,
811
+ .cgroup = perf_event__repipe,
752812 .fork = perf_event__repipe,
753813 .exit = perf_event__repipe,
754814 .lost = perf_event__repipe,
....@@ -756,27 +816,34 @@
756816 .aux = perf_event__repipe,
757817 .itrace_start = perf_event__repipe,
758818 .context_switch = perf_event__repipe,
759
- .read = perf_event__repipe_sample,
760819 .throttle = perf_event__repipe,
761820 .unthrottle = perf_event__repipe,
821
+ .ksymbol = perf_event__repipe,
822
+ .bpf = perf_event__repipe,
823
+ .text_poke = perf_event__repipe,
762824 .attr = perf_event__repipe_attr,
825
+ .event_update = perf_event__repipe_event_update,
763826 .tracing_data = perf_event__repipe_op2_synth,
764
- .auxtrace_info = perf_event__repipe_op2_synth,
765
- .auxtrace = perf_event__repipe_auxtrace,
766
- .auxtrace_error = perf_event__repipe_op2_synth,
767
- .time_conv = perf_event__repipe_op2_synth,
768827 .finished_round = perf_event__repipe_oe_synth,
769828 .build_id = perf_event__repipe_op2_synth,
770829 .id_index = perf_event__repipe_op2_synth,
830
+ .auxtrace_info = perf_event__repipe_op2_synth,
831
+ .auxtrace_error = perf_event__repipe_op2_synth,
832
+ .time_conv = perf_event__repipe_op2_synth,
833
+ .thread_map = perf_event__repipe_op2_synth,
834
+ .cpu_map = perf_event__repipe_op2_synth,
835
+ .stat_config = perf_event__repipe_op2_synth,
836
+ .stat = perf_event__repipe_op2_synth,
837
+ .stat_round = perf_event__repipe_op2_synth,
771838 .feature = perf_event__repipe_op2_synth,
839
+ .compressed = perf_event__repipe_op4_synth,
840
+ .auxtrace = perf_event__repipe_auxtrace,
772841 },
773842 .input_name = "-",
774843 .samples = LIST_HEAD_INIT(inject.samples),
775844 .output = {
776
- .file = {
777
- .path = "-",
778
- },
779
- .mode = PERF_DATA_MODE_WRITE,
845
+ .path = "-",
846
+ .mode = PERF_DATA_MODE_WRITE,
780847 },
781848 };
782849 struct perf_data data = {
....@@ -787,9 +854,11 @@
787854 struct option options[] = {
788855 OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
789856 "Inject build-ids into the output stream"),
857
+ OPT_BOOLEAN(0, "buildid-all", &inject.build_id_all,
858
+ "Inject build-ids of all DSOs into the output stream"),
790859 OPT_STRING('i', "input", &inject.input_name, "file",
791860 "input file name"),
792
- OPT_STRING('o', "output", &inject.output.file.path, "file",
861
+ OPT_STRING('o', "output", &inject.output.path, "file",
793862 "output file name"),
794863 OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
795864 "Merge sched-stat and sched-switch for getting events "
....@@ -803,7 +872,8 @@
803872 "kallsyms pathname"),
804873 OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"),
805874 OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts,
806
- NULL, "opts", "Instruction Tracing options",
875
+ NULL, "opts", "Instruction Tracing options\n"
876
+ ITRACE_HELP,
807877 itrace_parse_synth_opts),
808878 OPT_BOOLEAN(0, "strip", &inject.strip,
809879 "strip non-synthesized events (use with --itrace)"),
....@@ -834,14 +904,17 @@
834904 return -1;
835905 }
836906
837
- inject.tool.ordered_events = inject.sched_stat;
907
+ data.path = inject.input_name;
908
+ inject.session = perf_session__new(&data, inject.output.is_pipe, &inject.tool);
909
+ if (IS_ERR(inject.session)) {
910
+ ret = PTR_ERR(inject.session);
911
+ goto out_close_output;
912
+ }
838913
839
- data.file.path = inject.input_name;
840
- inject.session = perf_session__new(&data, true, &inject.tool);
841
- if (inject.session == NULL)
842
- return -1;
914
+ if (zstd_init(&(inject.session->zstd_data), 0) < 0)
915
+ pr_warning("Decompression initialization failed.\n");
843916
844
- if (inject.build_ids) {
917
+ if (inject.build_ids && !inject.build_id_all) {
845918 /*
846919 * to make sure the mmap records are ordered correctly
847920 * and so that the correct especially due to jitted code
....@@ -851,6 +924,11 @@
851924 inject.tool.ordered_events = true;
852925 inject.tool.ordering_requires_timestamps = true;
853926 }
927
+
928
+ if (inject.sched_stat) {
929
+ inject.tool.ordered_events = true;
930
+ }
931
+
854932 #ifdef HAVE_JITDUMP
855933 if (inject.jit_mode) {
856934 inject.tool.mmap2 = perf_event__jit_repipe_mmap2;
....@@ -871,6 +949,9 @@
871949 ret = __cmd_inject(&inject);
872950
873951 out_delete:
952
+ zstd_fini(&(inject.session->zstd_data));
874953 perf_session__delete(inject.session);
954
+out_close_output:
955
+ perf_data__close(&inject.output);
875956 return ret;
876957 }