[PATCH v2 07/14] perf cs-etm: Factor out final instruction sample synthesis
Leo Yan
leo.yan at arm.com
Wed Sep 23 08:21:47 PDT 2026
cs_etm__flush() and cs_etm__end_block() duplicate the instruction sample
used to report the remaining branch history at the end of a trace.
Move this code into cs_etm__synth_last_instruction_sample(), preserving
the sample generation and instruction period reset.
Assisted-by: Codex:gpt-6
Signed-off-by: Leo Yan <leo.yan at arm.com>
---
tools/perf/util/cs-etm.c | 71 ++++++++++++++++++------------------------------
1 file changed, 26 insertions(+), 45 deletions(-)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index c54218aeef53e8420447e9a2bee6e98d8225e335..5b5ee52c0277f5ff8f03c2908e4af1d7801845ff 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -1685,6 +1685,28 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
return ret;
}
+static int cs_etm__synth_last_instruction_sample(struct cs_etm_queue *etmq,
+ struct cs_etm_traceid_queue *tidq)
+{
+ struct cs_etm_packet *packet = tidq->prev_packet;
+ int ret;
+
+ if (!etmq->etm->synth_opts.last_branch ||
+ !etmq->etm->synth_opts.instructions)
+ return 0;
+
+ if (packet->sample_type != CS_ETM_RANGE)
+ return 0;
+
+ ret = cs_etm__synth_instruction_sample(etmq, tidq, packet,
+ cs_etm__last_executed_instr(packet),
+ tidq->period_instructions);
+ if (!ret)
+ tidq->period_instructions = 0;
+
+ return ret;
+}
+
/*
* The cs etm packet encodes an instruction range between a branch target
* and the next taken branch. Generate sample accordingly.
@@ -2023,28 +2045,9 @@ static int cs_etm__flush(struct cs_etm_queue *etmq,
if (tidq->prev_packet->sample_type == CS_ETM_EMPTY)
goto swap_packet;
- if (etmq->etm->synth_opts.last_branch &&
- etmq->etm->synth_opts.instructions &&
- tidq->prev_packet->sample_type == CS_ETM_RANGE) {
- u64 addr;
- /*
- * Generate a last branch event for the branches left in the
- * circular buffer at the end of the trace.
- *
- * Use the address of the end of the last reported execution
- * range
- */
- addr = cs_etm__last_executed_instr(tidq->prev_packet);
-
- err = cs_etm__synth_instruction_sample(
- etmq, tidq, tidq->prev_packet, addr,
- tidq->period_instructions);
- if (err)
- return err;
-
- tidq->period_instructions = 0;
-
- }
+ err = cs_etm__synth_last_instruction_sample(etmq, tidq);
+ if (err)
+ return err;
if (etm->synth_opts.branches &&
tidq->prev_packet->sample_type == CS_ETM_RANGE) {
@@ -2066,8 +2069,6 @@ static int cs_etm__flush(struct cs_etm_queue *etmq,
static int cs_etm__end_block(struct cs_etm_queue *etmq,
struct cs_etm_traceid_queue *tidq)
{
- int err;
-
/*
* It has no new packet coming and 'etmq->packet' contains the stale
* packet which was set at the previous time with packets swapping;
@@ -2077,27 +2078,7 @@ static int cs_etm__end_block(struct cs_etm_queue *etmq,
* event for the branches left in the circular buffer at the end of
* the trace.
*/
- if (etmq->etm->synth_opts.last_branch &&
- etmq->etm->synth_opts.instructions &&
- tidq->prev_packet->sample_type == CS_ETM_RANGE) {
- u64 addr;
-
- /*
- * Use the address of the end of the last reported execution
- * range.
- */
- addr = cs_etm__last_executed_instr(tidq->prev_packet);
-
- err = cs_etm__synth_instruction_sample(
- etmq, tidq, tidq->prev_packet, addr,
- tidq->period_instructions);
- if (err)
- return err;
-
- tidq->period_instructions = 0;
- }
-
- return 0;
+ return cs_etm__synth_last_instruction_sample(etmq, tidq);
}
static int cs_etm__flush_stack_cb(struct thread *thread,
--
2.34.1
More information about the linux-arm-kernel
mailing list