[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