All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leo Yan <leo.yan@linaro.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Mike Leach <mike.leach@linaro.org>,
	James Clark <james.clark@arm.com>,
	John Garry <john.g.garry@oracle.com>,
	Will Deacon <will@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Leo Yan <leo.yan@linaro.org>
Subject: [PATCH] perf cs-etm: Fix kernel timestamp handling
Date: Sun, 10 Sep 2023 17:24:13 +0800	[thread overview]
Message-ID: <20230910092413.53538-1-leo.yan@linaro.org> (raw)

The timestamp can originate from two sources: the kernel timestamp,
which is recorded in the event PERF_RECORD_AUX, and the Arm CoreSight
hardware trace data.  On some Arm platforms, CoreSight trace data fails
to support timestamp tracing.  This can be due to either a missed
connection between the timer counter and Arm CoreSight or the absence
of support for the virtual timestamp.  If Arm CoreSight fails to support
hardware timestamp tracing, we need to fall back on using the kernel
timestamp.

The current code can support both timestamp sources when synthesizing
samples. However, the decoding flow only relies on the hardware
timestamp.  If the hardware timestamp is zero, it becomes impossible to
decode the trace data.  Consequently, in this case, the commands below
won't output any samples:

    perf record -e cs_etm// --per-thread --timestamp -- ls
    perf script

To fix this issue, this patch unifies the method of resolving time:

1) It renames cs_etm__resolve_sample_time() to the more general name
   cs_etm__resolve_time();
2) It changes the function argument type from 'cs_etm_traceid_queue' to
   'cs_etm_packet_queue';
3) In the end, both the decoding flow and the assignment of timestamps
   to samples call cs_etm__resolve_time() to obtain timestamp.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 tools/perf/util/cs-etm.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 9729d006550d..fa88e731933d 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -400,6 +400,17 @@ void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
 	etmq->pending_timestamp_chan_id = trace_chan_id;
 }
 
+static u64 cs_etm__resolve_time(struct cs_etm_queue *etmq,
+				struct cs_etm_packet_queue *packet_queue)
+{
+	struct cs_etm_auxtrace *etm = etmq->etm;
+
+	if (!etm->timeless_decoding && etm->has_virtual_ts)
+		return packet_queue->cs_timestamp;
+	else
+		return etm->latest_kernel_timestamp;
+}
+
 static u64 cs_etm__etmq_get_timestamp(struct cs_etm_queue *etmq,
 				      u8 *trace_chan_id)
 {
@@ -419,8 +430,7 @@ static u64 cs_etm__etmq_get_timestamp(struct cs_etm_queue *etmq,
 	/* Acknowledge pending status */
 	etmq->pending_timestamp_chan_id = 0;
 
-	/* See function cs_etm_decoder__do_{hard|soft}_timestamp() */
-	return packet_queue->cs_timestamp;
+	return cs_etm__resolve_time(etmq, packet_queue);
 }
 
 static void cs_etm__clear_packet_queue(struct cs_etm_packet_queue *queue)
@@ -1434,18 +1444,6 @@ u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp)
 		return cs_timestamp;
 }
 
-static inline u64 cs_etm__resolve_sample_time(struct cs_etm_queue *etmq,
-					       struct cs_etm_traceid_queue *tidq)
-{
-	struct cs_etm_auxtrace *etm = etmq->etm;
-	struct cs_etm_packet_queue *packet_queue = &tidq->packet_queue;
-
-	if (!etm->timeless_decoding && etm->has_virtual_ts)
-		return packet_queue->cs_timestamp;
-	else
-		return etm->latest_kernel_timestamp;
-}
-
 static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
 					    struct cs_etm_traceid_queue *tidq,
 					    u64 addr, u64 period)
@@ -1454,13 +1452,14 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
 	struct cs_etm_auxtrace *etm = etmq->etm;
 	union perf_event *event = tidq->event_buf;
 	struct perf_sample sample = {.ip = 0,};
