hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/tools/perf/util/jitdump.c
....@@ -2,6 +2,7 @@
22 #include <sys/sysmacros.h>
33 #include <sys/types.h>
44 #include <errno.h>
5
+#include <libgen.h>
56 #include <stdio.h>
67 #include <stdlib.h>
78 #include <string.h>
....@@ -13,7 +14,7 @@
1314 #include <sys/mman.h>
1415 #include <linux/stringify.h>
1516
16
-#include "util.h"
17
+#include "build-id.h"
1718 #include "event.h"
1819 #include "debug.h"
1920 #include "evlist.h"
....@@ -25,9 +26,10 @@
2526 #include "jit.h"
2627 #include "jitdump.h"
2728 #include "genelf.h"
28
-#include "../builtin.h"
29
+#include "thread.h"
2930
30
-#include "sane_ctype.h"
31
+#include <linux/ctype.h>
32
+#include <linux/zalloc.h>
3133
3234 struct jit_buf_desc {
3335 struct perf_data *output;
....@@ -38,7 +40,7 @@
3840 uint64_t sample_type;
3941 size_t bufsize;
4042 FILE *in;
41
- bool needs_bswap; /* handles cross-endianess */
43
+ bool needs_bswap; /* handles cross-endianness */
4244 bool use_arch_timestamp;
4345 void *debug_data;
4446 void *unwinding_data;
....@@ -56,7 +58,7 @@
5658 unsigned long vma;
5759 unsigned int lineno;
5860 /* The filename format is unspecified, absolute path, relative etc. */
59
- char const filename[0];
61
+ char const filename[];
6062 };
6163
6264 struct jit_tool {
....@@ -116,13 +118,13 @@
116118 static int
117119 jit_validate_events(struct perf_session *session)
118120 {
119
- struct perf_evsel *evsel;
121
+ struct evsel *evsel;
120122
121123 /*
122124 * check that all events use CLOCK_MONOTONIC
123125 */
124126 evlist__for_each_entry(session->evlist, evsel) {
125
- if (evsel->attr.use_clockid == 0 || evsel->attr.clockid != CLOCK_MONOTONIC)
127
+ if (evsel->core.attr.use_clockid == 0 || evsel->core.attr.clockid != CLOCK_MONOTONIC)
126128 return -1;
127129 }
128130 return 0;
....@@ -367,17 +369,31 @@
367369
368370 static uint64_t convert_timestamp(struct jit_buf_desc *jd, uint64_t timestamp)
369371 {
370
- struct perf_tsc_conversion tc;
372
+ struct perf_tsc_conversion tc = { .time_shift = 0, };
373
+ struct perf_record_time_conv *time_conv = &jd->session->time_conv;
371374
372375 if (!jd->use_arch_timestamp)
373376 return timestamp;
374377
375
- tc.time_shift = jd->session->time_conv.time_shift;
376
- tc.time_mult = jd->session->time_conv.time_mult;
377
- tc.time_zero = jd->session->time_conv.time_zero;
378
+ tc.time_shift = time_conv->time_shift;
379
+ tc.time_mult = time_conv->time_mult;
380
+ tc.time_zero = time_conv->time_zero;
378381
379
- if (!tc.time_mult)
380
- return 0;
382
+ /*
383
+ * The event TIME_CONV was extended for the fields from "time_cycles"
384
+ * when supported cap_user_time_short, for backward compatibility,
385
+ * checks the event size and assigns these extended fields if these
386
+ * fields are contained in the event.
387
+ */
388
+ if (event_contains(*time_conv, time_cycles)) {
389
+ tc.time_cycles = time_conv->time_cycles;
390
+ tc.time_mask = time_conv->time_mask;
391
+ tc.cap_user_time_zero = time_conv->cap_user_time_zero;
392
+ tc.cap_user_time_short = time_conv->cap_user_time_short;
393
+
394
+ if (!tc.cap_user_time_zero)
395
+ return 0;
396
+ }
381397
382398 return tsc_to_perf_time(timestamp, &tc);
383399 }
....@@ -430,14 +446,12 @@
430446 jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size);
431447
432448 if (jd->debug_data && jd->nr_debug_entries) {
433
- free(jd->debug_data);
434
- jd->debug_data = NULL;
449
+ zfree(&jd->debug_data);
435450 jd->nr_debug_entries = 0;
436451 }
437452
438453 if (jd->unwinding_data && jd->eh_frame_hdr_size) {
439
- free(jd->unwinding_data);
440
- jd->unwinding_data = NULL;
454
+ zfree(&jd->unwinding_data);
441455 jd->eh_frame_hdr_size = 0;
442456 jd->unwinding_mapped_size = 0;
443457 jd->unwinding_size = 0;
....@@ -750,6 +764,28 @@
750764 return 0;
751765 }
752766
767
+static void jit_add_pid(struct machine *machine, pid_t pid)
768
+{
769
+ struct thread *thread = machine__findnew_thread(machine, pid, pid);
770
+
771
+ if (!thread) {
772
+ pr_err("%s: thread %d not found or created\n", __func__, pid);
773
+ return;
774
+ }
775
+
776
+ thread->priv = (void *)1;
777
+}
778
+
779
+static bool jit_has_pid(struct machine *machine, pid_t pid)
780
+{
781
+ struct thread *thread = machine__find_thread(machine, pid, pid);
782
+
783
+ if (!thread)
784
+ return 0;
785
+
786
+ return (bool)thread->priv;
787
+}
788
+
753789 int
754790 jit_process(struct perf_session *session,
755791 struct perf_data *output,
....@@ -758,15 +794,20 @@
758794 pid_t pid,
759795 u64 *nbytes)
760796 {
761
- struct perf_evsel *first;
797
+ struct evsel *first;
762798 struct jit_buf_desc jd;
763799 int ret;
764800
765801 /*
766802 * first, detect marker mmap (i.e., the jitdump mmap)
767803 */
768
- if (jit_detect(filename, pid))
804
+ if (jit_detect(filename, pid)) {
805
+ // Strip //anon* mmaps if we processed a jitdump for this pid
806
+ if (jit_has_pid(machine, pid) && (strncmp(filename, "//anon", 6) == 0))
807
+ return 1;
808
+
769809 return 0;
810
+ }
770811
771812 memset(&jd, 0, sizeof(jd));
772813
....@@ -778,13 +819,14 @@
778819 * track sample_type to compute id_all layout
779820 * perf sets the same sample type to all events as of now
780821 */
781
- first = perf_evlist__first(session->evlist);
782
- jd.sample_type = first->attr.sample_type;
822
+ first = evlist__first(session->evlist);
823
+ jd.sample_type = first->core.attr.sample_type;
783824
784825 *nbytes = 0;
785826
786827 ret = jit_inject(&jd, filename);
787828 if (!ret) {
829
+ jit_add_pid(machine, pid);
788830 *nbytes = jd.bytes_written;
789831 ret = 1;
790832 }