From: Leo Yan <leo.yan@arm.com>
To: James Clark <james.clark@linaro.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>,
Mike Leach <mike.leach@arm.com>,
John Garry <john.g.garry@oracle.com>,
Will Deacon <will@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Mathieu Poirier <mathieu.poirier@linaro.org>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Suyash Mahar <smahar@meta.com>, Amir Ayupov <aaupov@fb.com>,
Leo Yan <leo.yan@linux.dev>,
linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>,
linux-doc@vger.kernel.org
Subject: Re: [PATCH v2 04/14] perf cs-etm: Use per-CPU queues for per-thread mode
Date: Wed, 26 Aug 2026 20:06:45 +0100 [thread overview]
Message-ID: <20260826190645.GL8904@e132581.arm.com> (raw)
In-Reply-To: <20260821-james-cs-unformatted-per-thread-fix-v2-4-00c4fd0701b4@linaro.org>
On Fri, Aug 21, 2026 at 10:49:02AM +0100, James Clark wrote:
> This fixes two problems, firstly per-thread mode didn't support multiple
> threads well or at all because we always use queue 0 and assumed it was
> for a single thread. However, Perf attaches to all child threads of one
> process or allows multiple threads to be specified on the commandline.
> This meant that trace before a context packet could use the wrong MMAP
> for decoding, and threads running concurrently wouldn't be interleaved
> properly.
If I connect this with patch 03, I understand "a context packet" here as
the trace synchronization with a timestamp, which is needed to correlate
with MMAP records.
What I don't quite understand is how switching to multiple queues fixes
the "trace before a context packet" case. Wouldn't decoding still need
to wait until the first timestamp/context information is available?
> The second problem is that we'd put all HW_IDs into queue 0, so if a
> thread runs on multiple CPUs then it would receive multiple HW_IDs and
> trigger the assert that unformatted trace should only have 1 decoder
> per-CPU:
>
> $ perf record --per-thread -e cs_etm//u -- taskset --cpu-list 0 \
> taskset --cpu-list 1 true
> $ perf script
>
> perf: util/cs-etm.c:3381: cs_etm__create_queue_decoders: Assertion `decoders == 1' failed.
Seems the commit log misses to explain how to fix issue.
> Fixes: 9182f04a85b2 ("perf cs-etm: Pass unformatted flag to decoder")
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
> tools/perf/util/cs-etm.c | 30 +++++++++++++++++++++++++-----
> 1 file changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index d423f1cb408f..ccf886efff95 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -295,9 +295,6 @@ static int cs_etm__insert_trace_id_node(struct cs_etm_queue *etmq,
>
> static struct cs_etm_queue *cs_etm__get_queue(struct cs_etm_auxtrace *etm, int cpu)
> {
> - if (etm->per_thread_decoding)
> - return etm->queues.queue_array[0].priv;
> -
> if (cpu < 0 || cpu >= (int)etm->queues.nr_queues)
> return NULL;
>
> @@ -1268,7 +1265,7 @@ static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm,
> queue->priv = etmq;
> etmq->etm = etm;
> etmq->queue_nr = queue_nr;
> - queue->cpu = queue_nr; /* Placeholder, may be reset to -1 in per-thread mode */
> + queue->cpu = queue_nr;
> etmq->offset = 0;
> etmq->sink_id = SINK_UNSET;
>
> @@ -2160,6 +2157,7 @@ static void cs_etm__flush_all_stack(struct cs_etm_queue *etmq)
> */
> static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
> {
> + struct cs_etm_auxtrace *etm = etmq->etm;
> int ret;
>
> /* The current block is not finished */
> @@ -2188,6 +2186,27 @@ static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
> */
> cs_etm__flush_all_stack(etmq);
>
> + /*
> + * Per-thread mode still uses a queue for each CPU, but that CPU can run
> + * different threads. When the TID from the AUX record on a CPU changes,
> + * re-initialize the thread using the AUX record/buffer fragment TID so
> + * we can start decoding even if the context ID packet was cropped or
> + * they're disabled.
> + */
> + if (etm->per_thread_decoding) {
> + struct cs_etm_traceid_queue *tidq = cs_etm__etmq_get_traceid_queue(etmq,
> + CS_ETM_PER_THREAD_TRACEID);
> +
> + if (thread__tid(tidq->decode_thread) != etmq->buffer->tid) {
> + thread__zput(tidq->frontend_thread);
> + thread__zput(tidq->decode_thread);
> + tidq->frontend_thread = machine__findnew_thread(&etm->session->machines.host,
> + -1, etmq->buffer->tid);
> + tidq->decode_thread = machine__findnew_thread(&etm->session->machines.host,
> + -1, etmq->buffer->tid);
> + }
> + }
This works if the auxtrace fragment initially represents trace from that
TID. However, doesn't this introduce an assumption that an AUX fragment
contains trace from only one thread?
It seems this assumption impacts the kernel patch [1], the tool's
implementatoin imposes the limitation that driver to cannot support
multiple threads run concurrently with shared sink.
Would it be better to enable contextidr for per-thread mode and rely on
Context ID packets to update the thread context? We could then reuse
cs_etm__etmq_update_thread() / cs_etm__etmq_update_decode_context()
rather than relying on the AUX fragment TID for this purpose.
[1] https://lore.kernel.org/linux-arm-kernel/d833aeed-7376-48af-b772-4fe4ac66471d@linaro.org/
next prev parent reply other threads:[~2026-08-26 19:06 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-21 9:48 [PATCH v2 00/14] perf cs-etm: Per-thread mode fixes and snapshot wrap support James Clark
2026-08-21 9:48 ` [PATCH v2 01/14] perf cs-etm: Fix nVHE per-thread decoding James Clark
2026-08-26 15:01 ` Leo Yan
2026-08-21 9:49 ` [PATCH v2 02/14] perf cs-etm: Warn for invalid timestamp option James Clark
2026-08-26 15:04 ` Leo Yan
2026-08-21 9:49 ` [PATCH v2 03/14] perf cs-etm: Turn on context packet timestamps in per-thread mode James Clark
2026-08-26 15:36 ` Leo Yan
2026-08-21 9:49 ` [PATCH v2 04/14] perf cs-etm: Use per-CPU queues for " James Clark
2026-08-26 19:06 ` Leo Yan [this message]
2026-08-21 9:49 ` [PATCH v2 05/14] perf cs-etm: Increase default timestamp generation period James Clark
2026-08-21 9:49 ` [PATCH v2 06/14] perf auxtrace: Turn Intel BTS snapshot search into a generic one James Clark
2026-08-21 9:49 ` [PATCH v2 07/14] perf arm-spe: Use generic snapshot search James Clark
2026-08-21 9:49 ` [PATCH v2 08/14] perf auxtrace: intel-pt: Use new snapshot_has_wrapped callback James Clark
2026-08-21 9:49 ` [PATCH v2 09/14] perf cs-etm: Queue partial AUX records James Clark
2026-08-21 9:49 ` [PATCH v2 10/14] perf cs-etm: Don't print missing buffers in snapshot mode James Clark
2026-08-21 9:49 ` [PATCH v2 11/14] perf auxtrace: cs-etm: Capture wrapped snapshots James Clark
2026-08-24 12:21 ` Adrian Hunter
2026-08-24 14:32 ` James Clark
2026-08-21 9:49 ` [PATCH v2 12/14] perf test: Allow infinite named_thread loops James Clark
2026-08-21 9:49 ` [PATCH v2 13/14] perf test: Add test for per-thread mode James Clark
2026-08-21 9:49 ` [PATCH v2 14/14] perf cs-etm: Test multiple per-thread threads 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=20260826190645.GL8904@e132581.arm.com \
--to=leo.yan@arm.com \
--cc=aaupov@fb.com \
--cc=acme@kernel.org \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=corbet@lwn.net \
--cc=coresight@lists.linaro.org \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=john.g.garry@oracle.com \
--cc=jolsa@kernel.org \
--cc=leo.yan@linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mathieu.poirier@linaro.org \
--cc=mike.leach@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=skhan@linuxfoundation.org \
--cc=smahar@meta.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox