In the case of mixed formatted and unformatted trace with v0 HW_IDs, or no HW_IDs at all resulting in the cs_etm__map_trace_ids_metadata() fallback, formatted queues will write their HW_IDs to unformatted queues. This will result in an assert because of multiple decoders on an unformatted queue.
Fix it by not inserting trace ID nodes on other unformatted queues. This isn't an issue for v0.1 HW_IDs because they aren't global so will only add to their own queue.
Fixes: 19c3e4db38c5 ("perf: cs-etm: Create decoders based on the trace ID mappings") Signed-off-by: James Clark james.clark@linaro.org --- tools/perf/util/cs-etm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 6e04602ec204..8dfafd389066 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -306,27 +306,27 @@ static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id { struct cs_etm_queue *etmq;
- /* - * If the queue is unformatted then only save one mapping in the - * queue associated with that CPU so only one decoder is made. - */ etmq = cs_etm__get_queue(etm, cpu_metadata[CS_ETM_CPU]); if (!etmq) return -EINVAL;
+ /* + * If the queue is unformatted then only save one mapping in the + * queue associated with that CPU so only one decoder is made. + */ if (etmq->format == UNFORMATTED) return cs_etm__insert_trace_id_node(etmq, trace_chan_id, cpu_metadata);
/* * Otherwise, version 0 trace IDs are global so save them into every - * queue. + * formatted queue. */ for (unsigned int i = 0; i < etm->queues.nr_queues; ++i) { int ret;
etmq = etm->queues.queue_array[i].priv; - if (!etmq) + if (!etmq || etmq->format == UNFORMATTED) continue;
ret = cs_etm__insert_trace_id_node(etmq, trace_chan_id,