[PATCH v4 03/12] rvtrace: Add functions to create/destroy a trace component path
Sergey Matyukevich
geomatsi at gmail.com
Fri May 22 12:55:19 PDT 2026
> Trace needs to be configured on a chain of trace components which are
> connected to each other. These chain of components is also referred
> to as trace component path. Add functions to create/destroy a trace
> component path which will be later used by RISC-V trace perf support.
>
> Co-developed-by: Mayuresh Chitale <mayuresh.chitale at oss.qualcomm.com>
> Signed-off-by: Mayuresh Chitale <mayuresh.chitale at oss.qualcomm.com>
> Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
> ---
> drivers/hwtracing/rvtrace/rvtrace-core.c | 223 +++++++++++++++++++++++
> include/linux/rvtrace.h | 43 ++++-
> 2 files changed, 264 insertions(+), 2 deletions(-)
...
I have been playing with a bit more complicated rvtrace graph with one
source (encoder) and two sinks (ramsink and simple test atb bridge sink)
with the following encoder output ports:
: trace at c000000 {
: compatible = "qemu,trace-component", "riscv,trace-component";
: reg = <0xc000000 0x1000>;
: cpus = <&CPU0>;
:
: out-ports {
: port at 0 {
: reg = <0>;
: CPU0_ENCODER_RAMSINK_OUTPUT: endpoint {
: remote-endpoint = <&CPU0_RAMSINK_INPUT>;
: };
: };
: port at 1 {
: reg = <1>;
: CPU0_ENCODER_TEST_OUTPUT: endpoint {
: remote-endpoint = <&CPU0_TEST_INPUT>;
: };
: };
: };
: };
In this case the first output port is enabled, but the second one is
not.
> +static int build_path_walk_fn(struct rvtrace_component *comp, bool *stop,
> + struct rvtrace_connection *stop_conn,
> + void *priv)
> +{
> + struct build_path_walk_priv *ppriv = priv;
> + struct rvtrace_path *path = ppriv->path;
> + struct rvtrace_path_node *node;
> +
> + if ((!ppriv->sink && rvtrace_is_sink(comp->pdata)) ||
> + (ppriv->sink && ppriv->sink == comp))
> + *stop = true;
> +
IIUC the root cause is that rvtrace_create_path from rvtrace-perf.c,
where the second argument is NULL, selects the first reachable sink.
The function __rvtrace_walk_output_components() walks pdata->outconns[]
in order and stops at the first component where rvtrace_is_sink() is true.
In the example with two sinks we stop at ramsink. As a result, the second
sink is not added to the list and never enabled later on.
> + if (*stop) {
> + node = kzalloc_obj(*node);
> + if (!path)
> + return -ENOMEM;
> + INIT_LIST_HEAD(&node->head);
> + rvtrace_get_component(comp);
> + node->comp = comp;
> + node->conn = stop_conn;
> + list_add(&node->head, &path->comp_list);
> + }
> +
> + return 0;
> +}
Regards,
Sergey
More information about the linux-riscv
mailing list