summaryrefslogtreecommitdiff
path: root/tools/perf/util/cs-etm.c
diff options
context:
space:
mode:
authorLeo Yan <leo.yan@linaro.org>2018-12-11 15:38:28 +0800
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-12-18 12:24:00 -0300
commit7100b12cf474f575658e6e4a834f0e8a0b3c9867 (patch)
tree5d5f4fa91f843890c724ff49836673b8db189da0 /tools/perf/util/cs-etm.c
parent02e7e2509e939b50f4f1b14c08b97f60256df3ea (diff)
perf cs-etm: Generate branch sample for exception packet
The exception packet appears as one element with 'elem_type' == OCSD_GEN_TRC_ELEM_EXCEPTION or OCSD_GEN_TRC_ELEM_EXCEPTION_RET, which is present for exception entry and exit respectively. The decoder sets the packet fields 'packet->exc' and 'packet->exc_ret' to indicate the exception packets; but exception packets don't have a dedicated sample type and shares the same sample type CS_ETM_RANGE with normal instruction packets. As a result, the exception packets are taken as normal instruction packets and this introduces confusion in mixing different packet types. Furthermore, these instruction range packets will be processed for branch samples only when 'packet->last_instr_taken_branch' is true, otherwise they will be omitted, this can introduce a mess for exception and exception returning due to not having the complete address range info for context switching. To process exception packets properly, this patch introduces two new sample types: CS_ETM_EXCEPTION and CS_ETM_EXCEPTION_RET; these two types of packets will be handled by cs_etm__exception(). The function cs_etm__exception() forces setting the previous CS_ETM_RANGE packet flag 'prev_packet->last_instr_taken_branch' to true, this matches well with the program flow when the exception is trapped from user space to kernel space, no matter if the most recent flow has branch taken or not; this is also safe for returning to user space after exception handling. After exception packets have their own sample type, the packet fields 'packet->exc' and 'packet->exc_ret' aren't needed anymore, so remove them. Signed-off-by: Leo Yan <leo.yan@linaro.org> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Leach <mike.leach@linaro.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Robert Walker <robert.walker@arm.com> Cc: coresight ml <coresight@lists.linaro.org> Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1544513908-16805-9-git-send-email-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/cs-etm.c')
-rw-r--r--tools/perf/util/cs-etm.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index cea3158915d3..27a374ddf661 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -1000,6 +1000,25 @@ static int cs_etm__sample(struct cs_etm_queue *etmq)
return 0;
}
+static int cs_etm__exception(struct cs_etm_queue *etmq)
+{
+ /*
+ * When the exception packet is inserted, whether the last instruction
+ * in previous range packet is taken branch or not, we need to force
+ * to set 'prev_packet->last_instr_taken_branch' to true. This ensures
+ * to generate branch sample for the instruction range before the
+ * exception is trapped to kernel or before the exception returning.
+ *
+ * The exception packet includes the dummy address values, so don't
+ * swap PACKET with PREV_PACKET. This keeps PREV_PACKET to be useful
+ * for generating instruction and branch samples.
+ */
+ if (etmq->prev_packet->sample_type == CS_ETM_RANGE)
+ etmq->prev_packet->last_instr_taken_branch = true;
+
+ return 0;
+}
+
static int cs_etm__flush(struct cs_etm_queue *etmq)
{
int err = 0;
@@ -1148,6 +1167,15 @@ static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
*/
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