aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing
diff options
context:
space:
mode:
authorSuzuki K Poulose <suzuki.poulose@arm.com>2018-09-20 15:17:56 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-25 14:09:18 -0400
commit3d6e8935758392179645e1b105789b3da329ad38 (patch)
tree185757d4c134f327f7cf817e74b9573e664ecfba /drivers/hwtracing
parentd25054ee8d18c937058a1b69b35fa5bfdef471f3 (diff)
coresight: perf: Remove set_buffer call back
In coresight perf mode, we need to prepare the sink before starting a session, which is done via set_buffer call back. We then proceed to enable the tracing. If we fail to start the session successfully, we leave the sink configuration unchanged. In order to make the operation atomic and to avoid yet another call back to clear the buffer, we get rid of the "set_buffer" call back and pass the buffer details via enable() call back to the sink. Cc: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r--drivers/hwtracing/coresight/coresight-etb10.c32
-rw-r--r--drivers/hwtracing/coresight/coresight-etm-perf.c9
-rw-r--r--drivers/hwtracing/coresight/coresight-priv.h2
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etf.c28
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etr.c7
-rw-r--r--drivers/hwtracing/coresight/coresight-tpiu.c2
-rw-r--r--drivers/hwtracing/coresight/coresight.c11
7 files changed, 58 insertions, 33 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index dba75c905e57..9fd77fdc1244 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -28,6 +28,7 @@
28 28
29 29
30#include "coresight-priv.h" 30#include "coresight-priv.h"
31#include "coresight-etm-perf.h"
31 32
32#define ETB_RAM_DEPTH_REG 0x004 33#define ETB_RAM_DEPTH_REG 0x004
33#define ETB_STATUS_REG 0x00c 34#define ETB_STATUS_REG 0x00c
@@ -90,6 +91,9 @@ struct etb_drvdata {
90 u32 trigger_cntr; 91 u32 trigger_cntr;
91}; 92};
92 93
94static int etb_set_buffer(struct coresight_device *csdev,
95 struct perf_output_handle *handle);
96
93static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata) 97static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata)
94{ 98{
95 u32 depth = 0; 99 u32 depth = 0;
@@ -131,12 +135,24 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
131 CS_LOCK(drvdata->base); 135 CS_LOCK(drvdata->base);
132} 136}
133 137
134static int etb_enable(struct coresight_device *csdev, u32 mode) 138static int etb_enable(struct coresight_device *csdev, u32 mode, void *data)
135{ 139{
140 int ret = 0;
136 u32 val; 141 u32 val;
137 unsigned long flags; 142 unsigned long flags;
138 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 143 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
139 144
145 /*
146 * We don't have an internal state to clean up if we fail to setup
147 * the perf buffer. So we can perform the step before we turn the
148 * ETB on and leave without cleaning up.
149 */
150 if (mode == CS_MODE_PERF) {
151 ret = etb_set_buffer(csdev, (struct perf_output_handle *)data);
152 if (ret)
153 goto out;
154 }
155
140 val = local_cmpxchg(&drvdata->mode, 156 val = local_cmpxchg(&drvdata->mode,
141 CS_MODE_DISABLED, mode); 157 CS_MODE_DISABLED, mode);
142 /* 158 /*
@@ -160,8 +176,9 @@ static int etb_enable(struct coresight_device *csdev, u32 mode)
160 spin_unlock_irqrestore(&drvdata->spinlock, flags); 176 spin_unlock_irqrestore(&drvdata->spinlock, flags);
161 177
162out: 178out:
163 dev_dbg(drvdata->dev, "ETB enabled\n"); 179 if (!ret)
164 return 0; 180 dev_dbg(drvdata->dev, "ETB enabled\n");
181 return ret;
165} 182}
166 183
167static void etb_disable_hw(struct etb_drvdata *drvdata) 184static void etb_disable_hw(struct etb_drvdata *drvdata)
@@ -298,12 +315,14 @@ static void etb_free_buffer(void *config)
298} 315}
299 316
300static int etb_set_buffer(struct coresight_device *csdev, 317static int etb_set_buffer(struct coresight_device *csdev,
301 struct perf_output_handle *handle, 318 struct perf_output_handle *handle)
302 void *sink_config)
303{ 319{
304 int ret = 0; 320 int ret = 0;
305 unsigned long head; 321 unsigned long head;
306 struct cs_buffers *buf = sink_config; 322 struct cs_buffers *buf = etm_perf_sink_config(handle);
323
324 if (!buf)
325 return -EINVAL;
307 326
308 /* wrap head around to the amount of space we have */ 327 /* wrap head around to the amount of space we have */
309 head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); 328 head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
@@ -457,7 +476,6 @@ static const struct coresight_ops_sink etb_sink_ops = {
457 .disable = etb_disable, 476 .disable = etb_disable,
458 .alloc_buffer = etb_alloc_buffer, 477 .alloc_buffer = etb_alloc_buffer,
459 .free_buffer = etb_free_buffer, 478 .free_buffer = etb_free_buffer,
460 .set_buffer = etb_set_buffer,
461 .update_buffer = etb_update_buffer, 479 .update_buffer = etb_update_buffer,
462}; 480};
463 481
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 16b83d8b2ac2..abe8249b893b 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -286,16 +286,11 @@ static void etm_event_start(struct perf_event *event, int flags)
286 path = etm_event_cpu_path(event_data, cpu); 286 path = etm_event_cpu_path(event_data, cpu);
287 /* We need a sink, no need to continue without one */ 287 /* We need a sink, no need to continue without one */
288 sink = coresight_get_sink(path); 288 sink = coresight_get_sink(path);
289 if (WARN_ON_ONCE(!sink || !sink_ops(sink)->set_buffer)) 289 if (WARN_ON_ONCE(!sink))
290 goto fail_end_stop;
291
292 /* Configure the sink */
293 if (sink_ops(sink)->set_buffer(sink, handle,
294 event_data->snk_config))
295 goto fail_end_stop; 290 goto fail_end_stop;
296 291
297 /* Nothing will happen without a path */ 292 /* Nothing will happen without a path */
298 if (coresight_enable_path(path, CS_MODE_PERF)) 293 if (coresight_enable_path(path, CS_MODE_PERF, handle))
299 goto fail_end_stop; 294 goto fail_end_stop;
300 295
301 /* Tell the perf core the event is alive */ 296 /* Tell the perf core the event is alive */
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 1a6cf3589866..c11da5564a67 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -137,7 +137,7 @@ static inline void coresight_write_reg_pair(void __iomem *addr, u64 val,
137} 137}
138 138
139void coresight_disable_path(struct list_head *path); 139void coresight_disable_path(struct list_head *path);
140int coresight_enable_path(struct list_head *path, u32 mode); 140int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data);
141struct coresight_device *coresight_get_sink(struct list_head *path); 141struct coresight_device *coresight_get_sink(struct list_head *path);
142struct coresight_device *coresight_get_enabled_sink(bool reset); 142struct coresight_device *coresight_get_enabled_sink(bool reset);
143struct list_head *coresight_build_path(struct coresight_device *csdev, 143struct list_head *coresight_build_path(struct coresight_device *csdev,
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 31a98f915641..4156c95ce1bb 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -10,6 +10,10 @@
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include "coresight-priv.h" 11#include "coresight-priv.h"
12#include "coresight-tmc.h" 12#include "coresight-tmc.h"
13#include "coresight-etm-perf.h"
14
15static int tmc_set_etf_buffer(struct coresight_device *csdev,
16 struct perf_output_handle *handle);
13 17
14static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata) 18static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
15{ 19{
@@ -182,11 +186,12 @@ out:
182 return ret; 186 return ret;
183} 187}
184 188
185static int tmc_enable_etf_sink_perf(struct coresight_device *csdev) 189static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
186{ 190{
187 int ret = 0; 191 int ret = 0;
188 unsigned long flags; 192 unsigned long flags;
189 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 193 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
194 struct perf_output_handle *handle = data;
190 195
191 spin_lock_irqsave(&drvdata->spinlock, flags); 196 spin_lock_irqsave(&drvdata->spinlock, flags);
192 if (drvdata->reading) { 197 if (drvdata->reading) {
@@ -204,15 +209,19 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev)
204 goto out; 209 goto out;
205 } 210 }
206 211
207 drvdata->mode = CS_MODE_PERF; 212 ret = tmc_set_etf_buffer(csdev, handle);
208 tmc_etb_enable_hw(drvdata); 213 if (!ret) {
214 drvdata->mode = CS_MODE_PERF;
215 tmc_etb_enable_hw(drvdata);
216 }
209out: 217out:
210 spin_unlock_irqrestore(&drvdata->spinlock, flags); 218 spin_unlock_irqrestore(&drvdata->spinlock, flags);
211 219
212 return ret; 220 return ret;
213} 221}
214 222
215static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode) 223static int tmc_enable_etf_sink(struct coresight_device *csdev,
224 u32 mode, void *data)
216{ 225{
217 int ret; 226 int ret;
218 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 227 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
@@ -222,7 +231,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
222 ret = tmc_enable_etf_sink_sysfs(csdev); 231 ret = tmc_enable_etf_sink_sysfs(csdev);
223 break; 232 break;
224 case CS_MODE_PERF: 233 case CS_MODE_PERF:
225 ret = tmc_enable_etf_sink_perf(csdev); 234 ret = tmc_enable_etf_sink_perf(csdev, data);
226 break; 235 break;
227 /* We shouldn't be here */ 236 /* We shouldn't be here */
228 default: 237 default:
@@ -328,12 +337,14 @@ static void tmc_free_etf_buffer(void *config)
328} 337}
329 338
330static int tmc_set_etf_buffer(struct coresight_device *csdev, 339static int tmc_set_etf_buffer(struct coresight_device *csdev,
331 struct perf_output_handle *handle, 340 struct perf_output_handle *handle)
332 void *sink_config)
333{ 341{
334 int ret = 0; 342 int ret = 0;
335 unsigned long head; 343 unsigned long head;
336 struct cs_buffers *buf = sink_config; 344 struct cs_buffers *buf = etm_perf_sink_config(handle);
345
346 if (!buf)
347 return -EINVAL;
337 348
338 /* wrap head around to the amount of space we have */ 349 /* wrap head around to the amount of space we have */
339 head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); 350 head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
@@ -472,7 +483,6 @@ static const struct coresight_ops_sink tmc_etf_sink_ops = {
472 .disable = tmc_disable_etf_sink, 483 .disable = tmc_disable_etf_sink,
473 .alloc_buffer = tmc_alloc_etf_buffer, 484 .alloc_buffer = tmc_alloc_etf_buffer,
474 .free_buffer = tmc_free_etf_buffer, 485 .free_buffer = tmc_free_etf_buffer,
475 .set_buffer = tmc_set_etf_buffer,
476 .update_buffer = tmc_update_etf_buffer, 486 .update_buffer = tmc_update_etf_buffer,
477}; 487};
478 488
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 5e9bb2f0e9c0..1aedfc3629c0 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1103,19 +1103,20 @@ out:
1103 return ret; 1103 return ret;
1104} 1104}
1105 1105
1106static int tmc_enable_etr_sink_perf(struct coresight_device *csdev) 1106static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
1107{ 1107{
1108 /* We don't support perf mode yet ! */ 1108 /* We don't support perf mode yet ! */
1109 return -EINVAL; 1109 return -EINVAL;
1110} 1110}
1111 1111
1112static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode) 1112static int tmc_enable_etr_sink(struct coresight_device *csdev,
1113 u32 mode, void *data)
1113{ 1114{
1114 switch (mode) { 1115 switch (mode) {
1115 case CS_MODE_SYSFS: 1116 case CS_MODE_SYSFS:
1116 return tmc_enable_etr_sink_sysfs(csdev); 1117 return tmc_enable_etr_sink_sysfs(csdev);
1117 case CS_MODE_PERF: 1118 case CS_MODE_PERF:
1118 return tmc_enable_etr_sink_perf(csdev); 1119 return tmc_enable_etr_sink_perf(csdev, data);
1119 } 1120 }
1120 1121
1121 /* We shouldn't be here */ 1122 /* We shouldn't be here */
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index ce0b84583861..b2f72a1fa402 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -68,7 +68,7 @@ static void tpiu_enable_hw(struct tpiu_drvdata *drvdata)
68 CS_LOCK(drvdata->base); 68 CS_LOCK(drvdata->base);
69} 69}
70 70
71static int tpiu_enable(struct coresight_device *csdev, u32 mode) 71static int tpiu_enable(struct coresight_device *csdev, u32 mode, void *__unused)
72{ 72{
73 struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 73 struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
74 74
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 07382c55b31d..e73ca6af4765 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -128,7 +128,8 @@ static int coresight_find_link_outport(struct coresight_device *csdev,
128 return -ENODEV; 128 return -ENODEV;
129} 129}
130 130
131static int coresight_enable_sink(struct coresight_device *csdev, u32 mode) 131static int coresight_enable_sink(struct coresight_device *csdev,
132 u32 mode, void *data)
132{ 133{
133 int ret; 134 int ret;
134 135
@@ -137,7 +138,7 @@ static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
137 * existing "mode" of operation. 138 * existing "mode" of operation.
138 */ 139 */
139 if (sink_ops(csdev)->enable) { 140 if (sink_ops(csdev)->enable) {
140 ret = sink_ops(csdev)->enable(csdev, mode); 141 ret = sink_ops(csdev)->enable(csdev, mode, data);
141 if (ret) 142 if (ret)
142 return ret; 143 return ret;
143 csdev->enable = true; 144 csdev->enable = true;
@@ -315,7 +316,7 @@ void coresight_disable_path(struct list_head *path)
315 } 316 }
316} 317}
317 318
318int coresight_enable_path(struct list_head *path, u32 mode) 319int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data)
319{ 320{
320 321
321 int ret = 0; 322 int ret = 0;
@@ -340,7 +341,7 @@ int coresight_enable_path(struct list_head *path, u32 mode)
340 341
341 switch (type) { 342 switch (type) {
342 case CORESIGHT_DEV_TYPE_SINK: 343 case CORESIGHT_DEV_TYPE_SINK:
343 ret = coresight_enable_sink(csdev, mode); 344 ret = coresight_enable_sink(csdev, mode, sink_data);
344 /* 345 /*
345 * Sink is the first component turned on. If we 346 * Sink is the first component turned on. If we
346 * failed to enable the sink, there are no components 347 * failed to enable the sink, there are no components
@@ -643,7 +644,7 @@ int coresight_enable(struct coresight_device *csdev)
643 goto out; 644 goto out;
644 } 645 }
645 646
646 ret = coresight_enable_path(path, CS_MODE_SYSFS); 647 ret = coresight_enable_path(path, CS_MODE_SYSFS, NULL);
647 if (ret) 648 if (ret)
648 goto err_path; 649 goto err_path;
649 650