+	struct cs_etm_packet_queue *packet_queue = &tidq->packet_queue;
 
 	event->sample.header.type = PERF_RECORD_SAMPLE;
 	event->sample.header.misc = cs_etm__cpu_mode(etmq, addr, tidq->el);
 	event->sample.header.size = sizeof(struct perf_event_header);
 
 	/* Set time field based on etm auxtrace config. */
-	sample.time = cs_etm__resolve_sample_time(etmq, tidq);
+	sample.time = cs_etm__resolve_time(etmq, packet_queue);
 
 	sample.ip = addr;
 	sample.pid = thread__pid(tidq->thread);
@@ -1505,6 +1504,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
 	struct cs_etm_auxtrace *etm = etmq->etm;
 	struct perf_sample sample = {.ip = 0,};
 	union perf_event *event = tidq->event_buf;
+	struct cs_etm_packet_queue *packet_queue = &tidq->packet_queue;
 	struct dummy_branch_stack {
 		u64			nr;
 		u64			hw_idx;
@@ -1520,7 +1520,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
 	event->sample.header.size = sizeof(struct perf_event_header);
 
 	/* Set time field based on etm auxtrace config. */
-	sample.time = cs_etm__resolve_sample_time(etmq, tidq);
+	sample.time = cs_etm__resolve_time(etmq, packet_queue);
 
 	sample.ip = ip;
 	sample.pid = thread__pid(tidq->prev_packet_thread);
-- 
2.34.1


WARNING: multiple messages have this Message-ID (diff)
From: Leo Yan <leo.yan@linaro.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Mike Leach <mike.leach@linaro.org>,
	James Clark <james.clark@arm.com>,
	John Garry <john.g.garry@oracle.com>,
	Will Deacon <will@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Leo Yan <leo.yan@linaro.org>
Subject: [PATCH] perf cs-etm: Fix kernel timestamp handling
Date: Sun, 10 Sep 2023 17:24:13 +0800	[thread overview]
Message-ID: <20230910092413.53538-1-leo.yan@linaro.org> (raw)

The timestamp can originate from two sources: the kernel timestamp,
which is recorded in the event PERF_RECORD_AUX, and the Arm CoreSight
hardware trace data.  On some Arm platforms, CoreSight trace data fails
to support timestamp tracing.  This can be due to either a missed
connection between the timer counter and Arm CoreSight or the absence
of support for the virtual timestamp.  If Arm CoreSight fails to support
hardware timestamp tracing, we need to fall back on using the kernel
timestamp.

The current code can support both timestamp sources when synthesizing
samples. However, the decoding flow only relies on the hardware
timestamp.  If the hardware timestamp is zero, it becomes impossible to
decode the trace data.  Consequently, in this case, the commands below
won't output any samples:

    perf record -e cs_etm// --per-thread --timestamp -- ls
    perf script

To fix this issue, this patch unifies the method of resolving time:

1) It renames cs_etm__resolve_sample_time() to the more general name
   cs_etm__resolve_time();
2) It changes the function argument type from 'cs_etm_traceid_queue' to
   'cs_etm_packet_queue';
3) In the end, both the decoding flow and the assignment of timestamps
   to samples call cs_etm__resolve_time() to obtain timestamp.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 tools/perf/util/cs-etm.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 9729d006550d..fa88e731933d 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -400,6 +400,17 @@ void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
 	etmq->pending_timestamp_chan_id = trace_chan_id;
 }
 
