diff options
Diffstat (limited to 'tools/perf/builtin-inject.c')
-rw-r--r-- | tools/perf/builtin-inject.c | 118 |
1 files changed, 72 insertions, 46 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 8dfc12bb119..09c106193e6 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include "perf.h" | 10 | #include "perf.h" |
11 | #include "util/session.h" | 11 | #include "util/session.h" |
12 | #include "util/tool.h" | ||
12 | #include "util/debug.h" | 13 | #include "util/debug.h" |
13 | 14 | ||
14 | #include "util/parse-options.h" | 15 | #include "util/parse-options.h" |
@@ -16,8 +17,9 @@ | |||
16 | static char const *input_name = "-"; | 17 | static char const *input_name = "-"; |
17 | static bool inject_build_ids; | 18 | static bool inject_build_ids; |
18 | 19 | ||
19 | static int perf_event__repipe_synth(union perf_event *event, | 20 | static int perf_event__repipe_synth(struct perf_tool *tool __used, |
20 | struct perf_session *session __used) | 21 | union perf_event *event, |
22 | struct machine *machine __used) | ||
21 | { | 23 | { |
22 | uint32_t size; | 24 | uint32_t size; |
23 | void *buf = event; | 25 | void *buf = event; |
@@ -36,41 +38,70 @@ static int perf_event__repipe_synth(union perf_event *event, | |||
36 | return 0; | 38 | return 0; |
37 | } | 39 | } |
38 | 40 | ||
39 | static int perf_event__repipe(union perf_event *event, | 41 | static int perf_event__repipe_op2_synth(struct perf_tool *tool, |
42 | union perf_event *event, | ||
43 | struct perf_session *session __used) | ||
44 | { | ||
45 | return perf_event__repipe_synth(tool, event, NULL); | ||
46 | } | ||
47 | |||
48 | static int perf_event__repipe_event_type_synth(struct perf_tool *tool, | ||
49 | union perf_event *event) | ||
50 | { | ||
51 | return perf_event__repipe_synth(tool, event, NULL); | ||
52 | } | ||
53 | |||
54 | static int perf_event__repipe_tracing_data_synth(union perf_event *event, | ||
55 | struct perf_session *session __used) | ||
56 | { | ||
57 | return perf_event__repipe_synth(NULL, event, NULL); | ||
58 | } | ||
59 | |||
60 | static int perf_event__repipe_attr(union perf_event *event, | ||
61 | struct perf_evlist **pevlist __used) | ||
62 | { | ||
63 | return perf_event__repipe_synth(NULL, event, NULL); | ||
64 | } | ||
65 | |||
66 | static int perf_event__repipe(struct perf_tool *tool, | ||
67 | union perf_event *event, | ||
40 | struct perf_sample *sample __used, | 68 | struct perf_sample *sample __used, |
41 | struct perf_session *session) | 69 | struct machine *machine) |
42 | { | 70 | { |
43 | return perf_event__repipe_synth(event, session); | 71 | return perf_event__repipe_synth(tool, event, machine); |
44 | } | 72 | } |
45 | 73 | ||
46 | static int perf_event__repipe_sample(union perf_event *event, | 74 | static int perf_event__repipe_sample(struct perf_tool *tool, |
75 | union perf_event *event, | ||
47 | struct perf_sample *sample __used, | 76 | struct perf_sample *sample __used, |
48 | struct perf_evsel *evsel __used, | 77 | struct perf_evsel *evsel __used, |
49 | struct perf_session *session) | 78 | struct machine *machine) |
50 | { | 79 | { |
51 | return perf_event__repipe_synth(event, session); | 80 | return perf_event__repipe_synth(tool, event, machine); |
52 | } | 81 | } |
53 | 82 | ||
54 | static int perf_event__repipe_mmap(union perf_event *event, | 83 | static int perf_event__repipe_mmap(struct perf_tool *tool, |
84 | union perf_event *event, | ||
55 | struct perf_sample *sample, | 85 | struct perf_sample *sample, |
56 | struct perf_session *session) | 86 | struct machine *machine) |
57 | { | 87 | { |
58 | int err; | 88 | int err; |
59 | 89 | ||
60 | err = perf_event__process_mmap(event, sample, session); | 90 | err = perf_event__process_mmap(tool, event, sample, machine); |
61 | perf_event__repipe(event, sample, session); | 91 | perf_event__repipe(tool, event, sample, machine); |
62 | 92 | ||
63 | return err; | 93 | return err; |
64 | } | 94 | } |
65 | 95 | ||
66 | static int perf_event__repipe_task(union perf_event *event, | 96 | static int perf_event__repipe_task(struct perf_tool *tool, |
97 | union perf_event *event, | ||
67 | struct perf_sample *sample, | 98 | struct perf_sample *sample, |
68 | struct perf_session *session) | 99 | struct machine *machine) |
69 | { | 100 | { |
70 | int err; | 101 | int err; |
71 | 102 | ||
72 | err = perf_event__process_task(event, sample, session); | 103 | err = perf_event__process_task(tool, event, sample, machine); |
73 | perf_event__repipe(event, sample, session); | 104 | perf_event__repipe(tool, event, sample, machine); |
74 | 105 | ||
75 | return err; | 106 | return err; |
76 | } | 107 | } |
@@ -80,7 +111,7 @@ static int perf_event__repipe_tracing_data(union perf_event *event, | |||
80 | { | 111 | { |
81 | int err; | 112 | int err; |
82 | 113 | ||
83 | perf_event__repipe_synth(event, session); | 114 | perf_event__repipe_synth(NULL, event, NULL); |
84 | err = perf_event__process_tracing_data(event, session); | 115 | err = perf_event__process_tracing_data(event, session); |
85 | 116 | ||
86 | return err; | 117 | return err; |
@@ -100,10 +131,10 @@ static int dso__read_build_id(struct dso *self) | |||
100 | return -1; | 131 | return -1; |
101 | } | 132 | } |
102 | 133 | ||
103 | static int dso__inject_build_id(struct dso *self, struct perf_session *session) | 134 | static int dso__inject_build_id(struct dso *self, struct perf_tool *tool, |
135 | struct machine *machine) | ||
104 | { | 136 | { |
105 | u16 misc = PERF_RECORD_MISC_USER; | 137 | u16 misc = PERF_RECORD_MISC_USER; |
106 | struct machine *machine; | ||
107 | int err; | 138 | int err; |
108 | 139 | ||
109 | if (dso__read_build_id(self) < 0) { | 140 | if (dso__read_build_id(self) < 0) { |
@@ -111,17 +142,11 @@ static int dso__inject_build_id(struct dso *self, struct perf_session *session) | |||
111 | return -1; | 142 | return -1; |
112 | } | 143 | } |
113 | 144 | ||
114 | machine = perf_session__find_host_machine(session); | ||
115 | if (machine == NULL) { | ||
116 | pr_err("Can't find machine for session\n"); | ||
117 | return -1; | ||
118 | } | ||
119 | |||
120 | if (self->kernel) | 145 | if (self->kernel) |
121 | misc = PERF_RECORD_MISC_KERNEL; | 146 | misc = PERF_RECORD_MISC_KERNEL; |
122 | 147 | ||
123 | err = perf_event__synthesize_build_id(self, misc, perf_event__repipe, | 148 | err = perf_event__synthesize_build_id(tool, self, misc, perf_event__repipe, |
124 | machine, session); | 149 | machine); |
125 | if (err) { | 150 | if (err) { |
126 | pr_err("Can't synthesize build_id event for %s\n", self->long_name); | 151 | pr_err("Can't synthesize build_id event for %s\n", self->long_name); |
127 | return -1; | 152 | return -1; |
@@ -130,10 +155,11 @@ static int dso__inject_build_id(struct dso *self, struct perf_session *session) | |||
130 | return 0; | 155 | return 0; |
131 | } | 156 | } |
132 | 157 | ||
133 | static int perf_event__inject_buildid(union perf_event *event, | 158 | static int perf_event__inject_buildid(struct perf_tool *tool, |
159 | union perf_event *event, | ||
134 | struct perf_sample *sample, | 160 | struct perf_sample *sample, |
135 | struct perf_evsel *evsel __used, | 161 | struct perf_evsel *evsel __used, |
136 | struct perf_session *session) | 162 | struct machine *machine) |
137 | { | 163 | { |
138 | struct addr_location al; | 164 | struct addr_location al; |
139 | struct thread *thread; | 165 | struct thread *thread; |
@@ -141,21 +167,21 @@ static int perf_event__inject_buildid(union perf_event *event, | |||
141 | 167 | ||
142 | cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 168 | cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
143 | 169 | ||
144 | thread = perf_session__findnew(session, event->ip.pid); | 170 | thread = machine__findnew_thread(machine, event->ip.pid); |
145 | if (thread == NULL) { | 171 | if (thread == NULL) { |
146 | pr_err("problem processing %d event, skipping it.\n", | 172 | pr_err("problem processing %d event, skipping it.\n", |
147 | event->header.type); | 173 | event->header.type); |
148 | goto repipe; | 174 | goto repipe; |
149 | } | 175 | } |
150 | 176 | ||
151 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, | 177 | thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, |
152 | event->ip.pid, event->ip.ip, &al); | 178 | event->ip.ip, &al); |
153 | 179 | ||
154 | if (al.map != NULL) { | 180 | if (al.map != NULL) { |
155 | if (!al.map->dso->hit) { | 181 | if (!al.map->dso->hit) { |
156 | al.map->dso->hit = 1; | 182 | al.map->dso->hit = 1; |
157 | if (map__load(al.map, NULL) >= 0) { | 183 | if (map__load(al.map, NULL) >= 0) { |
158 | dso__inject_build_id(al.map->dso, session); | 184 | dso__inject_build_id(al.map->dso, tool, machine); |
159 | /* | 185 | /* |
160 | * If this fails, too bad, let the other side | 186 | * If this fails, too bad, let the other side |
161 | * account this as unresolved. | 187 | * account this as unresolved. |
@@ -168,24 +194,24 @@ static int perf_event__inject_buildid(union perf_event *event, | |||
168 | } | 194 | } |
169 | 195 | ||
170 | repipe: | 196 | repipe: |
171 | perf_event__repipe(event, sample, session); | 197 | perf_event__repipe(tool, event, sample, machine); |
172 | return 0; | 198 | return 0; |
173 | } | 199 | } |
174 | 200 | ||
175 | struct perf_event_ops inject_ops = { | 201 | struct perf_tool perf_inject = { |
176 | .sample = perf_event__repipe_sample, | 202 | .sample = perf_event__repipe_sample, |
177 | .mmap = perf_event__repipe, | 203 | .mmap = perf_event__repipe, |
178 | .comm = perf_event__repipe, | 204 | .comm = perf_event__repipe, |
179 | .fork = perf_event__repipe, | 205 | .fork = perf_event__repipe, |
180 | .exit = perf_event__repipe, | 206 | .exit = perf_event__repipe, |
181 | .lost = perf_event__repipe, | 207 | .lost = perf_event__repipe, |
182 | .read = perf_event__repipe, | 208 | .read = perf_event__repipe_sample, |
183 | .throttle = perf_event__repipe, | 209 | .throttle = perf_event__repipe, |
184 | .unthrottle = perf_event__repipe, | 210 | .unthrottle = perf_event__repipe, |
185 | .attr = perf_event__repipe_synth, | 211 | .attr = perf_event__repipe_attr, |
186 | .event_type = perf_event__repipe_synth, | 212 | .event_type = perf_event__repipe_event_type_synth, |
187 | .tracing_data = perf_event__repipe_synth, | 213 | .tracing_data = perf_event__repipe_tracing_data_synth, |
188 | .build_id = perf_event__repipe_synth, | 214 | .build_id = perf_event__repipe_op2_synth, |
189 | }; | 215 | }; |
190 | 216 | ||
191 | extern volatile int session_done; | 217 | extern volatile int session_done; |
@@ -203,17 +229,17 @@ static int __cmd_inject(void) | |||
203 | signal(SIGINT, sig_handler); | 229 | signal(SIGINT, sig_handler); |
204 | 230 | ||
205 | if (inject_build_ids) { | 231 | if (inject_build_ids) { |
206 | inject_ops.sample = perf_event__inject_buildid; | 232 | perf_inject.sample = perf_event__inject_buildid; |
207 | inject_ops.mmap = perf_event__repipe_mmap; | 233 | perf_inject.mmap = perf_event__repipe_mmap; |
208 | inject_ops.fork = perf_event__repipe_task; | 234 | perf_inject.fork = perf_event__repipe_task; |
209 | inject_ops.tracing_data = perf_event__repipe_tracing_data; | 235 | perf_inject.tracing_data = perf_event__repipe_tracing_data; |
210 | } | 236 | } |
211 | 237 | ||
212 | session = perf_session__new(input_name, O_RDONLY, false, true, &inject_ops); | 238 | session = perf_session__new(input_name, O_RDONLY, false, true, &perf_inject); |
213 | if (session == NULL) | 239 | if (session == NULL) |
214 | return -ENOMEM; | 240 | return -ENOMEM; |
215 | 241 | ||
216 | ret = perf_session__process_events(session, &inject_ops); | 242 | ret = perf_session__process_events(session, &perf_inject); |
217 | 243 | ||
218 | perf_session__delete(session); | 244 | perf_session__delete(session); |
219 | 245 | ||