perf cs-etm: Free partially created queues

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.

Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
James Clark 2026-10-02 12:15:12 +01:00 committed by Arnaldo Carvalho de Melo
parent 31627cfb63
commit 18eaa04d94
3 changed files with 23 additions and 16 deletions

View File

@ -741,7 +741,7 @@ cs_etm_decoder__new(int decoders, struct cs_etm_decoder_params *d_params,
return decoder;
err_free_decoder:
cs_etm_decoder__free(decoder);
cs_etm_decoder__zfree(&decoder);
return NULL;
}
@ -793,14 +793,14 @@ int cs_etm_decoder__process_data_block(struct cs_etm_decoder *decoder,
return ret;
}
void cs_etm_decoder__free(struct cs_etm_decoder *decoder)
void cs_etm_decoder__zfree(struct cs_etm_decoder **decoder)
{
if (!decoder)
if (!(*decoder))
return;
ocsd_destroy_dcd_tree(decoder->dcd_tree);
decoder->dcd_tree = NULL;
free(decoder);
ocsd_destroy_dcd_tree((*decoder)->dcd_tree);
(*decoder)->dcd_tree = NULL;
zfree(decoder);
}
const char *cs_etm_decoder__get_name(struct cs_etm_decoder *decoder)

View File

@ -96,7 +96,7 @@ cs_etm_decoder__new(int num_cpu,
struct cs_etm_decoder_params *d_params,
struct cs_etm_trace_params t_params[]);
void cs_etm_decoder__free(struct cs_etm_decoder *decoder);
void cs_etm_decoder__zfree(struct cs_etm_decoder **decoder);
int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder,
u64 start, u64 end,

View File

@ -1002,7 +1002,7 @@ static void cs_etm__free_queue(void *priv)
if (!etmq)
return;
cs_etm_decoder__free(etmq->decoder);
cs_etm_decoder__zfree(&etmq->decoder);
cs_etm__free_traceid_queues(etmq);
if (etmq->own_traceid_list) {
@ -1017,13 +1017,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);
@ -1033,13 +1030,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++)
@ -3476,7 +3483,7 @@ static int cs_etm__create_queue_decoders(struct cs_etm_queue *etmq)
return 0;
out_free_decoder:
cs_etm_decoder__free(etmq->decoder);
cs_etm_decoder__zfree(&etmq->decoder);
out_free:
zfree(&t_params);
return -EINVAL;
@ -3758,7 +3765,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);