aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Yan <leo.yan@linaro.org>2018-05-10 00:01:59 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-05-11 09:45:23 -0400
commit46d53620044f7b574c0f3216f8b4f2ce3559ce31 (patch)
tree2d46f5e59edf875cfb85ea103f5cc09e393bc057
parent04d2600ab669b2d44dd7920cc8a1b95c8144084c (diff)
perf cs-etm: Support unknown_thread in cs_etm_auxtrace
CoreSight doesn't allocate thread structure for unknown_thread in ETM auxtrace, so unknown_thread is NULL pointer. If the perf data doesn't contain valid tid and then cs_etm__mem_access() uses unknown_thread instead as thread handler, this results in a segmentation fault when thread__find_addr_map() accesses the thread handler. This commit creates a new thread data which is used by unknown_thread, so CoreSight tracing can roll back to use unknown_thread if perf data doesn't include valid thread info. This commit also releases thread data for initialization failure case and for normal auxtrace free flow. Signed-off-by: Leo Yan <leo.yan@linaro.org> Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1525924920-4381-1-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/cs-etm.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 40020b1ca54f..2bf28b5acc08 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -239,6 +239,7 @@ static void cs_etm__free(struct perf_session *session)
239 for (i = 0; i < aux->num_cpu; i++) 239 for (i = 0; i < aux->num_cpu; i++)
240 zfree(&aux->metadata[i]); 240 zfree(&aux->metadata[i]);
241 241
242 thread__zput(aux->unknown_thread);
242 zfree(&aux->metadata); 243 zfree(&aux->metadata);
243 zfree(&aux); 244 zfree(&aux);
244} 245}
@@ -1357,6 +1358,23 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
1357 etm->auxtrace.free = cs_etm__free; 1358 etm->auxtrace.free = cs_etm__free;
1358 session->auxtrace = &etm->auxtrace; 1359 session->auxtrace = &etm->auxtrace;
1359 1360
1361 etm->unknown_thread = thread__new(999999999, 999999999);
1362 if (!etm->unknown_thread)
1363 goto err_free_queues;
1364
1365 /*
1366 * Initialize list node so that at thread__zput() we can avoid
1367 * segmentation fault at list_del_init().
1368 */
1369 INIT_LIST_HEAD(&etm->unknown_thread->node);
1370
1371 err = thread__set_comm(etm->unknown_thread, "unknown", 0);
1372 if (err)
1373 goto err_delete_thread;
1374
1375 if (thread__init_map_groups(etm->unknown_thread, etm->machine))
1376 goto err_delete_thread;
1377
1360 if (dump_trace) { 1378 if (dump_trace) {
1361 cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu); 1379 cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
1362 return 0; 1380 return 0;
@@ -1371,16 +1389,18 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
1371 1389
1372 err = cs_etm__synth_events(etm, session); 1390 err = cs_etm__synth_events(etm, session);
1373 if (err) 1391 if (err)
1374 goto err_free_queues; 1392 goto err_delete_thread;
1375 1393
1376 err = auxtrace_queues__process_index(&etm->queues, session); 1394 err = auxtrace_queues__process_index(&etm->queues, session);
1377 if (err) 1395 if (err)
1378 goto err_free_queues; 1396 goto err_delete_thread;
1379 1397
1380 etm->data_queued = etm->queues.populated; 1398 etm->data_queued = etm->queues.populated;
1381 1399
1382 return 0; 1400 return 0;
1383 1401
1402err_delete_thread:
1403 thread__zput(etm->unknown_thread);
1384err_free_queues: 1404err_free_queues:
1385 auxtrace_queues__free(&etm->queues); 1405 auxtrace_queues__free(&etm->queues);
1386 session->auxtrace = NULL; 1406 session->auxtrace = NULL;