hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/tools/perf/util/cs-etm.c
....@@ -11,7 +11,9 @@
1111 #include <linux/kernel.h>
1212 #include <linux/log2.h>
1313 #include <linux/types.h>
14
+#include <linux/zalloc.h>
1415
16
+#include <opencsd/ocsd_if_types.h>
1517 #include <stdlib.h>
1618
1719 #include "auxtrace.h"
....@@ -19,25 +21,23 @@
1921 #include "cs-etm.h"
2022 #include "cs-etm-decoder/cs-etm-decoder.h"
2123 #include "debug.h"
24
+#include "dso.h"
2225 #include "evlist.h"
2326 #include "intlist.h"
2427 #include "machine.h"
2528 #include "map.h"
2629 #include "perf.h"
30
+#include "session.h"
31
+#include "map_symbol.h"
32
+#include "branch.h"
33
+#include "symbol.h"
34
+#include "tool.h"
2735 #include "thread.h"
28
-#include "thread_map.h"
2936 #include "thread-stack.h"
30
-#include "util.h"
37
+#include <tools/libc_compat.h>
38
+#include "util/synthetic-events.h"
3139
3240 #define MAX_TIMESTAMP (~0ULL)
33
-
34
-/*
35
- * A64 instructions are always 4 bytes
36
- *
37
- * Only A64 is supported, so can use this constant for converting between
38
- * addresses and instruction counts, calculting offsets etc
39
- */
40
-#define A64_INSTR_SIZE 4
4141
4242 struct cs_etm_auxtrace {
4343 struct auxtrace auxtrace;
....@@ -66,33 +66,81 @@
6666 unsigned int pmu_type;
6767 };
6868
69
-struct cs_etm_queue {
70
- struct cs_etm_auxtrace *etm;
71
- struct thread *thread;
72
- struct cs_etm_decoder *decoder;
73
- struct auxtrace_buffer *buffer;
74
- const struct cs_etm_state *state;
75
- union perf_event *event_buf;
76
- unsigned int queue_nr;
69
+struct cs_etm_traceid_queue {
70
+ u8 trace_chan_id;
7771 pid_t pid, tid;
78
- int cpu;
79
- u64 time;
80
- u64 timestamp;
81
- u64 offset;
8272 u64 period_instructions;
73
+ size_t last_branch_pos;
74
+ union perf_event *event_buf;
75
+ struct thread *thread;
8376 struct branch_stack *last_branch;
8477 struct branch_stack *last_branch_rb;
85
- size_t last_branch_pos;
8678 struct cs_etm_packet *prev_packet;
8779 struct cs_etm_packet *packet;
80
+ struct cs_etm_packet_queue packet_queue;
81
+};
82
+
83
+struct cs_etm_queue {
84
+ struct cs_etm_auxtrace *etm;
85
+ struct cs_etm_decoder *decoder;
86
+ struct auxtrace_buffer *buffer;
87
+ unsigned int queue_nr;
88
+ u8 pending_timestamp;
89
+ u64 offset;
90
+ const unsigned char *buf;
91
+ size_t buf_len, buf_used;
92
+ /* Conversion between traceID and index in traceid_queues array */
93
+ struct intlist *traceid_queues_list;
94
+ struct cs_etm_traceid_queue **traceid_queues;
8895 };
8996
9097 /* RB tree for quick conversion between traceID and metadata pointers */
9198 static struct intlist *traceid_list;
9299
93100 static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);
101
+static int cs_etm__process_queues(struct cs_etm_auxtrace *etm);
94102 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
95
- pid_t tid, u64 time_);
103
+ pid_t tid);
104
+static int cs_etm__get_data_block(struct cs_etm_queue *etmq);
105
+static int cs_etm__decode_data_block(struct cs_etm_queue *etmq);
106
+
107
+/* PTMs ETMIDR [11:8] set to b0011 */
108
+#define ETMIDR_PTM_VERSION 0x00000300
109
+
110
+/*
111
+ * A struct auxtrace_heap_item only has a queue_nr and a timestamp to
112
+ * work with. One option is to modify to auxtrace_heap_XYZ() API or simply
113
+ * encode the etm queue number as the upper 16 bit and the channel as
114
+ * the lower 16 bit.
115
+ */
116
+#define TO_CS_QUEUE_NR(queue_nr, trace_chan_id) \
117
+ (queue_nr << 16 | trace_chan_id)
118
+#define TO_QUEUE_NR(cs_queue_nr) (cs_queue_nr >> 16)
119
+#define TO_TRACE_CHAN_ID(cs_queue_nr) (cs_queue_nr & 0x0000ffff)
120
+
121
+static u32 cs_etm__get_v7_protocol_version(u32 etmidr)
122
+{
123
+ etmidr &= ETMIDR_PTM_VERSION;
124
+
125
+ if (etmidr == ETMIDR_PTM_VERSION)
126
+ return CS_ETM_PROTO_PTM;
127
+
128
+ return CS_ETM_PROTO_ETMV3;
129
+}
130
+
131
+static int cs_etm__get_magic(u8 trace_chan_id, u64 *magic)
132
+{
133
+ struct int_node *inode;
134
+ u64 *metadata;
135
+
136
+ inode = intlist__find(traceid_list, trace_chan_id);
137
+ if (!inode)
138
+ return -EINVAL;
139
+
140
+ metadata = inode->priv;
141
+ *magic = metadata[CS_ETM_MAGIC];
142
+ return 0;
143
+}
96144
97145 int cs_etm__get_cpu(u8 trace_chan_id, int *cpu)
98146 {
....@@ -108,6 +156,233 @@
108156 return 0;
109157 }
110158
159
+void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
160
+ u8 trace_chan_id)
161
+{
162
+ /*
163
+ * Wnen a timestamp packet is encountered the backend code
164
+ * is stopped so that the front end has time to process packets
165
+ * that were accumulated in the traceID queue. Since there can
166
+ * be more than one channel per cs_etm_queue, we need to specify
167
+ * what traceID queue needs servicing.
168
+ */
169
+ etmq->pending_timestamp = trace_chan_id;
170
+}
171
+
172
+static u64 cs_etm__etmq_get_timestamp(struct cs_etm_queue *etmq,
173
+ u8 *trace_chan_id)
174
+{
175
+ struct cs_etm_packet_queue *packet_queue;
176
+
177
+ if (!etmq->pending_timestamp)
178
+ return 0;
179
+
180
+ if (trace_chan_id)
181
+ *trace_chan_id = etmq->pending_timestamp;
182
+
183
+ packet_queue = cs_etm__etmq_get_packet_queue(etmq,
184
+ etmq->pending_timestamp);
185
+ if (!packet_queue)
186
+ return 0;
187
+
188
+ /* Acknowledge pending status */
189
+ etmq->pending_timestamp = 0;
190
+
191
+ /* See function cs_etm_decoder__do_{hard|soft}_timestamp() */
192
+ return packet_queue->timestamp;
193
+}
194
+
195
+static void cs_etm__clear_packet_queue(struct cs_etm_packet_queue *queue)
196
+{
197
+ int i;
198
+
199
+ queue->head = 0;
200
+ queue->tail = 0;
201
+ queue->packet_count = 0;
202
+ for (i = 0; i < CS_ETM_PACKET_MAX_BUFFER; i++) {
203
+ queue->packet_buffer[i].isa = CS_ETM_ISA_UNKNOWN;
204
+ queue->packet_buffer[i].start_addr = CS_ETM_INVAL_ADDR;
205
+ queue->packet_buffer[i].end_addr = CS_ETM_INVAL_ADDR;
206
+ queue->packet_buffer[i].instr_count = 0;
207
+ queue->packet_buffer[i].last_instr_taken_branch = false;
208
+ queue->packet_buffer[i].last_instr_size = 0;
209
+ queue->packet_buffer[i].last_instr_type = 0;
210
+ queue->packet_buffer[i].last_instr_subtype = 0;
211
+ queue->packet_buffer[i].last_instr_cond = 0;
212
+ queue->packet_buffer[i].flags = 0;
213
+ queue->packet_buffer[i].exception_number = UINT32_MAX;
214
+ queue->packet_buffer[i].trace_chan_id = UINT8_MAX;
215
+ queue->packet_buffer[i].cpu = INT_MIN;
216
+ }
217
+}
218
+
219
+static void cs_etm__clear_all_packet_queues(struct cs_etm_queue *etmq)
220
+{
221
+ int idx;
222
+ struct int_node *inode;
223
+ struct cs_etm_traceid_queue *tidq;
224
+ struct intlist *traceid_queues_list = etmq->traceid_queues_list;
225
+
226
+ intlist__for_each_entry(inode, traceid_queues_list) {
227
+ idx = (int)(intptr_t)inode->priv;
228
+ tidq = etmq->traceid_queues[idx];
229
+ cs_etm__clear_packet_queue(&tidq->packet_queue);
230
+ }
231
+}
232
+
233
+static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
234
+ struct cs_etm_traceid_queue *tidq,
235
+ u8 trace_chan_id)
236
+{
237
+ int rc = -ENOMEM;
238
+ struct auxtrace_queue *queue;
239
+ struct cs_etm_auxtrace *etm = etmq->etm;
240
+
241
+ cs_etm__clear_packet_queue(&tidq->packet_queue);
242
+
243
+ queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
244
+ tidq->tid = queue->tid;
245
+ tidq->pid = -1;
246
+ tidq->trace_chan_id = trace_chan_id;
247
+
248
+ tidq->packet = zalloc(sizeof(struct cs_etm_packet));
249
+ if (!tidq->packet)
250
+ goto out;
251
+
252
+ tidq->prev_packet = zalloc(sizeof(struct cs_etm_packet));
253
+ if (!tidq->prev_packet)
254
+ goto out_free;
255
+
256
+ if (etm->synth_opts.last_branch) {
257
+ size_t sz = sizeof(struct branch_stack);
258
+
259
+ sz += etm->synth_opts.last_branch_sz *
260
+ sizeof(struct branch_entry);
261
+ tidq->last_branch = zalloc(sz);
262
+ if (!tidq->last_branch)
263
+ goto out_free;
264
+ tidq->last_branch_rb = zalloc(sz);
265
+ if (!tidq->last_branch_rb)
266
+ goto out_free;
267
+ }
268
+
269
+ tidq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
270
+ if (!tidq->event_buf)
271
+ goto out_free;
272
+
273
+ return 0;
274
+
275
+out_free:
276
+ zfree(&tidq->last_branch_rb);
277
+ zfree(&tidq->last_branch);
278
+ zfree(&tidq->prev_packet);
279
+ zfree(&tidq->packet);
280
+out:
281
+ return rc;
282
+}
283
+
284
+static struct cs_etm_traceid_queue
285
+*cs_etm__etmq_get_traceid_queue(struct cs_etm_queue *etmq, u8 trace_chan_id)
286
+{
287
+ int idx;
288
+ struct int_node *inode;
289
+ struct intlist *traceid_queues_list;
290
+ struct cs_etm_traceid_queue *tidq, **traceid_queues;
291
+ struct cs_etm_auxtrace *etm = etmq->etm;
292
+
293
+ if (etm->timeless_decoding)
294
+ trace_chan_id = CS_ETM_PER_THREAD_TRACEID;
295
+
296
+ traceid_queues_list = etmq->traceid_queues_list;
297
+
298
+ /*
299
+ * Check if the traceid_queue exist for this traceID by looking
300
+ * in the queue list.
301
+ */
302
+ inode = intlist__find(traceid_queues_list, trace_chan_id);
303
+ if (inode) {
304
+ idx = (int)(intptr_t)inode->priv;
305
+ return etmq->traceid_queues[idx];
306
+ }
307
+
308
+ /* We couldn't find a traceid_queue for this traceID, allocate one */
309
+ tidq = malloc(sizeof(*tidq));
310
+ if (!tidq)
311
+ return NULL;
312
+
313
+ memset(tidq, 0, sizeof(*tidq));
314
+
315
+ /* Get a valid index for the new traceid_queue */
316
+ idx = intlist__nr_entries(traceid_queues_list);
317
+ /* Memory for the inode is free'ed in cs_etm_free_traceid_queues () */
318
+ inode = intlist__findnew(traceid_queues_list, trace_chan_id);
319
+ if (!inode)
320
+ goto out_free;
321
+
322
+ /* Associate this traceID with this index */
323
+ inode->priv = (void *)(intptr_t)idx;
324
+
325
+ if (cs_etm__init_traceid_queue(etmq, tidq, trace_chan_id))
326
+ goto out_free;
327
+
328
+ /* Grow the traceid_queues array by one unit */
329
+ traceid_queues = etmq->traceid_queues;
330
+ traceid_queues = reallocarray(traceid_queues,
331
+ idx + 1,
332
+ sizeof(*traceid_queues));
333
+
334
+ /*
335
+ * On failure reallocarray() returns NULL and the original block of
336
+ * memory is left untouched.
337
+ */
338
+ if (!traceid_queues)
339
+ goto out_free;
340
+
341
+ traceid_queues[idx] = tidq;
342
+ etmq->traceid_queues = traceid_queues;
343
+
344
+ return etmq->traceid_queues[idx];
345
+
346
+out_free:
347
+ /*
348
+ * Function intlist__remove() removes the inode from the list
349
+ * and delete the memory associated to it.
350
+ */
351
+ intlist__remove(traceid_queues_list, inode);
352
+ free(tidq);
353
+
354
+ return NULL;
355
+}
356
+
357
+struct cs_etm_packet_queue
358
+*cs_etm__etmq_get_packet_queue(struct cs_etm_queue *etmq, u8 trace_chan_id)
359
+{
360
+ struct cs_etm_traceid_queue *tidq;
361
+
362
+ tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
363
+ if (tidq)
364
+ return &tidq->packet_queue;
365
+
366
+ return NULL;
367
+}
368
+
369
+static void cs_etm__packet_swap(struct cs_etm_auxtrace *etm,
370
+ struct cs_etm_traceid_queue *tidq)
371
+{
372
+ struct cs_etm_packet *tmp;
373
+
374
+ if (etm->sample_branches || etm->synth_opts.last_branch ||
375
+ etm->sample_instructions) {
376
+ /*
377
+ * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
378
+ * the next incoming packet.
379
+ */
380
+ tmp = tidq->packet;
381
+ tidq->packet = tidq->prev_packet;
382
+ tidq->prev_packet = tmp;
383
+ }
384
+}
385
+
111386 static void cs_etm__packet_dump(const char *pkt_string)
112387 {
113388 const char *color = PERF_COLOR_BLUE;
....@@ -121,10 +396,83 @@
121396 fflush(stdout);
122397 }
123398
399
+static void cs_etm__set_trace_param_etmv3(struct cs_etm_trace_params *t_params,
400
+ struct cs_etm_auxtrace *etm, int idx,
401
+ u32 etmidr)
402
+{
403
+ u64 **metadata = etm->metadata;
404
+
405
+ t_params[idx].protocol = cs_etm__get_v7_protocol_version(etmidr);
406
+ t_params[idx].etmv3.reg_ctrl = metadata[idx][CS_ETM_ETMCR];
407
+ t_params[idx].etmv3.reg_trc_id = metadata[idx][CS_ETM_ETMTRACEIDR];
408
+}
409
+
410
+static void cs_etm__set_trace_param_etmv4(struct cs_etm_trace_params *t_params,
411
+ struct cs_etm_auxtrace *etm, int idx)
412
+{
413
+ u64 **metadata = etm->metadata;
414
+
415
+ t_params[idx].protocol = CS_ETM_PROTO_ETMV4i;
416
+ t_params[idx].etmv4.reg_idr0 = metadata[idx][CS_ETMV4_TRCIDR0];
417
+ t_params[idx].etmv4.reg_idr1 = metadata[idx][CS_ETMV4_TRCIDR1];
418
+ t_params[idx].etmv4.reg_idr2 = metadata[idx][CS_ETMV4_TRCIDR2];
419
+ t_params[idx].etmv4.reg_idr8 = metadata[idx][CS_ETMV4_TRCIDR8];
420
+ t_params[idx].etmv4.reg_configr = metadata[idx][CS_ETMV4_TRCCONFIGR];
421
+ t_params[idx].etmv4.reg_traceidr = metadata[idx][CS_ETMV4_TRCTRACEIDR];
422
+}
423
+
424
+static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params,
425
+ struct cs_etm_auxtrace *etm)
426
+{
427
+ int i;
428
+ u32 etmidr;
429
+ u64 architecture;
430
+
431
+ for (i = 0; i < etm->num_cpu; i++) {
432
+ architecture = etm->metadata[i][CS_ETM_MAGIC];
433
+
434
+ switch (architecture) {
435
+ case __perf_cs_etmv3_magic:
436
+ etmidr = etm->metadata[i][CS_ETM_ETMIDR];
437
+ cs_etm__set_trace_param_etmv3(t_params, etm, i, etmidr);
438
+ break;
439
+ case __perf_cs_etmv4_magic:
440
+ cs_etm__set_trace_param_etmv4(t_params, etm, i);
441
+ break;
442
+ default:
443
+ return -EINVAL;
444
+ }
445
+ }
446
+
447
+ return 0;
448
+}
449
+
450
+static int cs_etm__init_decoder_params(struct cs_etm_decoder_params *d_params,
451
+ struct cs_etm_queue *etmq,
452
+ enum cs_etm_decoder_operation mode)
453
+{
454
+ int ret = -EINVAL;
455
+
456
+ if (!(mode < CS_ETM_OPERATION_MAX))
457
+ goto out;
458
+
459
+ d_params->packet_printer = cs_etm__packet_dump;
460
+ d_params->operation = mode;
461
+ d_params->data = etmq;
462
+ d_params->formatted = true;
463
+ d_params->fsyncs = false;
464
+ d_params->hsyncs = false;
465
+ d_params->frame_aligned = true;
466
+
467
+ ret = 0;
468
+out:
469
+ return ret;
470
+}
471
+
124472 static void cs_etm__dump_event(struct cs_etm_auxtrace *etm,
125473 struct auxtrace_buffer *buffer)
126474 {
127
- int i, ret;
475
+ int ret;
128476 const char *color = PERF_COLOR_BLUE;
129477 struct cs_etm_decoder_params d_params;
130478 struct cs_etm_trace_params *t_params;
....@@ -138,32 +486,22 @@
138486
139487 /* Use metadata to fill in trace parameters for trace decoder */
140488 t_params = zalloc(sizeof(*t_params) * etm->num_cpu);
141
- for (i = 0; i < etm->num_cpu; i++) {
142
- t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
143
- t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
144
- t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
145
- t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
146
- t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
147
- t_params[i].etmv4.reg_configr =
148
- etm->metadata[i][CS_ETMV4_TRCCONFIGR];
149
- t_params[i].etmv4.reg_traceidr =
150
- etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
151
- }
489
+
490
+ if (!t_params)
491
+ return;
492
+
493
+ if (cs_etm__init_trace_params(t_params, etm))
494
+ goto out_free;
152495
153496 /* Set decoder parameters to simply print the trace packets */
154
- d_params.packet_printer = cs_etm__packet_dump;
155
- d_params.operation = CS_ETM_OPERATION_PRINT;
156
- d_params.formatted = true;
157
- d_params.fsyncs = false;
158
- d_params.hsyncs = false;
159
- d_params.frame_aligned = true;
497
+ if (cs_etm__init_decoder_params(&d_params, NULL,
498
+ CS_ETM_OPERATION_PRINT))
499
+ goto out_free;
160500
161501 decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);
162502
163
- zfree(&t_params);
164
-
165503 if (!decoder)
166
- return;
504
+ goto out_free;
167505 do {
168506 size_t consumed;
169507
....@@ -178,6 +516,9 @@
178516 } while (buffer_used < buffer->size);
179517
180518 cs_etm_decoder__free(decoder);
519
+
520
+out_free:
521
+ zfree(&t_params);
181522 }
182523
183524 static int cs_etm__flush_events(struct perf_session *session,
....@@ -193,15 +534,52 @@
193534 if (!tool->ordered_events)
194535 return -EINVAL;
195536
196
- if (!etm->timeless_decoding)
197
- return -EINVAL;
198
-
199537 ret = cs_etm__update_queues(etm);
200538
201539 if (ret < 0)
202540 return ret;
203541
204
- return cs_etm__process_timeless_queues(etm, -1, MAX_TIMESTAMP - 1);
542
+ if (etm->timeless_decoding)
543
+ return cs_etm__process_timeless_queues(etm, -1);
544
+
545
+ return cs_etm__process_queues(etm);
546
+}
547
+
548
+static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
549
+{
550
+ int idx;
551
+ uintptr_t priv;
552
+ struct int_node *inode, *tmp;
553
+ struct cs_etm_traceid_queue *tidq;
554
+ struct intlist *traceid_queues_list = etmq->traceid_queues_list;
555
+
556
+ intlist__for_each_entry_safe(inode, tmp, traceid_queues_list) {
557
+ priv = (uintptr_t)inode->priv;
558
+ idx = priv;
559
+
560
+ /* Free this traceid_queue from the array */
561
+ tidq = etmq->traceid_queues[idx];
562
+ thread__zput(tidq->thread);
563
+ zfree(&tidq->event_buf);
564
+ zfree(&tidq->last_branch);
565
+ zfree(&tidq->last_branch_rb);
566
+ zfree(&tidq->prev_packet);
567
+ zfree(&tidq->packet);
568
+ zfree(&tidq);
569
+
570
+ /*
571
+ * Function intlist__remove() removes the inode from the list
572
+ * and delete the memory associated to it.
573
+ */
574
+ intlist__remove(traceid_queues_list, inode);
575
+ }
576
+
577
+ /* Then the RB tree itself */
578
+ intlist__delete(traceid_queues_list);
579
+ etmq->traceid_queues_list = NULL;
580
+
581
+ /* finally free the traceid_queues array */
582
+ zfree(&etmq->traceid_queues);
205583 }
206584
207585 static void cs_etm__free_queue(void *priv)
....@@ -211,13 +589,8 @@
211589 if (!etmq)
212590 return;
213591
214
- thread__zput(etmq->thread);
215592 cs_etm_decoder__free(etmq->decoder);
216
- zfree(&etmq->event_buf);
217
- zfree(&etmq->last_branch);
218
- zfree(&etmq->last_branch_rb);
219
- zfree(&etmq->prev_packet);
220
- zfree(&etmq->packet);
593
+ cs_etm__free_traceid_queues(etmq);
221594 free(etmq);
222595 }
223596
....@@ -261,6 +634,16 @@
261634 zfree(&aux);
262635 }
263636
637
+static bool cs_etm__evsel_is_auxtrace(struct perf_session *session,
638
+ struct evsel *evsel)
639
+{
640
+ struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
641
+ struct cs_etm_auxtrace,
642
+ auxtrace);
643
+
644
+ return evsel->core.attr.type == aux->pmu_type;
645
+}
646
+
264647 static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address)
265648 {
266649 struct machine *machine;
....@@ -282,26 +665,30 @@
282665 }
283666 }
284667
285
-static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address,
286
- size_t size, u8 *buffer)
668
+static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
669
+ u64 address, size_t size, u8 *buffer)
287670 {
288671 u8 cpumode;
289672 u64 offset;
290673 int len;
291
- struct thread *thread;
292
- struct machine *machine;
293
- struct addr_location al;
674
+ struct thread *thread;
675
+ struct machine *machine;
676
+ struct addr_location al;
677
+ struct cs_etm_traceid_queue *tidq;
294678
295679 if (!etmq)
296
- return -1;
680
+ return 0;
297681
298682 machine = etmq->etm->machine;
299683 cpumode = cs_etm__cpu_mode(etmq, address);
684
+ tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
685
+ if (!tidq)
686
+ return 0;
300687
301
- thread = etmq->thread;
688
+ thread = tidq->thread;
302689 if (!thread) {
303690 if (cpumode != PERF_RECORD_MISC_KERNEL)
304
- return -EINVAL;
691
+ return 0;
305692 thread = etmq->etm->unknown_thread;
306693 }
307694
....@@ -324,51 +711,19 @@
324711 return len;
325712 }
326713
327
-static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm,
328
- unsigned int queue_nr)
714
+static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm)
329715 {
330
- int i;
331716 struct cs_etm_decoder_params d_params;
332
- struct cs_etm_trace_params *t_params;
717
+ struct cs_etm_trace_params *t_params = NULL;
333718 struct cs_etm_queue *etmq;
334
- size_t szp = sizeof(struct cs_etm_packet);
335719
336720 etmq = zalloc(sizeof(*etmq));
337721 if (!etmq)
338722 return NULL;
339723
340
- etmq->packet = zalloc(szp);
341
- if (!etmq->packet)
724
+ etmq->traceid_queues_list = intlist__new(NULL);
725
+ if (!etmq->traceid_queues_list)
342726 goto out_free;
343
-
344
- if (etm->synth_opts.last_branch || etm->sample_branches) {
345
- etmq->prev_packet = zalloc(szp);
346
- if (!etmq->prev_packet)
347
- goto out_free;
348
- }
349
-
350
- if (etm->synth_opts.last_branch) {
351
- size_t sz = sizeof(struct branch_stack);
352
-
353
- sz += etm->synth_opts.last_branch_sz *
354
- sizeof(struct branch_entry);
355
- etmq->last_branch = zalloc(sz);
356
- if (!etmq->last_branch)
357
- goto out_free;
358
- etmq->last_branch_rb = zalloc(sz);
359
- if (!etmq->last_branch_rb)
360
- goto out_free;
361
- }
362
-
363
- etmq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
364
- if (!etmq->event_buf)
365
- goto out_free;
366
-
367
- etmq->etm = etm;
368
- etmq->queue_nr = queue_nr;
369
- etmq->pid = -1;
370
- etmq->tid = -1;
371
- etmq->cpu = -1;
372727
373728 /* Use metadata to fill in trace parameters for trace decoder */
374729 t_params = zalloc(sizeof(*t_params) * etm->num_cpu);
....@@ -376,30 +731,15 @@
376731 if (!t_params)
377732 goto out_free;
378733
379
- for (i = 0; i < etm->num_cpu; i++) {
380
- t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
381
- t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
382
- t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
383
- t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
384
- t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
385
- t_params[i].etmv4.reg_configr =
386
- etm->metadata[i][CS_ETMV4_TRCCONFIGR];
387
- t_params[i].etmv4.reg_traceidr =
388
- etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
389
- }
734
+ if (cs_etm__init_trace_params(t_params, etm))
735
+ goto out_free;
390736
391
- /* Set decoder parameters to simply print the trace packets */
392
- d_params.packet_printer = cs_etm__packet_dump;
393
- d_params.operation = CS_ETM_OPERATION_DECODE;
394
- d_params.formatted = true;
395
- d_params.fsyncs = false;
396
- d_params.hsyncs = false;
397
- d_params.frame_aligned = true;
398
- d_params.data = etmq;
737
+ /* Set decoder parameters to decode trace packets */
738
+ if (cs_etm__init_decoder_params(&d_params, etmq,
739
+ CS_ETM_OPERATION_DECODE))
740
+ goto out_free;
399741
400742 etmq->decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);
401
-
402
- zfree(&t_params);
403743
404744 if (!etmq->decoder)
405745 goto out_free;
....@@ -413,19 +753,13 @@
413753 cs_etm__mem_access))
414754 goto out_free_decoder;
415755
416
- etmq->offset = 0;
417
- etmq->period_instructions = 0;
418
-
756
+ zfree(&t_params);
419757 return etmq;
420758
421759 out_free_decoder:
422760 cs_etm_decoder__free(etmq->decoder);
423761 out_free:
424
- zfree(&etmq->event_buf);
425
- zfree(&etmq->last_branch);
426
- zfree(&etmq->last_branch_rb);
427
- zfree(&etmq->prev_packet);
428
- zfree(&etmq->packet);
762
+ intlist__delete(etmq->traceid_queues_list);
429763 free(etmq);
430764
431765 return NULL;
....@@ -435,30 +769,99 @@
435769 struct auxtrace_queue *queue,
436770 unsigned int queue_nr)
437771 {
772
+ int ret = 0;
773
+ unsigned int cs_queue_nr;
774
+ u8 trace_chan_id;
775
+ u64 timestamp;
438776 struct cs_etm_queue *etmq = queue->priv;
439777
440778 if (list_empty(&queue->head) || etmq)
441
- return 0;
779
+ goto out;
442780
443
- etmq = cs_etm__alloc_queue(etm, queue_nr);
781
+ etmq = cs_etm__alloc_queue(etm);
444782
445
- if (!etmq)
446
- return -ENOMEM;
783
+ if (!etmq) {
784
+ ret = -ENOMEM;
785
+ goto out;
786
+ }
447787
448788 queue->priv = etmq;
789
+ etmq->etm = etm;
790
+ etmq->queue_nr = queue_nr;
791
+ etmq->offset = 0;
449792
450
- if (queue->cpu != -1)
451
- etmq->cpu = queue->cpu;
793
+ if (etm->timeless_decoding)
794
+ goto out;
452795
453
- etmq->tid = queue->tid;
796
+ /*
797
+ * We are under a CPU-wide trace scenario. As such we need to know
798
+ * when the code that generated the traces started to execute so that
799
+ * it can be correlated with execution on other CPUs. So we get a
800
+ * handle on the beginning of traces and decode until we find a
801
+ * timestamp. The timestamp is then added to the auxtrace min heap
802
+ * in order to know what nibble (of all the etmqs) to decode first.
803
+ */
804
+ while (1) {
805
+ /*
806
+ * Fetch an aux_buffer from this etmq. Bail if no more
807
+ * blocks or an error has been encountered.
808
+ */
809
+ ret = cs_etm__get_data_block(etmq);
810
+ if (ret <= 0)
811
+ goto out;
454812
455
- return 0;
813
+ /*
814
+ * Run decoder on the trace block. The decoder will stop when
815
+ * encountering a timestamp, a full packet queue or the end of
816
+ * trace for that block.
817
+ */
818
+ ret = cs_etm__decode_data_block(etmq);
819
+ if (ret)
820
+ goto out;
821
+
822
+ /*
823
+ * Function cs_etm_decoder__do_{hard|soft}_timestamp() does all
824
+ * the timestamp calculation for us.
825
+ */
826
+ timestamp = cs_etm__etmq_get_timestamp(etmq, &trace_chan_id);
827
+
828
+ /* We found a timestamp, no need to continue. */
829
+ if (timestamp)
830
+ break;
831
+
832
+ /*
833
+ * We didn't find a timestamp so empty all the traceid packet
834
+ * queues before looking for another timestamp packet, either
835
+ * in the current data block or a new one. Packets that were
836
+ * just decoded are useless since no timestamp has been
837
+ * associated with them. As such simply discard them.
838
+ */
839
+ cs_etm__clear_all_packet_queues(etmq);
840
+ }
841
+
842
+ /*
843
+ * We have a timestamp. Add it to the min heap to reflect when
844
+ * instructions conveyed by the range packets of this traceID queue
845
+ * started to execute. Once the same has been done for all the traceID
846
+ * queues of each etmq, redenring and decoding can start in
847
+ * chronological order.
848
+ *
849
+ * Note that packets decoded above are still in the traceID's packet
850
+ * queue and will be processed in cs_etm__process_queues().
851
+ */
852
+ cs_queue_nr = TO_CS_QUEUE_NR(queue_nr, trace_chan_id);
853
+ ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, timestamp);
854
+out:
855
+ return ret;
456856 }
457857
458858 static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm)
459859 {
460860 unsigned int i;
461861 int ret;
862
+
863
+ if (!etm->kernel_start)
864
+ etm->kernel_start = machine__kernel_start(etm->machine);
462865
463866 for (i = 0; i < etm->queues.nr_queues; i++) {
464867 ret = cs_etm__setup_queue(etm, &etm->queues.queue_array[i], i);
....@@ -479,10 +882,12 @@
479882 return 0;
480883 }
481884
482
-static inline void cs_etm__copy_last_branch_rb(struct cs_etm_queue *etmq)
885
+static inline
886
+void cs_etm__copy_last_branch_rb(struct cs_etm_queue *etmq,
887
+ struct cs_etm_traceid_queue *tidq)
483888 {
484
- struct branch_stack *bs_src = etmq->last_branch_rb;
485
- struct branch_stack *bs_dst = etmq->last_branch;
889
+ struct branch_stack *bs_src = tidq->last_branch_rb;
890
+ struct branch_stack *bs_dst = tidq->last_branch;
486891 size_t nr = 0;
487892
488893 /*
....@@ -502,9 +907,9 @@
502907 * two steps. First, copy the branches from the most recently inserted
503908 * branch ->last_branch_pos until the end of bs_src->entries buffer.
504909 */
505
- nr = etmq->etm->synth_opts.last_branch_sz - etmq->last_branch_pos;
910
+ nr = etmq->etm->synth_opts.last_branch_sz - tidq->last_branch_pos;
506911 memcpy(&bs_dst->entries[0],
507
- &bs_src->entries[etmq->last_branch_pos],
912
+ &bs_src->entries[tidq->last_branch_pos],
508913 sizeof(struct branch_entry) * nr);
509914
510915 /*
....@@ -517,68 +922,75 @@
517922 if (bs_src->nr >= etmq->etm->synth_opts.last_branch_sz) {
518923 memcpy(&bs_dst->entries[nr],
519924 &bs_src->entries[0],
520
- sizeof(struct branch_entry) * etmq->last_branch_pos);
925
+ sizeof(struct branch_entry) * tidq->last_branch_pos);
521926 }
522927 }
523928
524
-static inline void cs_etm__reset_last_branch_rb(struct cs_etm_queue *etmq)
929
+static inline
930
+void cs_etm__reset_last_branch_rb(struct cs_etm_traceid_queue *tidq)
525931 {
526
- etmq->last_branch_pos = 0;
527
- etmq->last_branch_rb->nr = 0;
932
+ tidq->last_branch_pos = 0;
933
+ tidq->last_branch_rb->nr = 0;
528934 }
529935
530
-static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet)
936
+static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq,
937
+ u8 trace_chan_id, u64 addr)
531938 {
532
- /* Returns 0 for the CS_ETM_TRACE_ON packet */
533
- if (packet->sample_type == CS_ETM_TRACE_ON)
534
- return 0;
939
+ u8 instrBytes[2];
535940
941
+ cs_etm__mem_access(etmq, trace_chan_id, addr,
942
+ ARRAY_SIZE(instrBytes), instrBytes);
536943 /*
537
- * The packet records the execution range with an exclusive end address
538
- *
539
- * A64 instructions are constant size, so the last executed
540
- * instruction is A64_INSTR_SIZE before the end address
541
- * Will need to do instruction level decode for T32 instructions as
542
- * they can be variable size (not yet supported).
944
+ * T32 instruction size is indicated by bits[15:11] of the first
945
+ * 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111
946
+ * denote a 32-bit instruction.
543947 */
544
- return packet->end_addr - A64_INSTR_SIZE;
948
+ return ((instrBytes[1] & 0xF8) >= 0xE8) ? 4 : 2;
545949 }
546950
547951 static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packet)
548952 {
549
- /* Returns 0 for the CS_ETM_TRACE_ON packet */
550
- if (packet->sample_type == CS_ETM_TRACE_ON)
953
+ /* Returns 0 for the CS_ETM_DISCONTINUITY packet */
954
+ if (packet->sample_type == CS_ETM_DISCONTINUITY)
551955 return 0;
552956
553957 return packet->start_addr;
554958 }
555959
556
-static inline u64 cs_etm__instr_count(const struct cs_etm_packet *packet)
960
+static inline
961
+u64 cs_etm__last_executed_instr(const struct cs_etm_packet *packet)
557962 {
558
- /*
559
- * Only A64 instructions are currently supported, so can get
560
- * instruction count by dividing.
561
- * Will need to do instruction level decode for T32 instructions as
562
- * they can be variable size (not yet supported).
563
- */
564
- return (packet->end_addr - packet->start_addr) / A64_INSTR_SIZE;
963
+ /* Returns 0 for the CS_ETM_DISCONTINUITY packet */
964
+ if (packet->sample_type == CS_ETM_DISCONTINUITY)
965
+ return 0;
966
+
967
+ return packet->end_addr - packet->last_instr_size;
565968 }
566969
567
-static inline u64 cs_etm__instr_addr(const struct cs_etm_packet *packet,
970
+static inline u64 cs_etm__instr_addr(struct cs_etm_queue *etmq,
971
+ u64 trace_chan_id,
972
+ const struct cs_etm_packet *packet,
568973 u64 offset)
569974 {
570
- /*
571
- * Only A64 instructions are currently supported, so can get
572
- * instruction address by muliplying.
573
- * Will need to do instruction level decode for T32 instructions as
574
- * they can be variable size (not yet supported).
575
- */
576
- return packet->start_addr + offset * A64_INSTR_SIZE;
975
+ if (packet->isa == CS_ETM_ISA_T32) {
976
+ u64 addr = packet->start_addr;
977
+
978
+ while (offset) {
979
+ addr += cs_etm__t32_instr_size(etmq,
980
+ trace_chan_id, addr);
981
+ offset--;
982
+ }
983
+ return addr;
984
+ }
985
+
986
+ /* Assume a 4 byte instruction size (A32/A64) */
987
+ return packet->start_addr + offset * 4;
577988 }
578989
579
-static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq)
990
+static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq,
991
+ struct cs_etm_traceid_queue *tidq)
580992 {
581
- struct branch_stack *bs = etmq->last_branch_rb;
993
+ struct branch_stack *bs = tidq->last_branch_rb;
582994 struct branch_entry *be;
583995
584996 /*
....@@ -587,14 +999,14 @@
587999 * buffer down. After writing the first element of the stack, move the
5881000 * insert position back to the end of the buffer.
5891001 */
590
- if (!etmq->last_branch_pos)
591
- etmq->last_branch_pos = etmq->etm->synth_opts.last_branch_sz;
1002
+ if (!tidq->last_branch_pos)
1003
+ tidq->last_branch_pos = etmq->etm->synth_opts.last_branch_sz;
5921004
593
- etmq->last_branch_pos -= 1;
1005
+ tidq->last_branch_pos -= 1;
5941006
595
- be = &bs->entries[etmq->last_branch_pos];
596
- be->from = cs_etm__last_executed_instr(etmq->prev_packet);
597
- be->to = cs_etm__first_executed_instr(etmq->packet);
1007
+ be = &bs->entries[tidq->last_branch_pos];
1008
+ be->from = cs_etm__last_executed_instr(tidq->prev_packet);
1009
+ be->to = cs_etm__first_executed_instr(tidq->packet);
5981010 /* No support for mispredict */
5991011 be->flags.mispred = 0;
6001012 be->flags.predicted = 1;
....@@ -616,7 +1028,7 @@
6161028
6171029
6181030 static int
619
-cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq)
1031
+cs_etm__get_trace(struct cs_etm_queue *etmq)
6201032 {
6211033 struct auxtrace_buffer *aux_buffer = etmq->buffer;
6221034 struct auxtrace_buffer *old_buffer = aux_buffer;
....@@ -630,7 +1042,7 @@
6301042 if (!aux_buffer) {
6311043 if (old_buffer)
6321044 auxtrace_buffer__drop_data(old_buffer);
633
- buff->len = 0;
1045
+ etmq->buf_len = 0;
6341046 return 0;
6351047 }
6361048
....@@ -650,41 +1062,90 @@
6501062 if (old_buffer)
6511063 auxtrace_buffer__drop_data(old_buffer);
6521064
653
- buff->offset = aux_buffer->offset;
654
- buff->len = aux_buffer->size;
655
- buff->buf = aux_buffer->data;
1065
+ etmq->buf_used = 0;
1066
+ etmq->buf_len = aux_buffer->size;
1067
+ etmq->buf = aux_buffer->data;
6561068
657
- buff->ref_timestamp = aux_buffer->reference;
658
-
659
- return buff->len;
1069
+ return etmq->buf_len;
6601070 }
6611071
6621072 static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
663
- struct auxtrace_queue *queue)
1073
+ struct cs_etm_traceid_queue *tidq)
6641074 {
665
- struct cs_etm_queue *etmq = queue->priv;
1075
+ if ((!tidq->thread) && (tidq->tid != -1))
1076
+ tidq->thread = machine__find_thread(etm->machine, -1,
1077
+ tidq->tid);
6661078
667
- /* CPU-wide tracing isn't supported yet */
668
- if (queue->tid == -1)
1079
+ if (tidq->thread)
1080
+ tidq->pid = tidq->thread->pid_;
1081
+}
1082
+
1083
+int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
1084
+ pid_t tid, u8 trace_chan_id)
1085
+{
1086
+ int cpu, err = -EINVAL;
1087
+ struct cs_etm_auxtrace *etm = etmq->etm;
1088
+ struct cs_etm_traceid_queue *tidq;
1089
+
1090
+ tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
1091
+ if (!tidq)
1092
+ return err;
1093
+
1094
+ if (cs_etm__get_cpu(trace_chan_id, &cpu) < 0)
1095
+ return err;
1096
+
1097
+ err = machine__set_current_tid(etm->machine, cpu, tid, tid);
1098
+ if (err)
1099
+ return err;
1100
+
1101
+ tidq->tid = tid;
1102
+ thread__zput(tidq->thread);
1103
+
1104
+ cs_etm__set_pid_tid_cpu(etm, tidq);
1105
+ return 0;
1106
+}
1107
+
1108
+bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq)
1109
+{
1110
+ return !!etmq->etm->timeless_decoding;
1111
+}
1112
+
1113
+static void cs_etm__copy_insn(struct cs_etm_queue *etmq,
1114
+ u64 trace_chan_id,
1115
+ const struct cs_etm_packet *packet,
1116
+ struct perf_sample *sample)
1117
+{
1118
+ /*
1119
+ * It's pointless to read instructions for the CS_ETM_DISCONTINUITY
1120
+ * packet, so directly bail out with 'insn_len' = 0.
1121
+ */
1122
+ if (packet->sample_type == CS_ETM_DISCONTINUITY) {
1123
+ sample->insn_len = 0;
6691124 return;
670
-
671
- if ((!etmq->thread) && (etmq->tid != -1))
672
- etmq->thread = machine__find_thread(etm->machine, -1,
673
- etmq->tid);
674
-
675
- if (etmq->thread) {
676
- etmq->pid = etmq->thread->pid_;
677
- if (queue->cpu == -1)
678
- etmq->cpu = etmq->thread->cpu;
6791125 }
1126
+
1127
+ /*
1128
+ * T32 instruction size might be 32-bit or 16-bit, decide by calling
1129
+ * cs_etm__t32_instr_size().
1130
+ */
1131
+ if (packet->isa == CS_ETM_ISA_T32)
1132
+ sample->insn_len = cs_etm__t32_instr_size(etmq, trace_chan_id,
1133
+ sample->ip);
1134
+ /* Otherwise, A64 and A32 instruction size are always 32-bit. */
1135
+ else
1136
+ sample->insn_len = 4;
1137
+
1138
+ cs_etm__mem_access(etmq, trace_chan_id, sample->ip,
1139
+ sample->insn_len, (void *)sample->insn);
6801140 }
6811141
6821142 static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
1143
+ struct cs_etm_traceid_queue *tidq,
6831144 u64 addr, u64 period)
6841145 {
6851146 int ret = 0;
6861147 struct cs_etm_auxtrace *etm = etmq->etm;
687
- union perf_event *event = etmq->event_buf;
1148
+ union perf_event *event = tidq->event_buf;
6881149 struct perf_sample sample = {.ip = 0,};
6891150
6901151 event->sample.header.type = PERF_RECORD_SAMPLE;
....@@ -692,20 +1153,19 @@
6921153 event->sample.header.size = sizeof(struct perf_event_header);
6931154
6941155 sample.ip = addr;
695
- sample.pid = etmq->pid;
696
- sample.tid = etmq->tid;
1156
+ sample.pid = tidq->pid;
1157
+ sample.tid = tidq->tid;
6971158 sample.id = etmq->etm->instructions_id;
6981159 sample.stream_id = etmq->etm->instructions_id;
6991160 sample.period = period;
700
- sample.cpu = etmq->packet->cpu;
701
- sample.flags = 0;
702
- sample.insn_len = 1;
1161
+ sample.cpu = tidq->packet->cpu;
1162
+ sample.flags = tidq->prev_packet->flags;
7031163 sample.cpumode = event->sample.header.misc;
7041164
705
- if (etm->synth_opts.last_branch) {
706
- cs_etm__copy_last_branch_rb(etmq);
707
- sample.branch_stack = etmq->last_branch;
708
- }
1165
+ cs_etm__copy_insn(etmq, tidq->trace_chan_id, tidq->packet, &sample);
1166
+
1167
+ if (etm->synth_opts.last_branch)
1168
+ sample.branch_stack = tidq->last_branch;
7091169
7101170 if (etm->synth_opts.inject) {
7111171 ret = cs_etm__inject_event(event, &sample,
....@@ -721,9 +1181,6 @@
7211181 "CS ETM Trace: failed to deliver instruction event, error %d\n",
7221182 ret);
7231183
724
- if (etm->synth_opts.last_branch)
725
- cs_etm__reset_last_branch_rb(etmq);
726
-
7271184 return ret;
7281185 }
7291186
....@@ -731,34 +1188,39 @@
7311188 * The cs etm packet encodes an instruction range between a branch target
7321189 * and the next taken branch. Generate sample accordingly.
7331190 */
734
-static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq)
1191
+static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
1192
+ struct cs_etm_traceid_queue *tidq)
7351193 {
7361194 int ret = 0;
7371195 struct cs_etm_auxtrace *etm = etmq->etm;
7381196 struct perf_sample sample = {.ip = 0,};
739
- union perf_event *event = etmq->event_buf;
1197
+ union perf_event *event = tidq->event_buf;
7401198 struct dummy_branch_stack {
7411199 u64 nr;
1200
+ u64 hw_idx;
7421201 struct branch_entry entries;
7431202 } dummy_bs;
7441203 u64 ip;
7451204
746
- ip = cs_etm__last_executed_instr(etmq->prev_packet);
1205
+ ip = cs_etm__last_executed_instr(tidq->prev_packet);
7471206
7481207 event->sample.header.type = PERF_RECORD_SAMPLE;
7491208 event->sample.header.misc = cs_etm__cpu_mode(etmq, ip);
7501209 event->sample.header.size = sizeof(struct perf_event_header);
7511210
7521211 sample.ip = ip;
753
- sample.pid = etmq->pid;
754
- sample.tid = etmq->tid;
755
- sample.addr = cs_etm__first_executed_instr(etmq->packet);
1212
+ sample.pid = tidq->pid;
1213
+ sample.tid = tidq->tid;
1214
+ sample.addr = cs_etm__first_executed_instr(tidq->packet);
7561215 sample.id = etmq->etm->branches_id;
7571216 sample.stream_id = etmq->etm->branches_id;
7581217 sample.period = 1;
759
- sample.cpu = etmq->packet->cpu;
760
- sample.flags = 0;
1218
+ sample.cpu = tidq->packet->cpu;
1219
+ sample.flags = tidq->prev_packet->flags;
7611220 sample.cpumode = event->sample.header.misc;
1221
+
1222
+ cs_etm__copy_insn(etmq, tidq->trace_chan_id, tidq->prev_packet,
1223
+ &sample);
7621224
7631225 /*
7641226 * perf report cannot handle events without a branch stack
....@@ -766,6 +1228,7 @@
7661228 if (etm->synth_opts.last_branch) {
7671229 dummy_bs = (struct dummy_branch_stack){
7681230 .nr = 1,
1231
+ .hw_idx = -1ULL,
7691232 .entries = {
7701233 .from = sample.ip,
7711234 .to = sample.addr,
....@@ -823,15 +1286,15 @@
8231286 static int cs_etm__synth_events(struct cs_etm_auxtrace *etm,
8241287 struct perf_session *session)
8251288 {
826
- struct perf_evlist *evlist = session->evlist;
827
- struct perf_evsel *evsel;
1289
+ struct evlist *evlist = session->evlist;
1290
+ struct evsel *evsel;
8281291 struct perf_event_attr attr;
8291292 bool found = false;
8301293 u64 id;
8311294 int err;
8321295
8331296 evlist__for_each_entry(evlist, evsel) {
834
- if (evsel->attr.type == etm->pmu_type) {
1297
+ if (evsel->core.attr.type == etm->pmu_type) {
8351298 found = true;
8361299 break;
8371300 }
....@@ -845,7 +1308,7 @@
8451308 memset(&attr, 0, sizeof(struct perf_event_attr));
8461309 attr.size = sizeof(struct perf_event_attr);
8471310 attr.type = PERF_TYPE_HARDWARE;
848
- attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK;
1311
+ attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK;
8491312 attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
8501313 PERF_SAMPLE_PERIOD;
8511314 if (etm->timeless_decoding)
....@@ -853,16 +1316,16 @@
8531316 else
8541317 attr.sample_type |= PERF_SAMPLE_TIME;
8551318
856
- attr.exclude_user = evsel->attr.exclude_user;
857
- attr.exclude_kernel = evsel->attr.exclude_kernel;
858
- attr.exclude_hv = evsel->attr.exclude_hv;
859
- attr.exclude_host = evsel->attr.exclude_host;
860
- attr.exclude_guest = evsel->attr.exclude_guest;
861
- attr.sample_id_all = evsel->attr.sample_id_all;
862
- attr.read_format = evsel->attr.read_format;
1319
+ attr.exclude_user = evsel->core.attr.exclude_user;
1320
+ attr.exclude_kernel = evsel->core.attr.exclude_kernel;
1321
+ attr.exclude_hv = evsel->core.attr.exclude_hv;
1322
+ attr.exclude_host = evsel->core.attr.exclude_host;
1323
+ attr.exclude_guest = evsel->core.attr.exclude_guest;
1324
+ attr.sample_id_all = evsel->core.attr.sample_id_all;
1325
+ attr.read_format = evsel->core.attr.read_format;
8631326
8641327 /* create new id val to be a fixed offset from evsel id */
865
- id = evsel->id[0] + 1000000000;
1328
+ id = evsel->core.id[0] + 1000000000;
8661329
8671330 if (!id)
8681331 id = 1;
....@@ -881,8 +1344,15 @@
8811344 attr.sample_type &= ~(u64)PERF_SAMPLE_ADDR;
8821345 }
8831346
884
- if (etm->synth_opts.last_branch)
1347
+ if (etm->synth_opts.last_branch) {
8851348 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
1349
+ /*
1350
+ * We don't use the hardware index, but the sample generation
1351
+ * code uses the new format branch_stack with this field,
1352
+ * so the event attributes must indicate that it's present.
1353
+ */
1354
+ attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;
1355
+ }
8861356
8871357 if (etm->synth_opts.instructions) {
8881358 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
....@@ -900,101 +1370,171 @@
9001370 return 0;
9011371 }
9021372
903
-static int cs_etm__sample(struct cs_etm_queue *etmq)
1373
+static int cs_etm__sample(struct cs_etm_queue *etmq,
1374
+ struct cs_etm_traceid_queue *tidq)
9041375 {
9051376 struct cs_etm_auxtrace *etm = etmq->etm;
906
- struct cs_etm_packet *tmp;
9071377 int ret;
908
- u64 instrs_executed;
1378
+ u8 trace_chan_id = tidq->trace_chan_id;
1379
+ u64 instrs_prev;
9091380
910
- instrs_executed = cs_etm__instr_count(etmq->packet);
911
- etmq->period_instructions += instrs_executed;
1381
+ /* Get instructions remainder from previous packet */
1382
+ instrs_prev = tidq->period_instructions;
1383
+
1384
+ tidq->period_instructions += tidq->packet->instr_count;
9121385
9131386 /*
9141387 * Record a branch when the last instruction in
9151388 * PREV_PACKET is a branch.
9161389 */
9171390 if (etm->synth_opts.last_branch &&
918
- etmq->prev_packet &&
919
- etmq->prev_packet->sample_type == CS_ETM_RANGE &&
920
- etmq->prev_packet->last_instr_taken_branch)
921
- cs_etm__update_last_branch_rb(etmq);
1391
+ tidq->prev_packet->sample_type == CS_ETM_RANGE &&
1392
+ tidq->prev_packet->last_instr_taken_branch)
1393
+ cs_etm__update_last_branch_rb(etmq, tidq);
9221394
9231395 if (etm->sample_instructions &&
924
- etmq->period_instructions >= etm->instructions_sample_period) {
1396
+ tidq->period_instructions >= etm->instructions_sample_period) {
9251397 /*
9261398 * Emit instruction sample periodically
9271399 * TODO: allow period to be defined in cycles and clock time
9281400 */
9291401
930
- /* Get number of instructions executed after the sample point */
931
- u64 instrs_over = etmq->period_instructions -
932
- etm->instructions_sample_period;
1402
+ /*
1403
+ * Below diagram demonstrates the instruction samples
1404
+ * generation flows:
1405
+ *
1406
+ * Instrs Instrs Instrs Instrs
1407
+ * Sample(n) Sample(n+1) Sample(n+2) Sample(n+3)
1408
+ * | | | |
1409
+ * V V V V
1410
+ * --------------------------------------------------
1411
+ * ^ ^
1412
+ * | |
1413
+ * Period Period
1414
+ * instructions(Pi) instructions(Pi')
1415
+ *
1416
+ * | |
1417
+ * \---------------- -----------------/
1418
+ * V
1419
+ * tidq->packet->instr_count
1420
+ *
1421
+ * Instrs Sample(n...) are the synthesised samples occurring
1422
+ * every etm->instructions_sample_period instructions - as
1423
+ * defined on the perf command line. Sample(n) is being the
1424
+ * last sample before the current etm packet, n+1 to n+3
1425
+ * samples are generated from the current etm packet.
1426
+ *
1427
+ * tidq->packet->instr_count represents the number of
1428
+ * instructions in the current etm packet.
1429
+ *
1430
+ * Period instructions (Pi) contains the the number of
1431
+ * instructions executed after the sample point(n) from the
1432
+ * previous etm packet. This will always be less than
1433
+ * etm->instructions_sample_period.
1434
+ *
1435
+ * When generate new samples, it combines with two parts
1436
+ * instructions, one is the tail of the old packet and another
1437
+ * is the head of the new coming packet, to generate
1438
+ * sample(n+1); sample(n+2) and sample(n+3) consume the
1439
+ * instructions with sample period. After sample(n+3), the rest
1440
+ * instructions will be used by later packet and it is assigned
1441
+ * to tidq->period_instructions for next round calculation.
1442
+ */
9331443
9341444 /*
935
- * Calculate the address of the sampled instruction (-1 as
936
- * sample is reported as though instruction has just been
937
- * executed, but PC has not advanced to next instruction)
1445
+ * Get the initial offset into the current packet instructions;
1446
+ * entry conditions ensure that instrs_prev is less than
1447
+ * etm->instructions_sample_period.
9381448 */
939
- u64 offset = (instrs_executed - instrs_over - 1);
940
- u64 addr = cs_etm__instr_addr(etmq->packet, offset);
1449
+ u64 offset = etm->instructions_sample_period - instrs_prev;
1450
+ u64 addr;
9411451
942
- ret = cs_etm__synth_instruction_sample(
943
- etmq, addr, etm->instructions_sample_period);
944
- if (ret)
945
- return ret;
1452
+ /* Prepare last branches for instruction sample */
1453
+ if (etm->synth_opts.last_branch)
1454
+ cs_etm__copy_last_branch_rb(etmq, tidq);
9461455
947
- /* Carry remaining instructions into next sample period */
948
- etmq->period_instructions = instrs_over;
1456
+ while (tidq->period_instructions >=
1457
+ etm->instructions_sample_period) {
1458
+ /*
1459
+ * Calculate the address of the sampled instruction (-1
1460
+ * as sample is reported as though instruction has just
1461
+ * been executed, but PC has not advanced to next
1462
+ * instruction)
1463
+ */
1464
+ addr = cs_etm__instr_addr(etmq, trace_chan_id,
1465
+ tidq->packet, offset - 1);
1466
+ ret = cs_etm__synth_instruction_sample(
1467
+ etmq, tidq, addr,
1468
+ etm->instructions_sample_period);
1469
+ if (ret)
1470
+ return ret;
1471
+
1472
+ offset += etm->instructions_sample_period;
1473
+ tidq->period_instructions -=
1474
+ etm->instructions_sample_period;
1475
+ }
9491476 }
9501477
951
- if (etm->sample_branches && etmq->prev_packet) {
1478
+ if (etm->sample_branches) {
9521479 bool generate_sample = false;
9531480
9541481 /* Generate sample for tracing on packet */
955
- if (etmq->prev_packet->sample_type == CS_ETM_TRACE_ON)
1482
+ if (tidq->prev_packet->sample_type == CS_ETM_DISCONTINUITY)
9561483 generate_sample = true;
9571484
9581485 /* Generate sample for branch taken packet */
959
- if (etmq->prev_packet->sample_type == CS_ETM_RANGE &&
960
- etmq->prev_packet->last_instr_taken_branch)
1486
+ if (tidq->prev_packet->sample_type == CS_ETM_RANGE &&
1487
+ tidq->prev_packet->last_instr_taken_branch)
9611488 generate_sample = true;
9621489
9631490 if (generate_sample) {
964
- ret = cs_etm__synth_branch_sample(etmq);
1491
+ ret = cs_etm__synth_branch_sample(etmq, tidq);
9651492 if (ret)
9661493 return ret;
9671494 }
9681495 }
9691496
970
- if (etm->sample_branches || etm->synth_opts.last_branch) {
971
- /*
972
- * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
973
- * the next incoming packet.
974
- */
975
- tmp = etmq->packet;
976
- etmq->packet = etmq->prev_packet;
977
- etmq->prev_packet = tmp;
978
- }
1497
+ cs_etm__packet_swap(etm, tidq);
9791498
9801499 return 0;
9811500 }
9821501
983
-static int cs_etm__flush(struct cs_etm_queue *etmq)
1502
+static int cs_etm__exception(struct cs_etm_traceid_queue *tidq)
1503
+{
1504
+ /*
1505
+ * When the exception packet is inserted, whether the last instruction
1506
+ * in previous range packet is taken branch or not, we need to force
1507
+ * to set 'prev_packet->last_instr_taken_branch' to true. This ensures
1508
+ * to generate branch sample for the instruction range before the
1509
+ * exception is trapped to kernel or before the exception returning.
1510
+ *
1511
+ * The exception packet includes the dummy address values, so don't
1512
+ * swap PACKET with PREV_PACKET. This keeps PREV_PACKET to be useful
1513
+ * for generating instruction and branch samples.
1514
+ */
1515
+ if (tidq->prev_packet->sample_type == CS_ETM_RANGE)
1516
+ tidq->prev_packet->last_instr_taken_branch = true;
1517
+
1518
+ return 0;
1519
+}
1520
+
1521
+static int cs_etm__flush(struct cs_etm_queue *etmq,
1522
+ struct cs_etm_traceid_queue *tidq)
9841523 {
9851524 int err = 0;
9861525 struct cs_etm_auxtrace *etm = etmq->etm;
987
- struct cs_etm_packet *tmp;
988
-
989
- if (!etmq->prev_packet)
990
- return 0;
9911526
9921527 /* Handle start tracing packet */
993
- if (etmq->prev_packet->sample_type == CS_ETM_EMPTY)
1528
+ if (tidq->prev_packet->sample_type == CS_ETM_EMPTY)
9941529 goto swap_packet;
9951530
9961531 if (etmq->etm->synth_opts.last_branch &&
997
- etmq->prev_packet->sample_type == CS_ETM_RANGE) {
1532
+ tidq->prev_packet->sample_type == CS_ETM_RANGE) {
1533
+ u64 addr;
1534
+
1535
+ /* Prepare last branches for instruction sample */
1536
+ cs_etm__copy_last_branch_rb(etmq, tidq);
1537
+
9981538 /*
9991539 * Generate a last branch event for the branches left in the
10001540 * circular buffer at the end of the trace.
....@@ -1002,129 +1542,611 @@
10021542 * Use the address of the end of the last reported execution
10031543 * range
10041544 */
1005
- u64 addr = cs_etm__last_executed_instr(etmq->prev_packet);
1545
+ addr = cs_etm__last_executed_instr(tidq->prev_packet);
10061546
10071547 err = cs_etm__synth_instruction_sample(
1008
- etmq, addr,
1009
- etmq->period_instructions);
1548
+ etmq, tidq, addr,
1549
+ tidq->period_instructions);
10101550 if (err)
10111551 return err;
10121552
1013
- etmq->period_instructions = 0;
1553
+ tidq->period_instructions = 0;
10141554
10151555 }
10161556
10171557 if (etm->sample_branches &&
1018
- etmq->prev_packet->sample_type == CS_ETM_RANGE) {
1019
- err = cs_etm__synth_branch_sample(etmq);
1558
+ tidq->prev_packet->sample_type == CS_ETM_RANGE) {
1559
+ err = cs_etm__synth_branch_sample(etmq, tidq);
10201560 if (err)
10211561 return err;
10221562 }
10231563
10241564 swap_packet:
1025
- if (etm->sample_branches || etm->synth_opts.last_branch) {
1026
- /*
1027
- * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
1028
- * the next incoming packet.
1029
- */
1030
- tmp = etmq->packet;
1031
- etmq->packet = etmq->prev_packet;
1032
- etmq->prev_packet = tmp;
1033
- }
1565
+ cs_etm__packet_swap(etm, tidq);
1566
+
1567
+ /* Reset last branches after flush the trace */
1568
+ if (etm->synth_opts.last_branch)
1569
+ cs_etm__reset_last_branch_rb(tidq);
10341570
10351571 return err;
10361572 }
10371573
1574
+static int cs_etm__end_block(struct cs_etm_queue *etmq,
1575
+ struct cs_etm_traceid_queue *tidq)
1576
+{
1577
+ int err;
1578
+
1579
+ /*
1580
+ * It has no new packet coming and 'etmq->packet' contains the stale
1581
+ * packet which was set at the previous time with packets swapping;
1582
+ * so skip to generate branch sample to avoid stale packet.
1583
+ *
1584
+ * For this case only flush branch stack and generate a last branch
1585
+ * event for the branches left in the circular buffer at the end of
1586
+ * the trace.
1587
+ */
1588
+ if (etmq->etm->synth_opts.last_branch &&
1589
+ tidq->prev_packet->sample_type == CS_ETM_RANGE) {
1590
+ u64 addr;
1591
+
1592
+ /* Prepare last branches for instruction sample */
1593
+ cs_etm__copy_last_branch_rb(etmq, tidq);
1594
+
1595
+ /*
1596
+ * Use the address of the end of the last reported execution
1597
+ * range.
1598
+ */
1599
+ addr = cs_etm__last_executed_instr(tidq->prev_packet);
1600
+
1601
+ err = cs_etm__synth_instruction_sample(
1602
+ etmq, tidq, addr,
1603
+ tidq->period_instructions);
1604
+ if (err)
1605
+ return err;
1606
+
1607
+ tidq->period_instructions = 0;
1608
+ }
1609
+
1610
+ return 0;
1611
+}
1612
+/*
1613
+ * cs_etm__get_data_block: Fetch a block from the auxtrace_buffer queue
1614
+ * if need be.
1615
+ * Returns: < 0 if error
1616
+ * = 0 if no more auxtrace_buffer to read
1617
+ * > 0 if the current buffer isn't empty yet
1618
+ */
1619
+static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
1620
+{
1621
+ int ret;
1622
+
1623
+ if (!etmq->buf_len) {
1624
+ ret = cs_etm__get_trace(etmq);
1625
+ if (ret <= 0)
1626
+ return ret;
1627
+ /*
1628
+ * We cannot assume consecutive blocks in the data file
1629
+ * are contiguous, reset the decoder to force re-sync.
1630
+ */
1631
+ ret = cs_etm_decoder__reset(etmq->decoder);
1632
+ if (ret)
1633
+ return ret;
1634
+ }
1635
+
1636
+ return etmq->buf_len;
1637
+}
1638
+
1639
+static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
1640
+ struct cs_etm_packet *packet,
1641
+ u64 end_addr)
1642
+{
1643
+ /* Initialise to keep compiler happy */
1644
+ u16 instr16 = 0;
1645
+ u32 instr32 = 0;
1646
+ u64 addr;
1647
+
1648
+ switch (packet->isa) {
1649
+ case CS_ETM_ISA_T32:
1650
+ /*
1651
+ * The SVC of T32 is defined in ARM DDI 0487D.a, F5.1.247:
1652
+ *
1653
+ * b'15 b'8
1654
+ * +-----------------+--------+
1655
+ * | 1 1 0 1 1 1 1 1 | imm8 |
1656
+ * +-----------------+--------+
1657
+ *
1658
+ * According to the specifiction, it only defines SVC for T32
1659
+ * with 16 bits instruction and has no definition for 32bits;
1660
+ * so below only read 2 bytes as instruction size for T32.
1661
+ */
1662
+ addr = end_addr - 2;
1663
+ cs_etm__mem_access(etmq, trace_chan_id, addr,
1664
+ sizeof(instr16), (u8 *)&instr16);
1665
+ if ((instr16 & 0xFF00) == 0xDF00)
1666
+ return true;
1667
+
1668
+ break;
1669
+ case CS_ETM_ISA_A32:
1670
+ /*
1671
+ * The SVC of A32 is defined in ARM DDI 0487D.a, F5.1.247:
1672
+ *
1673
+ * b'31 b'28 b'27 b'24
1674
+ * +---------+---------+-------------------------+
1675
+ * | !1111 | 1 1 1 1 | imm24 |
1676
+ * +---------+---------+-------------------------+
1677
+ */
1678
+ addr = end_addr - 4;
1679
+ cs_etm__mem_access(etmq, trace_chan_id, addr,
1680
+ sizeof(instr32), (u8 *)&instr32);
1681
+ if ((instr32 & 0x0F000000) == 0x0F000000 &&
1682
+ (instr32 & 0xF0000000) != 0xF0000000)
1683
+ return true;
1684
+
1685
+ break;
1686
+ case CS_ETM_ISA_A64:
1687
+ /*
1688
+ * The SVC of A64 is defined in ARM DDI 0487D.a, C6.2.294:
1689
+ *
1690
+ * b'31 b'21 b'4 b'0
1691
+ * +-----------------------+---------+-----------+
1692
+ * | 1 1 0 1 0 1 0 0 0 0 0 | imm16 | 0 0 0 0 1 |
1693
+ * +-----------------------+---------+-----------+
1694
+ */
1695
+ addr = end_addr - 4;
1696
+ cs_etm__mem_access(etmq, trace_chan_id, addr,
1697
+ sizeof(instr32), (u8 *)&instr32);
1698
+ if ((instr32 & 0xFFE0001F) == 0xd4000001)
1699
+ return true;
1700
+
1701
+ break;
1702
+ case CS_ETM_ISA_UNKNOWN:
1703
+ default:
1704
+ break;
1705
+ }
1706
+
1707
+ return false;
1708
+}
1709
+
1710
+static bool cs_etm__is_syscall(struct cs_etm_queue *etmq,
1711
+ struct cs_etm_traceid_queue *tidq, u64 magic)
1712
+{
1713
+ u8 trace_chan_id = tidq->trace_chan_id;
1714
+ struct cs_etm_packet *packet = tidq->packet;
1715
+ struct cs_etm_packet *prev_packet = tidq->prev_packet;
1716
+
1717
+ if (magic == __perf_cs_etmv3_magic)
1718
+ if (packet->exception_number == CS_ETMV3_EXC_SVC)
1719
+ return true;
1720
+
1721
+ /*
1722
+ * ETMv4 exception type CS_ETMV4_EXC_CALL covers SVC, SMC and
1723
+ * HVC cases; need to check if it's SVC instruction based on
1724
+ * packet address.
1725
+ */
1726
+ if (magic == __perf_cs_etmv4_magic) {
1727
+ if (packet->exception_number == CS_ETMV4_EXC_CALL &&
1728
+ cs_etm__is_svc_instr(etmq, trace_chan_id, prev_packet,
1729
+ prev_packet->end_addr))
1730
+ return true;
1731
+ }
1732
+
1733
+ return false;
1734
+}
1735
+
1736
+static bool cs_etm__is_async_exception(struct cs_etm_traceid_queue *tidq,
1737
+ u64 magic)
1738
+{
1739
+ struct cs_etm_packet *packet = tidq->packet;
1740
+
1741
+ if (magic == __perf_cs_etmv3_magic)
1742
+ if (packet->exception_number == CS_ETMV3_EXC_DEBUG_HALT ||
1743
+ packet->exception_number == CS_ETMV3_EXC_ASYNC_DATA_ABORT ||
1744
+ packet->exception_number == CS_ETMV3_EXC_PE_RESET ||
1745
+ packet->exception_number == CS_ETMV3_EXC_IRQ ||
1746
+ packet->exception_number == CS_ETMV3_EXC_FIQ)
1747
+ return true;
1748
+
1749
+ if (magic == __perf_cs_etmv4_magic)
1750
+ if (packet->exception_number == CS_ETMV4_EXC_RESET ||
1751
+ packet->exception_number == CS_ETMV4_EXC_DEBUG_HALT ||
1752
+ packet->exception_number == CS_ETMV4_EXC_SYSTEM_ERROR ||
1753
+ packet->exception_number == CS_ETMV4_EXC_INST_DEBUG ||
1754
+ packet->exception_number == CS_ETMV4_EXC_DATA_DEBUG ||
1755
+ packet->exception_number == CS_ETMV4_EXC_IRQ ||
1756
+ packet->exception_number == CS_ETMV4_EXC_FIQ)
1757
+ return true;
1758
+
1759
+ return false;
1760
+}
1761
+
1762
+static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq,
1763
+ struct cs_etm_traceid_queue *tidq,
1764
+ u64 magic)
1765
+{
1766
+ u8 trace_chan_id = tidq->trace_chan_id;
1767
+ struct cs_etm_packet *packet = tidq->packet;
1768
+ struct cs_etm_packet *prev_packet = tidq->prev_packet;
1769
+
1770
+ if (magic == __perf_cs_etmv3_magic)
1771
+ if (packet->exception_number == CS_ETMV3_EXC_SMC ||
1772
+ packet->exception_number == CS_ETMV3_EXC_HYP ||
1773
+ packet->exception_number == CS_ETMV3_EXC_JAZELLE_THUMBEE ||
1774
+ packet->exception_number == CS_ETMV3_EXC_UNDEFINED_INSTR ||
1775
+ packet->exception_number == CS_ETMV3_EXC_PREFETCH_ABORT ||
1776
+ packet->exception_number == CS_ETMV3_EXC_DATA_FAULT ||
1777
+ packet->exception_number == CS_ETMV3_EXC_GENERIC)
1778
+ return true;
1779
+
1780
+ if (magic == __perf_cs_etmv4_magic) {
1781
+ if (packet->exception_number == CS_ETMV4_EXC_TRAP ||
1782
+ packet->exception_number == CS_ETMV4_EXC_ALIGNMENT ||
1783
+ packet->exception_number == CS_ETMV4_EXC_INST_FAULT ||
1784
+ packet->exception_number == CS_ETMV4_EXC_DATA_FAULT)
1785
+ return true;
1786
+
1787
+ /*
1788
+ * For CS_ETMV4_EXC_CALL, except SVC other instructions
1789
+ * (SMC, HVC) are taken as sync exceptions.
1790
+ */
1791
+ if (packet->exception_number == CS_ETMV4_EXC_CALL &&
1792
+ !cs_etm__is_svc_instr(etmq, trace_chan_id, prev_packet,
1793
+ prev_packet->end_addr))
1794
+ return true;
1795
+
1796
+ /*
1797
+ * ETMv4 has 5 bits for exception number; if the numbers
1798
+ * are in the range ( CS_ETMV4_EXC_FIQ, CS_ETMV4_EXC_END ]
1799
+ * they are implementation defined exceptions.
1800
+ *
1801
+ * For this case, simply take it as sync exception.
1802
+ */
1803
+ if (packet->exception_number > CS_ETMV4_EXC_FIQ &&
1804
+ packet->exception_number <= CS_ETMV4_EXC_END)
1805
+ return true;
1806
+ }
1807
+
1808
+ return false;
1809
+}
1810
+
1811
+static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
1812
+ struct cs_etm_traceid_queue *tidq)
1813
+{
1814
+ struct cs_etm_packet *packet = tidq->packet;
1815
+ struct cs_etm_packet *prev_packet = tidq->prev_packet;
1816
+ u8 trace_chan_id = tidq->trace_chan_id;
1817
+ u64 magic;
1818
+ int ret;
1819
+
1820
+ switch (packet->sample_type) {
1821
+ case CS_ETM_RANGE:
1822
+ /*
1823
+ * Immediate branch instruction without neither link nor
1824
+ * return flag, it's normal branch instruction within
1825
+ * the function.
1826
+ */
1827
+ if (packet->last_instr_type == OCSD_INSTR_BR &&
1828
+ packet->last_instr_subtype == OCSD_S_INSTR_NONE) {
1829
+ packet->flags = PERF_IP_FLAG_BRANCH;
1830
+
1831
+ if (packet->last_instr_cond)
1832
+ packet->flags |= PERF_IP_FLAG_CONDITIONAL;
1833
+ }
1834
+
1835
+ /*
1836
+ * Immediate branch instruction with link (e.g. BL), this is
1837
+ * branch instruction for function call.
1838
+ */
1839
+ if (packet->last_instr_type == OCSD_INSTR_BR &&
1840
+ packet->last_instr_subtype == OCSD_S_INSTR_BR_LINK)
1841
+ packet->flags = PERF_IP_FLAG_BRANCH |
1842
+ PERF_IP_FLAG_CALL;
1843
+
1844
+ /*
1845
+ * Indirect branch instruction with link (e.g. BLR), this is
1846
+ * branch instruction for function call.
1847
+ */
1848
+ if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
1849
+ packet->last_instr_subtype == OCSD_S_INSTR_BR_LINK)
1850
+ packet->flags = PERF_IP_FLAG_BRANCH |
1851
+ PERF_IP_FLAG_CALL;
1852
+
1853
+ /*
1854
+ * Indirect branch instruction with subtype of
1855
+ * OCSD_S_INSTR_V7_IMPLIED_RET, this is explicit hint for
1856
+ * function return for A32/T32.
1857
+ */
1858
+ if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
1859
+ packet->last_instr_subtype == OCSD_S_INSTR_V7_IMPLIED_RET)
1860
+ packet->flags = PERF_IP_FLAG_BRANCH |
1861
+ PERF_IP_FLAG_RETURN;
1862
+
1863
+ /*
1864
+ * Indirect branch instruction without link (e.g. BR), usually
1865
+ * this is used for function return, especially for functions
1866
+ * within dynamic link lib.
1867
+ */
1868
+ if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
1869
+ packet->last_instr_subtype == OCSD_S_INSTR_NONE)
1870
+ packet->flags = PERF_IP_FLAG_BRANCH |
1871
+ PERF_IP_FLAG_RETURN;
1872
+
1873
+ /* Return instruction for function return. */
1874
+ if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
1875
+ packet->last_instr_subtype == OCSD_S_INSTR_V8_RET)
1876
+ packet->flags = PERF_IP_FLAG_BRANCH |
1877
+ PERF_IP_FLAG_RETURN;
1878
+
1879
+ /*
1880
+ * Decoder might insert a discontinuity in the middle of
1881
+ * instruction packets, fixup prev_packet with flag
1882
+ * PERF_IP_FLAG_TRACE_BEGIN to indicate restarting trace.
1883
+ */
1884
+ if (prev_packet->sample_type == CS_ETM_DISCONTINUITY)
1885
+ prev_packet->flags |= PERF_IP_FLAG_BRANCH |
1886
+ PERF_IP_FLAG_TRACE_BEGIN;
1887
+
1888
+ /*
1889
+ * If the previous packet is an exception return packet
1890
+ * and the return address just follows SVC instuction,
1891
+ * it needs to calibrate the previous packet sample flags
1892
+ * as PERF_IP_FLAG_SYSCALLRET.
1893
+ */
1894
+ if (prev_packet->flags == (PERF_IP_FLAG_BRANCH |
1895
+ PERF_IP_FLAG_RETURN |
1896
+ PERF_IP_FLAG_INTERRUPT) &&
1897
+ cs_etm__is_svc_instr(etmq, trace_chan_id,
1898
+ packet, packet->start_addr))
1899
+ prev_packet->flags = PERF_IP_FLAG_BRANCH |
1900
+ PERF_IP_FLAG_RETURN |
1901
+ PERF_IP_FLAG_SYSCALLRET;
1902
+ break;
1903
+ case CS_ETM_DISCONTINUITY:
1904
+ /*
1905
+ * The trace is discontinuous, if the previous packet is
1906
+ * instruction packet, set flag PERF_IP_FLAG_TRACE_END
1907
+ * for previous packet.
1908
+ */
1909
+ if (prev_packet->sample_type == CS_ETM_RANGE)
1910
+ prev_packet->flags |= PERF_IP_FLAG_BRANCH |
1911
+ PERF_IP_FLAG_TRACE_END;
1912
+ break;
1913
+ case CS_ETM_EXCEPTION:
1914
+ ret = cs_etm__get_magic(packet->trace_chan_id, &magic);
1915
+ if (ret)
1916
+ return ret;
1917
+
1918
+ /* The exception is for system call. */
1919
+ if (cs_etm__is_syscall(etmq, tidq, magic))
1920
+ packet->flags = PERF_IP_FLAG_BRANCH |
1921
+ PERF_IP_FLAG_CALL |
1922
+ PERF_IP_FLAG_SYSCALLRET;
1923
+ /*
1924
+ * The exceptions are triggered by external signals from bus,
1925
+ * interrupt controller, debug module, PE reset or halt.
1926
+ */
1927
+ else if (cs_etm__is_async_exception(tidq, magic))
1928
+ packet->flags = PERF_IP_FLAG_BRANCH |
1929
+ PERF_IP_FLAG_CALL |
1930
+ PERF_IP_FLAG_ASYNC |
1931
+ PERF_IP_FLAG_INTERRUPT;
1932
+ /*
1933
+ * Otherwise, exception is caused by trap, instruction &
1934
+ * data fault, or alignment errors.
1935
+ */
1936
+ else if (cs_etm__is_sync_exception(etmq, tidq, magic))
1937
+ packet->flags = PERF_IP_FLAG_BRANCH |
1938
+ PERF_IP_FLAG_CALL |
1939
+ PERF_IP_FLAG_INTERRUPT;
1940
+
1941
+ /*
1942
+ * When the exception packet is inserted, since exception
1943
+ * packet is not used standalone for generating samples
1944
+ * and it's affiliation to the previous instruction range
1945
+ * packet; so set previous range packet flags to tell perf
1946
+ * it is an exception taken branch.
1947
+ */
1948
+ if (prev_packet->sample_type == CS_ETM_RANGE)
1949
+ prev_packet->flags = packet->flags;
1950
+ break;
1951
+ case CS_ETM_EXCEPTION_RET:
1952
+ /*
1953
+ * When the exception return packet is inserted, since
1954
+ * exception return packet is not used standalone for
1955
+ * generating samples and it's affiliation to the previous
1956
+ * instruction range packet; so set previous range packet
1957
+ * flags to tell perf it is an exception return branch.
1958
+ *
1959
+ * The exception return can be for either system call or
1960
+ * other exception types; unfortunately the packet doesn't
1961
+ * contain exception type related info so we cannot decide
1962
+ * the exception type purely based on exception return packet.
1963
+ * If we record the exception number from exception packet and
1964
+ * reuse it for excpetion return packet, this is not reliable
1965
+ * due the trace can be discontinuity or the interrupt can
1966
+ * be nested, thus the recorded exception number cannot be
1967
+ * used for exception return packet for these two cases.
1968
+ *
1969
+ * For exception return packet, we only need to distinguish the
1970
+ * packet is for system call or for other types. Thus the
1971
+ * decision can be deferred when receive the next packet which
1972
+ * contains the return address, based on the return address we
1973
+ * can read out the previous instruction and check if it's a
1974
+ * system call instruction and then calibrate the sample flag
1975
+ * as needed.
1976
+ */
1977
+ if (prev_packet->sample_type == CS_ETM_RANGE)
1978
+ prev_packet->flags = PERF_IP_FLAG_BRANCH |
1979
+ PERF_IP_FLAG_RETURN |
1980
+ PERF_IP_FLAG_INTERRUPT;
1981
+ break;
1982
+ case CS_ETM_EMPTY:
1983
+ default:
1984
+ break;
1985
+ }
1986
+
1987
+ return 0;
1988
+}
1989
+
1990
+static int cs_etm__decode_data_block(struct cs_etm_queue *etmq)
1991
+{
1992
+ int ret = 0;
1993
+ size_t processed = 0;
1994
+
1995
+ /*
1996
+ * Packets are decoded and added to the decoder's packet queue
1997
+ * until the decoder packet processing callback has requested that
1998
+ * processing stops or there is nothing left in the buffer. Normal
1999
+ * operations that stop processing are a timestamp packet or a full
2000
+ * decoder buffer queue.
2001
+ */
2002
+ ret = cs_etm_decoder__process_data_block(etmq->decoder,
2003
+ etmq->offset,
2004
+ &etmq->buf[etmq->buf_used],
2005
+ etmq->buf_len,
2006
+ &processed);
2007
+ if (ret)
2008
+ goto out;
2009
+
2010
+ etmq->offset += processed;
2011
+ etmq->buf_used += processed;
2012
+ etmq->buf_len -= processed;
2013
+
2014
+out:
2015
+ return ret;
2016
+}
2017
+
2018
+static int cs_etm__process_traceid_queue(struct cs_etm_queue *etmq,
2019
+ struct cs_etm_traceid_queue *tidq)
2020
+{
2021
+ int ret;
2022
+ struct cs_etm_packet_queue *packet_queue;
2023
+
2024
+ packet_queue = &tidq->packet_queue;
2025
+
2026
+ /* Process each packet in this chunk */
2027
+ while (1) {
2028
+ ret = cs_etm_decoder__get_packet(packet_queue,
2029
+ tidq->packet);
2030
+ if (ret <= 0)
2031
+ /*
2032
+ * Stop processing this chunk on
2033
+ * end of data or error
2034
+ */
2035
+ break;
2036
+
2037
+ /*
2038
+ * Since packet addresses are swapped in packet
2039
+ * handling within below switch() statements,
2040
+ * thus setting sample flags must be called
2041
+ * prior to switch() statement to use address
2042
+ * information before packets swapping.
2043
+ */
2044
+ ret = cs_etm__set_sample_flags(etmq, tidq);
2045
+ if (ret < 0)
2046
+ break;
2047
+
2048
+ switch (tidq->packet->sample_type) {
2049
+ case CS_ETM_RANGE:
2050
+ /*
2051
+ * If the packet contains an instruction
2052
+ * range, generate instruction sequence
2053
+ * events.
2054
+ */
2055
+ cs_etm__sample(etmq, tidq);
2056
+ break;
2057
+ case CS_ETM_EXCEPTION:
2058
+ case CS_ETM_EXCEPTION_RET:
2059
+ /*
2060
+ * If the exception packet is coming,
2061
+ * make sure the previous instruction
2062
+ * range packet to be handled properly.
2063
+ */
2064
+ cs_etm__exception(tidq);
2065
+ break;
2066
+ case CS_ETM_DISCONTINUITY:
2067
+ /*
2068
+ * Discontinuity in trace, flush
2069
+ * previous branch stack
2070
+ */
2071
+ cs_etm__flush(etmq, tidq);
2072
+ break;
2073
+ case CS_ETM_EMPTY:
2074
+ /*
2075
+ * Should not receive empty packet,
2076
+ * report error.
2077
+ */
2078
+ pr_err("CS ETM Trace: empty packet\n");
2079
+ return -EINVAL;
2080
+ default:
2081
+ break;
2082
+ }
2083
+ }
2084
+
2085
+ return ret;
2086
+}
2087
+
2088
+static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
2089
+{
2090
+ int idx;
2091
+ struct int_node *inode;
2092
+ struct cs_etm_traceid_queue *tidq;
2093
+ struct intlist *traceid_queues_list = etmq->traceid_queues_list;
2094
+
2095
+ intlist__for_each_entry(inode, traceid_queues_list) {
2096
+ idx = (int)(intptr_t)inode->priv;
2097
+ tidq = etmq->traceid_queues[idx];
2098
+
2099
+ /* Ignore return value */
2100
+ cs_etm__process_traceid_queue(etmq, tidq);
2101
+
2102
+ /*
2103
+ * Generate an instruction sample with the remaining
2104
+ * branchstack entries.
2105
+ */
2106
+ cs_etm__flush(etmq, tidq);
2107
+ }
2108
+}
2109
+
10382110 static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
10392111 {
1040
- struct cs_etm_auxtrace *etm = etmq->etm;
1041
- struct cs_etm_buffer buffer;
1042
- size_t buffer_used, processed;
10432112 int err = 0;
2113
+ struct cs_etm_traceid_queue *tidq;
10442114
1045
- if (!etm->kernel_start)
1046
- etm->kernel_start = machine__kernel_start(etm->machine);
2115
+ tidq = cs_etm__etmq_get_traceid_queue(etmq, CS_ETM_PER_THREAD_TRACEID);
2116
+ if (!tidq)
2117
+ return -EINVAL;
10472118
10482119 /* Go through each buffer in the queue and decode them one by one */
10492120 while (1) {
1050
- buffer_used = 0;
1051
- memset(&buffer, 0, sizeof(buffer));
1052
- err = cs_etm__get_trace(&buffer, etmq);
2121
+ err = cs_etm__get_data_block(etmq);
10532122 if (err <= 0)
1054
- return err;
1055
- /*
1056
- * We cannot assume consecutive blocks in the data file are
1057
- * contiguous, reset the decoder to force re-sync.
1058
- */
1059
- err = cs_etm_decoder__reset(etmq->decoder);
1060
- if (err != 0)
10612123 return err;
10622124
10632125 /* Run trace decoder until buffer consumed or end of trace */
10642126 do {
1065
- processed = 0;
1066
- err = cs_etm_decoder__process_data_block(
1067
- etmq->decoder,
1068
- etmq->offset,
1069
- &buffer.buf[buffer_used],
1070
- buffer.len - buffer_used,
1071
- &processed);
2127
+ err = cs_etm__decode_data_block(etmq);
10722128 if (err)
10732129 return err;
10742130
1075
- etmq->offset += processed;
1076
- buffer_used += processed;
2131
+ /*
2132
+ * Process each packet in this chunk, nothing to do if
2133
+ * an error occurs other than hoping the next one will
2134
+ * be better.
2135
+ */
2136
+ err = cs_etm__process_traceid_queue(etmq, tidq);
10772137
1078
- /* Process each packet in this chunk */
1079
- while (1) {
1080
- err = cs_etm_decoder__get_packet(etmq->decoder,
1081
- etmq->packet);
1082
- if (err <= 0)
1083
- /*
1084
- * Stop processing this chunk on
1085
- * end of data or error
1086
- */
1087
- break;
1088
-
1089
- switch (etmq->packet->sample_type) {
1090
- case CS_ETM_RANGE:
1091
- /*
1092
- * If the packet contains an instruction
1093
- * range, generate instruction sequence
1094
- * events.
1095
- */
1096
- cs_etm__sample(etmq);
1097
- break;
1098
- case CS_ETM_TRACE_ON:
1099
- /*
1100
- * Discontinuity in trace, flush
1101
- * previous branch stack
1102
- */
1103
- cs_etm__flush(etmq);
1104
- break;
1105
- case CS_ETM_EMPTY:
1106
- /*
1107
- * Should not receive empty packet,
1108
- * report error.
1109
- */
1110
- pr_err("CS ETM Trace: empty packet\n");
1111
- return -EINVAL;
1112
- default:
1113
- break;
1114
- }
1115
- }
1116
- } while (buffer.len > buffer_used);
2138
+ } while (etmq->buf_len);
11172139
11182140 if (err == 0)
11192141 /* Flush any remaining branch stack entries */
1120
- err = cs_etm__flush(etmq);
2142
+ err = cs_etm__end_block(etmq, tidq);
11212143 }
11222144
11232145 return err;
11242146 }
11252147
11262148 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
1127
- pid_t tid, u64 time_)
2149
+ pid_t tid)
11282150 {
11292151 unsigned int i;
11302152 struct auxtrace_queues *queues = &etm->queues;
....@@ -1132,13 +2154,180 @@
11322154 for (i = 0; i < queues->nr_queues; i++) {
11332155 struct auxtrace_queue *queue = &etm->queues.queue_array[i];
11342156 struct cs_etm_queue *etmq = queue->priv;
2157
+ struct cs_etm_traceid_queue *tidq;
11352158
1136
- if (etmq && ((tid == -1) || (etmq->tid == tid))) {
1137
- etmq->time = time_;
1138
- cs_etm__set_pid_tid_cpu(etm, queue);
2159
+ if (!etmq)
2160
+ continue;
2161
+
2162
+ tidq = cs_etm__etmq_get_traceid_queue(etmq,
2163
+ CS_ETM_PER_THREAD_TRACEID);
2164
+
2165
+ if (!tidq)
2166
+ continue;
2167
+
2168
+ if ((tid == -1) || (tidq->tid == tid)) {
2169
+ cs_etm__set_pid_tid_cpu(etm, tidq);
11392170 cs_etm__run_decoder(etmq);
11402171 }
11412172 }
2173
+
2174
+ return 0;
2175
+}
2176
+
2177
+static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
2178
+{
2179
+ int ret = 0;
2180
+ unsigned int cs_queue_nr, queue_nr;
2181
+ u8 trace_chan_id;
2182
+ u64 timestamp;
2183
+ struct auxtrace_queue *queue;
2184
+ struct cs_etm_queue *etmq;
2185
+ struct cs_etm_traceid_queue *tidq;
2186
+
2187
+ while (1) {
2188
+ if (!etm->heap.heap_cnt)
2189
+ goto out;
2190
+
2191
+ /* Take the entry at the top of the min heap */
2192
+ cs_queue_nr = etm->heap.heap_array[0].queue_nr;
2193
+ queue_nr = TO_QUEUE_NR(cs_queue_nr);
2194
+ trace_chan_id = TO_TRACE_CHAN_ID(cs_queue_nr);
2195
+ queue = &etm->queues.queue_array[queue_nr];
2196
+ etmq = queue->priv;
2197
+
2198
+ /*
2199
+ * Remove the top entry from the heap since we are about
2200
+ * to process it.
2201
+ */
2202
+ auxtrace_heap__pop(&etm->heap);
2203
+
2204
+ tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
2205
+ if (!tidq) {
2206
+ /*
2207
+ * No traceID queue has been allocated for this traceID,
2208
+ * which means something somewhere went very wrong. No
2209
+ * other choice than simply exit.
2210
+ */
2211
+ ret = -EINVAL;
2212
+ goto out;
2213
+ }
2214
+
2215
+ /*
2216
+ * Packets associated with this timestamp are already in
2217
+ * the etmq's traceID queue, so process them.
2218
+ */
2219
+ ret = cs_etm__process_traceid_queue(etmq, tidq);
2220
+ if (ret < 0)
2221
+ goto out;
2222
+
2223
+ /*
2224
+ * Packets for this timestamp have been processed, time to
2225
+ * move on to the next timestamp, fetching a new auxtrace_buffer
2226
+ * if need be.
2227
+ */
2228
+refetch:
2229
+ ret = cs_etm__get_data_block(etmq);
2230
+ if (ret < 0)
2231
+ goto out;
2232
+
2233
+ /*
2234
+ * No more auxtrace_buffers to process in this etmq, simply
2235
+ * move on to another entry in the auxtrace_heap.
2236
+ */
2237
+ if (!ret)
2238
+ continue;
2239
+
2240
+ ret = cs_etm__decode_data_block(etmq);
2241
+ if (ret)
2242
+ goto out;
2243
+
2244
+ timestamp = cs_etm__etmq_get_timestamp(etmq, &trace_chan_id);
2245
+
2246
+ if (!timestamp) {
2247
+ /*
2248
+ * Function cs_etm__decode_data_block() returns when
2249
+ * there is no more traces to decode in the current
2250
+ * auxtrace_buffer OR when a timestamp has been
2251
+ * encountered on any of the traceID queues. Since we
2252
+ * did not get a timestamp, there is no more traces to
2253
+ * process in this auxtrace_buffer. As such empty and
2254
+ * flush all traceID queues.
2255
+ */
2256
+ cs_etm__clear_all_traceid_queues(etmq);
2257
+
2258
+ /* Fetch another auxtrace_buffer for this etmq */
2259
+ goto refetch;
2260
+ }
2261
+
2262
+ /*
2263
+ * Add to the min heap the timestamp for packets that have
2264
+ * just been decoded. They will be processed and synthesized
2265
+ * during the next call to cs_etm__process_traceid_queue() for
2266
+ * this queue/traceID.
2267
+ */
2268
+ cs_queue_nr = TO_CS_QUEUE_NR(queue_nr, trace_chan_id);
2269
+ ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, timestamp);
2270
+ }
2271
+
2272
+out:
2273
+ return ret;
2274
+}
2275
+
2276
+static int cs_etm__process_itrace_start(struct cs_etm_auxtrace *etm,
2277
+ union perf_event *event)
2278
+{
2279
+ struct thread *th;
2280
+
2281
+ if (etm->timeless_decoding)
2282
+ return 0;
2283
+
2284
+ /*
2285
+ * Add the tid/pid to the log so that we can get a match when
2286
+ * we get a contextID from the decoder.
2287
+ */
2288
+ th = machine__findnew_thread(etm->machine,
2289
+ event->itrace_start.pid,
2290
+ event->itrace_start.tid);
2291
+ if (!th)
2292
+ return -ENOMEM;
2293
+
2294
+ thread__put(th);
2295
+
2296
+ return 0;
2297
+}
2298
+
2299
+static int cs_etm__process_switch_cpu_wide(struct cs_etm_auxtrace *etm,
2300
+ union perf_event *event)
2301
+{
2302
+ struct thread *th;
2303
+ bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
2304
+
2305
+ /*
2306
+ * Context switch in per-thread mode are irrelevant since perf
2307
+ * will start/stop tracing as the process is scheduled.
2308
+ */
2309
+ if (etm->timeless_decoding)
2310
+ return 0;
2311
+
2312
+ /*
2313
+ * SWITCH_IN events carry the next process to be switched out while
2314
+ * SWITCH_OUT events carry the process to be switched in. As such
2315
+ * we don't care about IN events.
2316
+ */
2317
+ if (!out)
2318
+ return 0;
2319
+
2320
+ /*
2321
+ * Add the tid/pid to the log so that we can get a match when
2322
+ * we get a contextID from the decoder.
2323
+ */
2324
+ th = machine__findnew_thread(etm->machine,
2325
+ event->context_switch.next_prev_pid,
2326
+ event->context_switch.next_prev_tid);
2327
+ if (!th)
2328
+ return -ENOMEM;
2329
+
2330
+ thread__put(th);
11422331
11432332 return 0;
11442333 }
....@@ -1162,9 +2351,6 @@
11622351 return -EINVAL;
11632352 }
11642353
1165
- if (!etm->timeless_decoding)
1166
- return -EINVAL;
1167
-
11682354 if (sample->time && (sample->time != (u64) -1))
11692355 timestamp = sample->time;
11702356 else
....@@ -1176,10 +2362,19 @@
11762362 return err;
11772363 }
11782364
1179
- if (event->header.type == PERF_RECORD_EXIT)
2365
+ if (etm->timeless_decoding &&
2366
+ event->header.type == PERF_RECORD_EXIT)
11802367 return cs_etm__process_timeless_queues(etm,
1181
- event->fork.tid,
1182
- sample->time);
2368
+ event->fork.tid);
2369
+
2370
+ if (event->header.type == PERF_RECORD_ITRACE_START)
2371
+ return cs_etm__process_itrace_start(etm, event);
2372
+ else if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)
2373
+ return cs_etm__process_switch_cpu_wide(etm, event);
2374
+
2375
+ if (!etm->timeless_decoding &&
2376
+ event->header.type == PERF_RECORD_AUX)
2377
+ return cs_etm__process_queues(etm);
11832378
11842379 return 0;
11852380 }
....@@ -1223,8 +2418,8 @@
12232418
12242419 static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
12252420 {
1226
- struct perf_evsel *evsel;
1227
- struct perf_evlist *evlist = etm->session->evlist;
2421
+ struct evsel *evsel;
2422
+ struct evlist *evlist = etm->session->evlist;
12282423 bool timeless_decoding = true;
12292424
12302425 /*
....@@ -1232,7 +2427,7 @@
12322427 * with the time bit set.
12332428 */
12342429 evlist__for_each_entry(evlist, evsel) {
1235
- if ((evsel->attr.sample_type & PERF_SAMPLE_TIME))
2430
+ if ((evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
12362431 timeless_decoding = false;
12372432 }
12382433
....@@ -1266,7 +2461,7 @@
12662461 [CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %llx\n",
12672462 };
12682463
1269
-static void cs_etm__print_auxtrace_info(u64 *val, int num)
2464
+static void cs_etm__print_auxtrace_info(__u64 *val, int num)
12702465 {
12712466 int i, j, cpu = 0;
12722467
....@@ -1289,7 +2484,7 @@
12892484 int cs_etm__process_auxtrace_info(union perf_event *event,
12902485 struct perf_session *session)
12912486 {
1292
- struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info;
2487
+ struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
12932488 struct cs_etm_auxtrace *etm = NULL;
12942489 struct int_node *inode;
12952490 unsigned int pmu_type;
....@@ -1389,7 +2584,7 @@
13892584
13902585 /* Something went wrong, no need to continue */
13912586 if (!inode) {
1392
- err = PTR_ERR(inode);
2587
+ err = -ENOMEM;
13932588 goto err_free_metadata;
13942589 }
13952590
....@@ -1443,11 +2638,14 @@
14432638 etm->auxtrace.flush_events = cs_etm__flush_events;
14442639 etm->auxtrace.free_events = cs_etm__free_events;
14452640 etm->auxtrace.free = cs_etm__free;
2641
+ etm->auxtrace.evsel_is_auxtrace = cs_etm__evsel_is_auxtrace;
14462642 session->auxtrace = &etm->auxtrace;
14472643
14482644 etm->unknown_thread = thread__new(999999999, 999999999);
1449
- if (!etm->unknown_thread)
2645
+ if (!etm->unknown_thread) {
2646
+ err = -ENOMEM;
14502647 goto err_free_queues;
2648
+ }
14512649
14522650 /*
14532651 * Initialize list node so that at thread__zput() we can avoid
....@@ -1459,18 +2657,21 @@
14592657 if (err)
14602658 goto err_delete_thread;
14612659
1462
- if (thread__init_map_groups(etm->unknown_thread, etm->machine))
2660
+ if (thread__init_maps(etm->unknown_thread, etm->machine)) {
2661
+ err = -ENOMEM;
14632662 goto err_delete_thread;
2663
+ }
14642664
14652665 if (dump_trace) {
14662666 cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
14672667 return 0;
14682668 }
14692669
1470
- if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
2670
+ if (session->itrace_synth_opts->set) {
14712671 etm->synth_opts = *session->itrace_synth_opts;
14722672 } else {
1473
- itrace_synth_opts__set_default(&etm->synth_opts);
2673
+ itrace_synth_opts__set_default(&etm->synth_opts,
2674
+ session->itrace_synth_opts->default_no_sample);
14742675 etm->synth_opts.callchain = false;
14752676 }
14762677
....@@ -1496,12 +2697,12 @@
14962697 err_free_metadata:
14972698 /* No need to check @metadata[j], free(NULL) is supported */
14982699 for (j = 0; j < num_cpu; j++)
1499
- free(metadata[j]);
2700
+ zfree(&metadata[j]);
15002701 zfree(&metadata);
15012702 err_free_traceid_list:
15022703 intlist__delete(traceid_list);
15032704 err_free_hdr:
15042705 zfree(&hdr);
15052706
1506
- return -EINVAL;
2707
+ return err;
15072708 }