From: Mathieu Poirier <mathieu.poirier@linaro.org>
To: acme@kernel.org
Cc: peterz@infradead.org, mingo@redhat.com,
alexander.shishkin@linux.intel.com, jolsa@redhat.com,
namhyung@kernel.org, suzuki.poulose@arm.com, leo.yan@linaro.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org
Subject: [PATCH v2 14/17] perf tools: Add support for multiple traceID queues
Date: Fri, 24 May 2019 11:35:05 -0600 [thread overview]
Message-ID: <20190524173508.29044-15-mathieu.poirier@linaro.org> (raw)
In-Reply-To: <20190524173508.29044-1-mathieu.poirier@linaro.org>
When operating in CPU-wide trace mode with a source/sink topology of N:1
packets with multiple traceID will end up in the same cs_etm_queue. In
order to properly decode packets they need to be split in different
queues, i.e one queue per traceID.
As such add support for multiple traceID per cs_etm_queue by adding
a new cs_etm_traceid_queue every time a new traceID is discovered
in the trace stream.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
tools/perf/Makefile.config | 3 +
tools/perf/util/cs-etm.c | 131 ++++++++++++++++++++++++++++++-------
2 files changed, 110 insertions(+), 24 deletions(-)
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index e1bb5288ab1f..feb2d1b85087 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -412,6 +412,9 @@ ifdef CORESIGHT
$(call feature_check,libopencsd)
ifeq ($(feature-libopencsd), 1)
CFLAGS += -DHAVE_CSTRACE_SUPPORT $(LIBOPENCSD_CFLAGS)
+ ifeq ($(feature-reallocarray), 0)
+ CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
+ endif
LDFLAGS += $(LIBOPENCSD_LDFLAGS)
EXTLIBS += $(OPENCSDLIBS)
$(call detected,CONFIG_LIBOPENCSD)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 2483293266d8..afc2491f9f2a 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -29,6 +29,7 @@
#include "thread.h"
#include "thread_map.h"
#include "thread-stack.h"
+#include <tools/libc_compat.h>
#include "util.h"
#define MAX_TIMESTAMP (~0ULL)
@@ -82,7 +83,9 @@ struct cs_etm_queue {
u64 offset;
const unsigned char *buf;
size_t buf_len, buf_used;
- struct cs_etm_traceid_queue *traceid_queues;
+ /* Conversion between traceID and index in traceid_queues array */
+ struct intlist *traceid_queues_list;
+ struct cs_etm_traceid_queue **traceid_queues;
};
static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);
@@ -208,31 +211,71 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
static struct cs_etm_traceid_queue
*cs_etm__etmq_get_traceid_queue(struct cs_etm_queue *etmq, u8 trace_chan_id)
{
- struct cs_etm_traceid_queue *tidq;
+ int idx;
+ struct int_node *inode;
+ struct intlist *traceid_queues_list;
+ struct cs_etm_traceid_queue *tidq, **traceid_queues;
struct cs_etm_auxtrace *etm = etmq->etm;
- if (!etm->timeless_decoding)
- return NULL;
+ if (etm->timeless_decoding)
+ trace_chan_id = CS_ETM_PER_THREAD_TRACEID;
- tidq = etmq->traceid_queues;
+ traceid_queues_list = etmq->traceid_queues_list;
- if (tidq)
- return tidq;
+ /*
+ * Check if the traceid_queue exist for this traceID by looking
+ * in the queue list.
+ */
+ inode = intlist__find(traceid_queues_list, trace_chan_id);
+ if (inode) {
+ idx = (int)(intptr_t)inode->priv;
+ return etmq->traceid_queues[idx];
+ }
+ /* We couldn't find a traceid_queue for this traceID, allocate one */
tidq = malloc(sizeof(*tidq));
if (!tidq)
return NULL;
memset(tidq, 0, sizeof(*tidq));
+ /* Get a valid index for the new traceid_queue */
+ idx = intlist__nr_entries(traceid_queues_list);
+ /* Memory for the inode is free'ed in cs_etm_free_traceid_queues () */
+ inode = intlist__findnew(traceid_queues_list, trace_chan_id);
+ if (!inode)
+ goto out_free;
+
+ /* Associate this traceID with this index */
+ inode->priv = (void *)(intptr_t)idx;
+
if (cs_etm__init_traceid_queue(etmq, tidq, trace_chan_id))
goto out_free;
- etmq->traceid_queues = tidq;
+ /* Grow the traceid_queues array by one unit */
+ traceid_queues = etmq->traceid_queues;
+ traceid_queues = reallocarray(traceid_queues,
+ idx + 1,
+ sizeof(*traceid_queues));
+
+ /*
+ * On failure reallocarray() returns NULL and the original block of
+ * memory is left untouched.
+ */
+ if (!traceid_queues)
+ goto out_free;
+
+ traceid_queues[idx] = tidq;
+ etmq->traceid_queues = traceid_queues;
- return etmq->traceid_queues;
+ return etmq->traceid_queues[idx];
out_free:
+ /*
+ * Function intlist__remove() removes the inode from the list
+ * and delete the memory associated to it.
+ */
+ intlist__remove(traceid_queues_list, inode);
free(tidq);
return NULL;
@@ -412,6 +455,44 @@ static int cs_etm__flush_events(struct perf_session *session,
return cs_etm__process_timeless_queues(etm, -1);
}
+static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
+{
+ int idx;
+ uintptr_t priv;
+ struct int_node *inode, *tmp;
+ struct cs_etm_traceid_queue *tidq;
+ struct intlist *traceid_queues_list = etmq->traceid_queues_list;
+
+ intlist__for_each_entry_safe(inode, tmp, traceid_queues_list) {
+ priv = (uintptr_t)inode->priv;
+ idx = priv;
+
+ /* Free this traceid_queue from the array */
+ tidq = etmq->traceid_queues[idx];
+ thread__zput(tidq->thread);
+ zfree(&tidq->event_buf);
+ zfree(&tidq->last_branch);
+ zfree(&tidq->last_branch_rb);
+ zfree(&tidq->prev_packet);
+ zfree(&tidq->packet);
+ zfree(&tidq);
+
+ /*
+ * Function intlist__remove() removes the inode from the list
+ * and delete the memory associated to it.
+ */
+ intlist__remove(traceid_queues_list, inode);
+ }
+
+ /* Then the RB tree itself */
+ intlist__delete(traceid_queues_list);
+ etmq->traceid_queues_list = NULL;
+
+ /* finally free the traceid_queues array */
+ free(etmq->traceid_queues);
+ etmq->traceid_queues = NULL;
+}
+
static void cs_etm__free_queue(void *priv)
{
struct cs_etm_queue *etmq = priv;
@@ -419,14 +500,8 @@ static void cs_etm__free_queue(void *priv)
if (!etmq)
return;
- thread__zput(etmq->traceid_queues->thread);
cs_etm_decoder__free(etmq->decoder);
- zfree(&etmq->traceid_queues->event_buf);
- zfree(&etmq->traceid_queues->last_branch);
- zfree(&etmq->traceid_queues->last_branch_rb);
- zfree(&etmq->traceid_queues->prev_packet);
- zfree(&etmq->traceid_queues->packet);
- zfree(&etmq->traceid_queues);
+ cs_etm__free_traceid_queues(etmq);
free(etmq);
}
@@ -497,19 +572,21 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
u8 cpumode;
u64 offset;
int len;
- struct thread *thread;
- struct machine *machine;
- struct addr_location al;
-
- (void)trace_chan_id;
+ struct thread *thread;
+ struct machine *machine;
+ struct addr_location al;
+ struct cs_etm_traceid_queue *tidq;
if (!etmq)
return 0;
machine = etmq->etm->machine;
cpumode = cs_etm__cpu_mode(etmq, address);
+ tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
+ if (!tidq)
+ return 0;
- thread = etmq->traceid_queues->thread;
+ thread = tidq->thread;
if (!thread) {
if (cpumode != PERF_RECORD_MISC_KERNEL)
return 0;
@@ -545,6 +622,10 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm)
if (!etmq)
return NULL;
+ etmq->traceid_queues_list = intlist__new(NULL);
+ if (!etmq->traceid_queues_list)
+ goto out_free;
+
/* Use metadata to fill in trace parameters for trace decoder */
t_params = zalloc(sizeof(*t_params) * etm->num_cpu);
@@ -579,6 +660,7 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm)
out_free_decoder:
cs_etm_decoder__free(etmq->decoder);
out_free:
+ intlist__delete(etmq->traceid_queues_list);
free(etmq);
return NULL;
@@ -1280,8 +1362,9 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
struct cs_etm_packet *packet,
u64 end_addr)
{
- u16 instr16;
- u32 instr32;
+ /* Initialise to keep compiler happy */
+ u16 instr16 = 0;
+ u32 instr32 = 0;
u64 addr;
switch (packet->isa) {
--
2.17.1
next prev parent reply other threads:[~2019-05-24 17:35 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-24 17:34 [PATCH v2 00/17] perf tools: Coresight: Add CPU-wide trace support Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 01/17] perf tools: Configure contextID tracing in CPU-wide mode Mathieu Poirier
2019-06-07 9:21 ` Suzuki K Poulose
2019-06-07 17:40 ` Mathieu Poirier
2019-06-07 18:20 ` Arnaldo Carvalho de Melo
2019-06-07 19:33 ` Mathieu Poirier
2019-06-17 19:36 ` [tip:perf/core] perf cs-etm: Remove duplicate GENMASK() define, use linux/bits.h instead tip-bot for Arnaldo Carvalho de Melo
2019-06-17 19:20 ` [tip:perf/core] perf cs-etm: Configure contextID tracing in CPU-wide mode tip-bot for Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 02/17] perf tools: Configure timestsamp generation " Mathieu Poirier
2019-06-07 9:41 ` Suzuki K Poulose
2019-06-07 17:46 ` Mathieu Poirier
2019-06-07 18:34 ` Arnaldo Carvalho de Melo
2019-06-17 19:20 ` [tip:perf/core] perf cs-etm: Configure timestamp " tip-bot for Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 03/17] perf tools: Configure SWITCH_EVENTS " Mathieu Poirier
2019-06-17 19:21 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 04/17] perf tools: Add handling of itrace start events Mathieu Poirier
2019-06-17 19:22 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 05/17] perf tools: Add handling of switch-CPU-wide events Mathieu Poirier
2019-06-17 19:22 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 06/17] perf tools: Refactor error path in cs_etm_decoder__new() Mathieu Poirier
2019-06-17 19:23 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 07/17] perf tools: Move packet queue out of decoder structure Mathieu Poirier
2019-06-17 19:24 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:34 ` [PATCH v2 08/17] perf tools: Fix indentation in function cs_etm__process_decoder_queue() Mathieu Poirier
2019-06-17 19:25 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 09/17] perf tools: Introduce the concept of trace ID queues Mathieu Poirier
2019-06-17 19:25 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 10/17] perf tools: Get rid of unused cpu in struct cs_etm_queue Mathieu Poirier
2019-06-17 19:26 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 11/17] perf tools: Move thread to traceid_queue Mathieu Poirier
2019-06-17 19:27 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 12/17] perf tools: Move tid/pid " Mathieu Poirier
2019-06-17 19:27 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 13/17] perf tools: Use traceID aware memory callback API Mathieu Poirier
2019-06-17 19:28 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` Mathieu Poirier [this message]
2019-06-17 19:29 ` [tip:perf/core] perf cs-etm: Add support for multiple traceID queues tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 15/17] perf tools: Linking PE contextID with perf thread mechanic Mathieu Poirier
2019-06-17 19:29 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 16/17] perf tools: Add notion of time to decoding code Mathieu Poirier
2019-06-06 18:50 ` Arnaldo Carvalho de Melo
2019-06-07 14:38 ` Mathieu Poirier
2019-06-17 19:30 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-24 17:35 ` [PATCH v2 17/17] perf tools: Add support for CPU-wide trace scenarios Mathieu Poirier
2019-06-17 19:31 ` [tip:perf/core] perf cs-etm: " tip-bot for Mathieu Poirier
2019-05-31 1:45 ` [PATCH v2 00/17] perf tools: Coresight: Add CPU-wide trace support Leo Yan
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=20190524173508.29044-15-mathieu.poirier@linaro.org \
--to=mathieu.poirier@linaro.org \
--cc=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=coresight@lists.linaro.org \
--cc=jolsa@redhat.com \
--cc=leo.yan@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=suzuki.poulose@arm.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).