The ETR sink needs to know if it is shared between sources in order to adequately allocate memory for CPU-wide trace sessions. If operating in an N:1 source/sink topology and the sink is shared, double buffering mode needs to be used in order to manage concurrency.
Since function etm_setup_aux() already has a handle on the path for the session, simply make it available to the ETR so that it can decide how memory is allocated.
This patch is introducing no change in behavior.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/hwtracing/coresight/coresight-etb10.c | 2 +- drivers/hwtracing/coresight/coresight-etm-perf.c | 9 ++++++--- drivers/hwtracing/coresight/coresight-tmc-etf.c | 2 +- drivers/hwtracing/coresight/coresight-tmc-etr.c | 11 +++++++++-- include/linux/coresight.h | 2 +- 5 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index cb16191ba3fd..660a146f2ea2 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -381,7 +381,7 @@ static int etb_disable(struct coresight_device *csdev) return 0; }
-static void *etb_alloc_buffer(struct coresight_device *csdev, int cpu, +static void *etb_alloc_buffer(struct list_head *path, int cpu, pid_t pid, void **pages, int nr_pages, bool overwrite) { diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 76d3e8f1041c..8013b09597b9 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -214,6 +214,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, pid_t pid = task_pid_nr(event->owner); struct coresight_device *sink; struct etm_event_data *event_data = NULL; + struct list_head *path = NULL;
event_data = alloc_event_data(cpu); if (!event_data) @@ -241,7 +242,6 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, * CPUs, we can handle it and fail the session. */ for_each_cpu(cpu, mask) { - struct list_head *path; struct coresight_device *csdev;
csdev = per_cpu(csdev_src, cpu); @@ -277,9 +277,12 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, if (!sink_ops(sink)->alloc_buffer || !sink_ops(sink)->free_buffer) goto err;
- /* Allocate the sink buffer for this session */ + /* + * Allocate the sink buffer for this session. In per-thread mode + * any path from source to sink will do. + */ event_data->snk_config = - sink_ops(sink)->alloc_buffer(sink, cpu, pid, pages, + sink_ops(sink)->alloc_buffer(path, cpu, pid, pages, nr_pages, overwrite); if (!event_data->snk_config) goto err; diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 33055e2c3017..c88073044da2 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -376,7 +376,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, dev_dbg(drvdata->dev, "TMC-ETF disabled\n"); }
-static void *tmc_alloc_etf_buffer(struct coresight_device *csdev, +static void *tmc_alloc_etf_buffer(struct list_head *path, int cpu, pid_t pid, void **pages, int nr_pages, bool overwrite) { diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index dc74c95413dc..d8c71d22bdef 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1277,12 +1277,19 @@ tmc_etr_setup_perf_buf(struct tmc_drvdata *drvdata, int node, pid_t pid, }
-static void *tmc_alloc_etr_buffer(struct coresight_device *csdev, int cpu, +static void *tmc_alloc_etr_buffer(struct list_head *path, int cpu, pid_t pid, void **pages, int nr_pages, bool snapshot) { struct etr_perf_buffer *etr_perf; - struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + struct coresight_device *csdev; + struct tmc_drvdata *drvdata; + + csdev = coresight_get_sink(path); + if (!csdev) + return NULL; + + drvdata = dev_get_drvdata(csdev->dev.parent);
if (cpu == -1) cpu = smp_processor_id(); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 21c53cc21f4b..26e6cd042339 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -194,7 +194,7 @@ struct coresight_device { struct coresight_ops_sink { int (*enable)(struct coresight_device *csdev, u32 mode, void *data); int (*disable)(struct coresight_device *csdev); - void *(*alloc_buffer)(struct coresight_device *csdev, int cpu, + void *(*alloc_buffer)(struct list_head *path, int cpu, pid_t pid, void **pages, int nr_pages, bool overwrite); void (*free_buffer)(void *config);