perf cs-etm: Modularize main packet processing loop

Making the main packet processing loop modular so that it can be called
from different decoding context (timeless vs. non-timless), avoiding to
repeat code.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Suzuki K Poulouse <suzuki.poulose@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/20190212171618.25355-13-mathieu.poirier@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Mathieu Poirier 2019-02-12 10:16:17 -07:00 committed by Arnaldo Carvalho de Melo
parent f74f349c21
commit 3fa0e83e29

View file

@ -1519,6 +1519,72 @@ static int cs_etm__decode_data_block(struct cs_etm_queue *etmq)
return ret;
}
static int cs_etm__process_decoder_queue(struct cs_etm_queue *etmq)
{
int ret;
/* Process each packet in this chunk */
while (1) {
ret = cs_etm_decoder__get_packet(etmq->decoder,
etmq->packet);
if (ret <= 0)
/*
* Stop processing this chunk on
* end of data or error
*/
break;
/*
* Since packet addresses are swapped in packet
* handling within below switch() statements,
* thus setting sample flags must be called
* prior to switch() statement to use address
* information before packets swapping.
*/
ret = cs_etm__set_sample_flags(etmq);
if (ret < 0)
break;
switch (etmq->packet->sample_type) {
case CS_ETM_RANGE:
/*
* If the packet contains an instruction
* range, generate instruction sequence
* events.
*/
cs_etm__sample(etmq);
break;
case CS_ETM_EXCEPTION:
case CS_ETM_EXCEPTION_RET:
/*
* If the exception packet is coming,
* make sure the previous instruction
* range packet to be handled properly.
*/
cs_etm__exception(etmq);
break;
case CS_ETM_DISCONTINUITY:
/*
* Discontinuity in trace, flush
* previous branch stack
*/
cs_etm__flush(etmq);
break;
case CS_ETM_EMPTY:
/*
* Should not receive empty packet,
* report error.
*/
pr_err("CS ETM Trace: empty packet\n");
return -EINVAL;
default:
break;
}
}
return ret;
}
static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
{
int err = 0;
@ -1544,64 +1610,13 @@ static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
if (err)
return err;
/* Process each packet in this chunk */
while (1) {
err = cs_etm_decoder__get_packet(etmq->decoder,
etmq->packet);
if (err <= 0)
/*
* Stop processing this chunk on
* end of data or error
*/
break;
/*
* Process each packet in this chunk, nothing to do if
* an error occurs other than hoping the next one will
* be better.
*/
err = cs_etm__process_decoder_queue(etmq);
/*
* Since packet addresses are swapped in packet
* handling within below switch() statements,
* thus setting sample flags must be called
* prior to switch() statement to use address
* information before packets swapping.
*/
err = cs_etm__set_sample_flags(etmq);
if (err < 0)
break;
switch (etmq->packet->sample_type) {
case CS_ETM_RANGE:
/*
* If the packet contains an instruction
* range, generate instruction sequence
* events.
*/
cs_etm__sample(etmq);
break;
case CS_ETM_EXCEPTION:
case CS_ETM_EXCEPTION_RET:
/*
* If the exception packet is coming,
* make sure the previous instruction
* range packet to be handled properly.
*/
cs_etm__exception(etmq);
break;
case CS_ETM_DISCONTINUITY:
/*
* Discontinuity in trace, flush
* previous branch stack
*/
cs_etm__flush(etmq);
break;
case CS_ETM_EMPTY:
/*
* Should not receive empty packet,
* report error.
*/
pr_err("CS ETM Trace: empty packet\n");
return -EINVAL;
default:
break;
}
}
} while (etmq->buf_len);
if (err == 0)