Re: [PATCH v14 2/7] coresight: tmc: add create/clean functions for etr_buf_list

From: Jie Gan

Date: Mon Mar 09 2026 - 06:28:23 EST




On 3/9/2026 6:02 PM, Suzuki K Poulose wrote:
On 09/03/2026 09:47, Jie Gan wrote:
Introduce functions for creating and inserting or removing the
etr_buf_node to/from the etr_buf_list.

The byte-cntr functionality requires two etr_buf to receive trace data.
The active etr_buf collects the trace data from source device, while the
byte-cntr reading function accesses the deactivated etr_buf after is
has been filled and synced, transferring data to the userspace.

Reviewed-by: Mike Leach <mike.leach@xxxxxxxxxx>
Signed-off-by: Jie Gan <jie.gan@xxxxxxxxxxxxxxxx>
---
  drivers/hwtracing/coresight/coresight-tmc-core.c |  1 +
  drivers/hwtracing/coresight/coresight-tmc-etr.c  | 94 ++++++++++++++ ++++++++++
  drivers/hwtracing/coresight/coresight-tmc.h      | 17 +++++
  3 files changed, 112 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/ drivers/hwtracing/coresight/coresight-tmc-core.c
index c89fe996af23..bac3278ef4dd 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -835,6 +835,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
          idr_init(&drvdata->idr);
          mutex_init(&drvdata->idr_mutex);
          dev_list = "tmc_etr";
+        INIT_LIST_HEAD(&drvdata->etr_buf_list);
          break;
      case TMC_CONFIG_TYPE_ETF:
          desc.groups = coresight_etf_groups;
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/ drivers/hwtracing/coresight/coresight-tmc-etr.c
index 4dc1defe27a5..15c0874ff641 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1918,6 +1918,100 @@ const struct coresight_ops tmc_etr_cs_ops = {
      .panic_ops    = &tmc_etr_sync_ops,
  };
+/**
+ * tmc_clean_etr_buf_list - clean the etr_buf_list.
+ * @drvdata:    driver data of the TMC device.
+ *
+ * Remove the allocated node from the list and free the extra buffer.
+ */
+void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata)
+{
...

+}
+EXPORT_SYMBOL_GPL(tmc_clean_etr_buf_list);
+
+/**
+ * tmc_create_etr_buf_list - create a list to manage the etr_buf_node.
+ * @drvdata:    driver data of the TMC device.
+ * @num_nodes:    number of nodes want to create with the list.
+ *
+ * Return 0 upon success and return the error number if fail.
+ */
+int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes)
+{

...


+EXPORT_SYMBOL_GPL(tmc_create_etr_buf_list);

Given the above functions are "EXPORTED" please could you make sure that
the locking requirements are documented and asserted (lockdep_assert)
in the functions ?


Will checking the locking scenario here and asserted with lockdep_assert_held.

These two functions should be protected with tmc_drvdata->spinlock.

Thanks,
Jie


Suzuki


+
  int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
  {
      int ret = 0;
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/ hwtracing/coresight/coresight-tmc.h
index 319a354ede9f..5ac07e8dd5ff 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -208,6 +208,19 @@ struct tmc_resrv_buf {
      s64        len;
  };
+/**
+ * @sysfs_buf:    Allocated sysfs_buf.
+ * @is_free:    Indicates whether the buffer is free to choose.
+ * @pos:    Position of the buffer.
+ * @node:    Node in etr_buf_list.
+ */
+struct etr_buf_node {
+    struct etr_buf        *sysfs_buf;
+    bool            is_free;
+    loff_t            pos;
+    struct list_head    node;
+};
+
  /**
   * struct tmc_drvdata - specifics associated to an TMC component
   * @atclk:    optional clock for the core parts of the TMC.
@@ -245,6 +258,7 @@ struct tmc_resrv_buf {
   *        (after crash) by default.
   * @crash_mdata: Reserved memory for storing tmc crash metadata.
   *         Used by ETR/ETF.
+ * @etr_buf_list: List that is used to manage allocated etr_buf.
   */
  struct tmc_drvdata {
      struct clk        *atclk;
@@ -275,6 +289,7 @@ struct tmc_drvdata {
      struct etr_buf        *perf_buf;
      struct tmc_resrv_buf    resrv_buf;
      struct tmc_resrv_buf    crash_mdata;
+    struct list_head        etr_buf_list;
  };
  struct etr_buf_operations {
@@ -447,5 +462,7 @@ struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
                     enum cs_mode mode,
                     struct coresight_path *path);
  extern const struct attribute_group coresight_etr_group;
+void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata);
+int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes);
  #endif