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 --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 12 ++++++------ tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 2 +- tools/perf/util/cs-etm.c | 25 ++++++++++++++++--------- 3 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 26940f1f1b0b..b56cf57a68c8 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -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) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h index 12c782fa6db2..2a8214f17958 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -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, diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index fda6b6c02e26..78ae8443ac96 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -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);