+static u64 cs_etm__resolve_time(struct cs_etm_queue *etmq,
+				struct cs_etm_packet_queue *packet_queue)
+{
+	struct cs_etm_auxtrace *etm = etmq->etm;
+
+	if (!etm->timeless_decoding && etm->has_virtual_ts)
+		return packet_queue->cs_timestamp;
+	else
+		return etm->latest_kernel_timestamp;
+}
+
 static u64 cs_etm__etmq_get_timestamp(struct cs_etm_queue *etmq,
 				      u8 *trace_chan_id)
 {
@@ -419,8 +430,7 @@ static u64 cs_etm__etmq_get_timestamp(struct cs_etm_queue *etmq,
 	/* Acknowledge pending status */
 	etmq->pending_timestamp_chan_id = 0;
 
-	/* See function cs_etm_decoder__do_{hard|soft}_timestamp() */
-	return packet_queue->cs_timestamp;
+	return cs_etm__resolve_time(etmq, packet_queue);
 }
 
 static void cs_etm__clear_packet_queue(struct cs_etm_packet_queue *queue)
@@ -1434,18 +1444,6 @@ u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp)
 		return cs_timestamp;
 }
 
-static inline u64 cs_etm__resolve_sample_time(struct cs_etm_queue *etmq,
-					       struct cs_etm_traceid_queue *tidq)
-{
-	struct cs_etm_auxtrace *etm = etmq->etm;
-	struct cs_etm_packet_queue *packet_queue = &tidq->packet_queue;
-
-	if (!etm->timeless_decoding && etm->has_virtual_ts)
-		return packet_queue->cs_timestamp;
-	else
-		return etm->latest_kernel_timestamp;
-}
-
 static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
 					    struct cs_etm_traceid_queue *tidq,
 					    u64 addr, u64 period)
@@ -1454,13 +1452,14 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
 	struct cs_etm_auxtrace *etm = etmq->etm;
 	union perf_event *event = tidq->event_buf;
 	struct perf_sample sample = {.ip = 0,};
+	struct cs_etm_packet_queue *packet_queue = &tidq->packet_queue;
 
 	event->sample.header.type = PERF_RECORD_SAMPLE;
 	event->sample.header.misc = cs_etm__cpu_mode(etmq, addr, tidq->el);
 	event->sample.header.size = sizeof(struct perf_event_header);
 
 	/* Set time field based on etm auxtrace config. */
-	sample.time = cs_etm__resolve_sample_time(etmq, tidq);
+	sample.time = cs_etm__resolve_time(etmq, packet_queue);
 
 	sample.ip = addr;
 	sample.pid = thread__pid(tidq->thread);
@@ -1505,6 +1504,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
 	struct cs_etm_auxtrace *etm = etmq->etm;
 	struct perf_sample sample = {.ip = 0,};
 	union perf_event *event = tidq->event_buf;
+	struct cs_etm_packet_queue *packet_queue = &tidq->packet_queue;
 	struct dummy_branch_stack {
 		u64			nr;
 		u64			hw_idx;
@@ -1520,7 +1520,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
 	event->sample.header.size = sizeof(struct perf_event_header);
 
 	/* Set time field based on etm auxtrace config. */
-	sample.time = cs_etm__resolve_sample_time(etmq, tidq);
+	sample.time = cs_etm__resolve_time(etmq, packet_queue);
 
 	sample.ip = ip;
 	sample.pid = thread__pid(tidq->prev_packet_thread);
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2023-09-10  9:24 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-10  9:24 Leo Yan [this message]
2023-09-10  9:24 ` [PATCH] perf cs-etm: Fix kernel timestamp handling Leo Yan
2023-09-11 13:24 ` James Clark
2023-09-11 13:24   ` James Clark
2023-09-12  1:52   ` Leo Yan
2023-09-12  1:52     ` Leo Yan
2023-09-12 10:57     ` James Clark
2023-09-12 10:57       ` James Clark

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230910092413.53538-1-leo.yan@linaro.org \
    --to=leo.yan@linaro.org \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=coresight@lists.linaro.org \
    --cc=irogers@google.com \
    --cc=james.clark@arm.com \
    --cc=john.g.garry@oracle.com \
    --cc=jolsa@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mike.leach@linaro.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.