1 /* 2 * Copyright(C) 2015 Linaro Limited. All rights reserved. 3 * Author: Mathieu Poirier <mathieu.poirier@linaro.org> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include <linux/coresight.h> 19 #include <linux/coresight-pmu.h> 20 #include <linux/cpumask.h> 21 #include <linux/device.h> 22 #include <linux/list.h> 23 #include <linux/mm.h> 24 #include <linux/init.h> 25 #include <linux/perf_event.h> 26 #include <linux/slab.h> 27 #include <linux/types.h> 28 #include <linux/workqueue.h> 29 30 #include "coresight-priv.h" 31 32 static struct pmu etm_pmu; 33 static bool etm_perf_up; 34 35 /** 36 * struct etm_event_data - Coresight specifics associated to an event 37 * @work: Handle to free allocated memory outside IRQ context. 38 * @mask: Hold the CPU(s) this event was set for. 39 * @snk_config: The sink configuration. 40 * @path: An array of path, each slot for one CPU. 41 */ 42 struct etm_event_data { 43 struct work_struct work; 44 cpumask_t mask; 45 void *snk_config; 46 struct list_head **path; 47 }; 48 49 static DEFINE_PER_CPU(struct perf_output_handle, ctx_handle); 50 static DEFINE_PER_CPU(struct coresight_device *, csdev_src); 51 52 /* ETMv3.5/PTM's ETMCR is 'config' */ 53 PMU_FORMAT_ATTR(cycacc, "config:" __stringify(ETM_OPT_CYCACC)); 54 PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS)); 55 56 static struct attribute *etm_config_formats_attr[] = { 57 &format_attr_cycacc.attr, 58 &format_attr_timestamp.attr, 59 NULL, 60 }; 61 62 static struct attribute_group etm_pmu_format_group = { 63 .name = "format", 64 .attrs = etm_config_formats_attr, 65 }; 66 67 static const struct attribute_group *etm_pmu_attr_groups[] = { 68 &etm_pmu_format_group, 69 NULL, 70 }; 71 72 static void etm_event_read(struct perf_event *event) {} 73 74 static int etm_event_init(struct perf_event *event) 75 { 76 if (event->attr.type != etm_pmu.type) 77 return -ENOENT; 78 79 return 0; 80 } 81 82 static void free_event_data(struct work_struct *work) 83 { 84 int cpu; 85 cpumask_t *mask; 86 struct etm_event_data *event_data; 87 struct coresight_device *sink; 88 89 event_data = container_of(work, struct etm_event_data, work); 90 mask = &event_data->mask; 91 /* 92 * First deal with the sink configuration. See comment in 93 * etm_setup_aux() about why we take the first available path. 94 */ 95 if (event_data->snk_config) { 96 cpu = cpumask_first(mask); 97 sink = coresight_get_sink(event_data->path[cpu]); 98 if (sink_ops(sink)->free_buffer) 99 sink_ops(sink)->free_buffer(event_data->snk_config); 100 } 101 102 for_each_cpu(cpu, mask) { 103 if (event_data->path[cpu]) 104 coresight_release_path(event_data->path[cpu]); 105 } 106 107 kfree(event_data->path); 108 kfree(event_data); 109 } 110 111 static void *alloc_event_data(int cpu) 112 { 113 int size; 114 cpumask_t *mask; 115 struct etm_event_data *event_data; 116 117 /* First get memory for the session's data */ 118 event_data = kzalloc(sizeof(struct etm_event_data), GFP_KERNEL); 119 if (!event_data) 120 return NULL; 121 122 /* Make sure nothing disappears under us */ 123 get_online_cpus(); 124 size = num_online_cpus(); 125 126 mask = &event_data->mask; 127 if (cpu != -1) 128 cpumask_set_cpu(cpu, mask); 129 else 130 cpumask_copy(mask, cpu_online_mask); 131 put_online_cpus(); 132 133 /* 134 * Each CPU has a single path between source and destination. As such 135 * allocate an array using CPU numbers as indexes. That way a path 136 * for any CPU can easily be accessed at any given time. We proceed 137 * the same way for sessions involving a single CPU. The cost of 138 * unused memory when dealing with single CPU trace scenarios is small 139 * compared to the cost of searching through an optimized array. 140 */ 141 event_data->path = kcalloc(size, 142 sizeof(struct list_head *), GFP_KERNEL); 143 if (!event_data->path) { 144 kfree(event_data); 145 return NULL; 146 } 147 148 return event_data; 149 } 150 151 static void etm_free_aux(void *data) 152 { 153 struct etm_event_data *event_data = data; 154 155 schedule_work(&event_data->work); 156 } 157 158 static void *etm_setup_aux(int event_cpu, void **pages, 159 int nr_pages, bool overwrite) 160 { 161 int cpu; 162 cpumask_t *mask; 163 struct coresight_device *sink; 164 struct etm_event_data *event_data = NULL; 165 166 event_data = alloc_event_data(event_cpu); 167 if (!event_data) 168 return NULL; 169 170 INIT_WORK(&event_data->work, free_event_data); 171 172 mask = &event_data->mask; 173 174 /* Setup the path for each CPU in a trace session */ 175 for_each_cpu(cpu, mask) { 176 struct coresight_device *csdev; 177 178 csdev = per_cpu(csdev_src, cpu); 179 if (!csdev) 180 goto err; 181 182 /* 183 * Building a path doesn't enable it, it simply builds a 184 * list of devices from source to sink that can be 185 * referenced later when the path is actually needed. 186 */ 187 event_data->path[cpu] = coresight_build_path(csdev); 188 if (!event_data->path[cpu]) 189 goto err; 190 } 191 192 /* 193 * In theory nothing prevent tracers in a trace session from being 194 * associated with different sinks, nor having a sink per tracer. But 195 * until we have HW with this kind of topology and a way to convey 196 * sink assignement from the perf cmd line we need to assume tracers 197 * in a trace session are using the same sink. Therefore pick the sink 198 * found at the end of the first available path. 199 */ 200 cpu = cpumask_first(mask); 201 /* Grab the sink at the end of the path */ 202 sink = coresight_get_sink(event_data->path[cpu]); 203 if (!sink) 204 goto err; 205 206 if (!sink_ops(sink)->alloc_buffer) 207 goto err; 208 209 /* Get the AUX specific data from the sink buffer */ 210 event_data->snk_config = 211 sink_ops(sink)->alloc_buffer(sink, cpu, pages, 212 nr_pages, overwrite); 213 if (!event_data->snk_config) 214 goto err; 215 216 out: 217 return event_data; 218 219 err: 220 etm_free_aux(event_data); 221 event_data = NULL; 222 goto out; 223 } 224 225 static void etm_event_start(struct perf_event *event, int flags) 226 { 227 int cpu = smp_processor_id(); 228 struct etm_event_data *event_data; 229 struct perf_output_handle *handle = this_cpu_ptr(&ctx_handle); 230 struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu); 231 232 if (!csdev) 233 goto fail; 234 235 /* 236 * Deal with the ring buffer API and get a handle on the 237 * session's information. 238 */ 239 event_data = perf_aux_output_begin(handle, event); 240 if (!event_data) 241 goto fail; 242 243 /* We need a sink, no need to continue without one */ 244 sink = coresight_get_sink(event_data->path[cpu]); 245 if (WARN_ON_ONCE(!sink || !sink_ops(sink)->set_buffer)) 246 goto fail_end_stop; 247 248 /* Configure the sink */ 249 if (sink_ops(sink)->set_buffer(sink, handle, 250 event_data->snk_config)) 251 goto fail_end_stop; 252 253 /* Nothing will happen without a path */ 254 if (coresight_enable_path(event_data->path[cpu], CS_MODE_PERF)) 255 goto fail_end_stop; 256 257 /* Tell the perf core the event is alive */ 258 event->hw.state = 0; 259 260 /* Finally enable the tracer */ 261 if (source_ops(csdev)->enable(csdev, &event->attr, CS_MODE_PERF)) 262 goto fail_end_stop; 263 264 out: 265 return; 266 267 fail_end_stop: 268 perf_aux_output_end(handle, 0, true); 269 fail: 270 event->hw.state = PERF_HES_STOPPED; 271 goto out; 272 } 273 274 static void etm_event_stop(struct perf_event *event, int mode) 275 { 276 bool lost; 277 int cpu = smp_processor_id(); 278 unsigned long size; 279 struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu); 280 struct perf_output_handle *handle = this_cpu_ptr(&ctx_handle); 281 struct etm_event_data *event_data = perf_get_aux(handle); 282 283 if (event->hw.state == PERF_HES_STOPPED) 284 return; 285 286 if (!csdev) 287 return; 288 289 sink = coresight_get_sink(event_data->path[cpu]); 290 if (!sink) 291 return; 292 293 /* stop tracer */ 294 source_ops(csdev)->disable(csdev); 295 296 /* tell the core */ 297 event->hw.state = PERF_HES_STOPPED; 298 299 if (mode & PERF_EF_UPDATE) { 300 if (WARN_ON_ONCE(handle->event != event)) 301 return; 302 303 /* update trace information */ 304 if (!sink_ops(sink)->update_buffer) 305 return; 306 307 sink_ops(sink)->update_buffer(sink, handle, 308 event_data->snk_config); 309 310 if (!sink_ops(sink)->reset_buffer) 311 return; 312 313 size = sink_ops(sink)->reset_buffer(sink, handle, 314 event_data->snk_config, 315 &lost); 316 317 perf_aux_output_end(handle, size, lost); 318 } 319 320 /* Disabling the path make its elements available to other sessions */ 321 coresight_disable_path(event_data->path[cpu]); 322 } 323 324 static int etm_event_add(struct perf_event *event, int mode) 325 { 326 int ret = 0; 327 struct hw_perf_event *hwc = &event->hw; 328 329 if (mode & PERF_EF_START) { 330 etm_event_start(event, 0); 331 if (hwc->state & PERF_HES_STOPPED) 332 ret = -EINVAL; 333 } else { 334 hwc->state = PERF_HES_STOPPED; 335 } 336 337 return ret; 338 } 339 340 static void etm_event_del(struct perf_event *event, int mode) 341 { 342 etm_event_stop(event, PERF_EF_UPDATE); 343 } 344 345 int etm_perf_symlink(struct coresight_device *csdev, bool link) 346 { 347 char entry[sizeof("cpu9999999")]; 348 int ret = 0, cpu = source_ops(csdev)->cpu_id(csdev); 349 struct device *pmu_dev = etm_pmu.dev; 350 struct device *cs_dev = &csdev->dev; 351 352 sprintf(entry, "cpu%d", cpu); 353 354 if (!etm_perf_up) 355 return -EPROBE_DEFER; 356 357 if (link) { 358 ret = sysfs_create_link(&pmu_dev->kobj, &cs_dev->kobj, entry); 359 if (ret) 360 return ret; 361 per_cpu(csdev_src, cpu) = csdev; 362 } else { 363 sysfs_remove_link(&pmu_dev->kobj, entry); 364 per_cpu(csdev_src, cpu) = NULL; 365 } 366 367 return 0; 368 } 369 370 static int __init etm_perf_init(void) 371 { 372 int ret; 373 374 etm_pmu.capabilities = PERF_PMU_CAP_EXCLUSIVE; 375 376 etm_pmu.attr_groups = etm_pmu_attr_groups; 377 etm_pmu.task_ctx_nr = perf_sw_context; 378 etm_pmu.read = etm_event_read; 379 etm_pmu.event_init = etm_event_init; 380 etm_pmu.setup_aux = etm_setup_aux; 381 etm_pmu.free_aux = etm_free_aux; 382 etm_pmu.start = etm_event_start; 383 etm_pmu.stop = etm_event_stop; 384 etm_pmu.add = etm_event_add; 385 etm_pmu.del = etm_event_del; 386 387 ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1); 388 if (ret == 0) 389 etm_perf_up = true; 390 391 return ret; 392 } 393 device_initcall(etm_perf_init); 394