[PATCH 2/6] perf cs-etm: Free partially created queues

From: James Clark

Date: Fri Aug 21 2026 - 06:09:39 EST


cs_etm__create_decoders() can fail half way through and the
err_free_queues label won't free them. Call the full queue free function
here instead. If no decoders were created it's a nop.

Signed-off-by: James Clark <james.clark@xxxxxxxxxx>
---
tools/perf/util/cs-etm.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 8dfafd389066..44e20067da1f 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -1014,13 +1014,10 @@ static void cs_etm__free_queue(void *priv)
free(etmq);
}

-static void cs_etm__free_events(struct perf_session *session)
+static void cs_etm__free_queues(struct cs_etm_auxtrace *etm)
{
unsigned int i;
- struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
- struct cs_etm_auxtrace,
- auxtrace);
- struct auxtrace_queues *queues = &aux->queues;
+ struct auxtrace_queues *queues = &etm->queues;

for (i = 0; i < queues->nr_queues; i++) {
cs_etm__free_queue(queues->queue_array[i].priv);
@@ -1030,13 +1027,23 @@ static void cs_etm__free_events(struct perf_session *session)
auxtrace_queues__free(queues);
}

+static void cs_etm__free_events(struct perf_session *session)
+{
+ struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
+ struct cs_etm_auxtrace,
+ auxtrace);
+
+ cs_etm__free_queues(aux);
+}
+
static void cs_etm__free(struct perf_session *session)
{
int i;
struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
struct cs_etm_auxtrace,
auxtrace);
- cs_etm__free_events(session);
+
+ cs_etm__free_queues(aux);
session->auxtrace = NULL;

for (i = 0; i < aux->num_cpu; i++)
@@ -3520,6 +3527,7 @@ static int cs_etm__create_queue_decoders(struct cs_etm_queue *etmq)

out_free_decoder:
cs_etm_decoder__free(etmq->decoder);
+ etmq->decoder = NULL;
out_free:
zfree(&t_params);
return -EINVAL;
@@ -3801,7 +3809,7 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
return 0;

err_free_queues:
- auxtrace_queues__free(&etm->queues);
+ cs_etm__free_queues(etm);
session->auxtrace = NULL;
err_free_etm:
zfree(&etm);

--
2.43.0