Merge remote-tracking branch 'origin/upstream/linux-linaro-lsk-v3.10-android' into...
[firefly-linux-kernel-4.4.55.git] / drivers / gator / gator_events_perf_pmu.c
1 /**
2  * Copyright (C) ARM Limited 2010-2013. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 #include "gator.h"
10
11 // gator_events_armvX.c is used for Linux 2.6.x
12 #if GATOR_PERF_PMU_SUPPORT
13
14 #include <linux/io.h>
15 #ifdef CONFIG_OF
16 #include <linux/of_address.h>
17 #endif
18 #include <linux/perf_event.h>
19 #include <linux/slab.h>
20
21 extern bool event_based_sampling;
22
23 // Maximum number of per-core counters - currently reserves enough space for two full hardware PMUs for big.LITTLE
24 #define CNTMAX 16
25 #define CCI_400 4
26 // Maximum number of uncore counters
27 // + 1 for the cci-400 cycles counter
28 #define UCCNT (CCI_400 + 1)
29
30 // Default to 0 if unable to probe the revision which was the previous behavior
31 #define DEFAULT_CCI_REVISION 0
32
33 // A gator_attr is needed for every counter
34 struct gator_attr {
35         // Set once in gator_events_perf_pmu_*_init - the name of the event in the gatorfs
36         char name[40];
37         // Exposed in gatorfs - set by gatord to enable this counter
38         unsigned long enabled;
39         // Set once in gator_events_perf_pmu_*_init - the perf type to use, see perf_type_id in the perf_event.h header file.
40         unsigned long type;
41         // Exposed in gatorfs - set by gatord to select the event to collect
42         unsigned long event;
43         // Exposed in gatorfs - set by gatord with the sample period to use and enable EBS for this counter
44         unsigned long count;
45         // Exposed as read only in gatorfs - set once in __attr_init as the key to use in the APC data
46         unsigned long key;
47 };
48
49 // Per-core counter attributes
50 static struct gator_attr attrs[CNTMAX];
51 // Number of initialized per-core counters
52 static int attr_count;
53 // Uncore counter attributes
54 static struct gator_attr uc_attrs[UCCNT];
55 // Number of initialized uncore counters
56 static int uc_attr_count;
57
58 struct gator_event {
59         int curr;
60         int prev;
61         int prev_delta;
62         bool zero;
63         struct perf_event *pevent;
64         struct perf_event_attr *pevent_attr;
65 };
66
67 static DEFINE_PER_CPU(struct gator_event[CNTMAX], events);
68 static struct gator_event uc_events[UCCNT];
69 static DEFINE_PER_CPU(int[(CNTMAX + UCCNT)*2], perf_cnt);
70
71 static void gator_events_perf_pmu_stop(void);
72
73 static int __create_files(struct super_block *sb, struct dentry *root, struct gator_attr *const attr)
74 {
75         struct dentry *dir;
76
77         if (attr->name[0] == '\0') {
78                 return 0;
79         }
80         dir = gatorfs_mkdir(sb, root, attr->name);
81         if (!dir) {
82                 return -1;
83         }
84         gatorfs_create_ulong(sb, dir, "enabled", &attr->enabled);
85         gatorfs_create_ulong(sb, dir, "count", &attr->count);
86         gatorfs_create_ro_ulong(sb, dir, "key", &attr->key);
87         gatorfs_create_ulong(sb, dir, "event", &attr->event);
88
89         return 0;
90 }
91
92 static int gator_events_perf_pmu_create_files(struct super_block *sb, struct dentry *root)
93 {
94         int cnt;
95
96         for (cnt = 0; cnt < attr_count; cnt++) {
97                 if (__create_files(sb, root, &attrs[cnt]) != 0) {
98                         return -1;
99                 }
100         }
101
102         for (cnt = 0; cnt < uc_attr_count; cnt++) {
103                 if (__create_files(sb, root, &uc_attrs[cnt]) != 0) {
104                         return -1;
105                 }
106         }
107
108         return 0;
109 }
110
111 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
112 static void ebs_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs)
113 #else
114 static void ebs_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs)
115 #endif
116 {
117         gator_backtrace_handler(regs);
118 }
119
120 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
121 static void dummy_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs)
122 #else
123 static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs)
124 #endif
125 {
126 // Required as perf_event_create_kernel_counter() requires an overflow handler, even though all we do is poll
127 }
128
129 static int gator_events_perf_pmu_read(int **buffer);
130
131 static int gator_events_perf_pmu_online(int **buffer, bool migrate)
132 {
133         return gator_events_perf_pmu_read(buffer);
134 }
135
136 static void __online_dispatch(int cpu, bool migrate, struct gator_attr *const attr, struct gator_event *const event)
137 {
138         perf_overflow_handler_t handler;
139
140         event->zero = true;
141
142         if (event->pevent != NULL || event->pevent_attr == 0 || migrate) {
143                 return;
144         }
145
146         if (attr->count > 0) {
147                 handler = ebs_overflow_handler;
148         } else {
149                 handler = dummy_handler;
150         }
151
152 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
153         event->pevent = perf_event_create_kernel_counter(event->pevent_attr, cpu, 0, handler);
154 #else
155         event->pevent = perf_event_create_kernel_counter(event->pevent_attr, cpu, 0, handler, 0);
156 #endif
157         if (IS_ERR(event->pevent)) {
158                 pr_debug("gator: unable to online a counter on cpu %d\n", cpu);
159                 event->pevent = NULL;
160                 return;
161         }
162
163         if (event->pevent->state != PERF_EVENT_STATE_ACTIVE) {
164                 pr_debug("gator: inactive counter on cpu %d\n", cpu);
165                 perf_event_release_kernel(event->pevent);
166                 event->pevent = NULL;
167                 return;
168         }
169 }
170
171 static void gator_events_perf_pmu_online_dispatch(int cpu, bool migrate)
172 {
173         int cnt;
174
175         cpu = pcpu_to_lcpu(cpu);
176
177         for (cnt = 0; cnt < attr_count; cnt++) {
178                 __online_dispatch(cpu, migrate, &attrs[cnt], &per_cpu(events, cpu)[cnt]);
179         }
180
181         if (cpu == 0) {
182                 for (cnt = 0; cnt < uc_attr_count; cnt++) {
183                         __online_dispatch(cpu, migrate, &uc_attrs[cnt], &uc_events[cnt]);
184                 }
185         }
186 }
187
188 static void __offline_dispatch(int cpu, struct gator_event *const event)
189 {
190         struct perf_event *pe = NULL;
191
192         if (event->pevent) {
193                 pe = event->pevent;
194                 event->pevent = NULL;
195         }
196
197         if (pe) {
198                 perf_event_release_kernel(pe);
199         }
200 }
201
202 static void gator_events_perf_pmu_offline_dispatch(int cpu, bool migrate)
203 {
204         int cnt;
205
206         if (migrate) {
207                 return;
208         }
209         cpu = pcpu_to_lcpu(cpu);
210
211         for (cnt = 0; cnt < attr_count; cnt++) {
212                 __offline_dispatch(cpu, &per_cpu(events, cpu)[cnt]);
213         }
214
215         if (cpu == 0) {
216                 for (cnt = 0; cnt < uc_attr_count; cnt++) {
217                         __offline_dispatch(cpu, &uc_events[cnt]);
218                 }
219         }
220 }
221
222 static int __check_ebs(struct gator_attr *const attr)
223 {
224         if (attr->count > 0) {
225                 if (!event_based_sampling) {
226                         event_based_sampling = true;
227                 } else {
228                         printk(KERN_WARNING "gator: Only one ebs counter is allowed\n");
229                         return -1;
230                 }
231         }
232
233         return 0;
234 }
235
236 static int __start(struct gator_attr *const attr, struct gator_event *const event)
237 {
238         u32 size = sizeof(struct perf_event_attr);
239
240         event->pevent = NULL;
241         if (!attr->enabled) {   // Skip disabled counters
242                 return 0;
243         }
244
245         event->prev = 0;
246         event->curr = 0;
247         event->prev_delta = 0;
248         event->pevent_attr = kmalloc(size, GFP_KERNEL);
249         if (!event->pevent_attr) {
250                 gator_events_perf_pmu_stop();
251                 return -1;
252         }
253
254         memset(event->pevent_attr, 0, size);
255         event->pevent_attr->type = attr->type;
256         event->pevent_attr->size = size;
257         event->pevent_attr->config = attr->event;
258         event->pevent_attr->sample_period = attr->count;
259         event->pevent_attr->pinned = 1;
260
261         return 0;
262 }
263
264 static int gator_events_perf_pmu_start(void)
265 {
266         int cnt, cpu;
267
268         event_based_sampling = false;
269         for (cnt = 0; cnt < attr_count; cnt++) {
270                 if (__check_ebs(&attrs[cnt]) != 0) {
271                         return -1;
272                 }
273         }
274
275         for (cnt = 0; cnt < uc_attr_count; cnt++) {
276                 if (__check_ebs(&uc_attrs[cnt]) != 0) {
277                         return -1;
278                 }
279         }
280
281         for_each_present_cpu(cpu) {
282                 for (cnt = 0; cnt < attr_count; cnt++) {
283                         if (__start(&attrs[cnt], &per_cpu(events, cpu)[cnt]) != 0) {
284                                 return -1;
285                         }
286                 }
287         }
288
289         for (cnt = 0; cnt < uc_attr_count; cnt++) {
290                 if (__start(&uc_attrs[cnt], &uc_events[cnt]) != 0) {
291                         return -1;
292                 }
293         }
294
295         return 0;
296 }
297
298 static void __event_stop(struct gator_event *const event)
299 {
300         if (event->pevent_attr) {
301                 kfree(event->pevent_attr);
302                 event->pevent_attr = NULL;
303         }
304 }
305
306 static void __attr_stop(struct gator_attr *const attr)
307 {
308         attr->enabled = 0;
309         attr->event = 0;
310         attr->count = 0;
311 }
312
313 static void gator_events_perf_pmu_stop(void)
314 {
315         unsigned int cnt, cpu;
316
317         for_each_present_cpu(cpu) {
318                 for (cnt = 0; cnt < attr_count; cnt++) {
319                         __event_stop(&per_cpu(events, cpu)[cnt]);
320                 }
321         }
322
323         for (cnt = 0; cnt < uc_attr_count; cnt++) {
324                 __event_stop(&uc_events[cnt]);
325         }
326
327         for (cnt = 0; cnt < attr_count; cnt++) {
328                 __attr_stop(&attrs[cnt]);
329         }
330
331         for (cnt = 0; cnt < uc_attr_count; cnt++) {
332                 __attr_stop(&uc_attrs[cnt]);
333         }
334 }
335
336 static void __read(int *const len, int cpu, struct gator_attr *const attr, struct gator_event *const event)
337 {
338         int delta;
339
340         struct perf_event *const ev = event->pevent;
341         if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
342                 /* After creating the perf counter in __online_dispatch, there
343                  * is a race condition between gator_events_perf_pmu_online and
344                  * gator_events_perf_pmu_read. So have
345                  * gator_events_perf_pmu_online call gator_events_perf_pmu_read
346                  * and in __read check to see if it's the first call after
347                  * __online_dispatch and if so, run the online code.
348                  */
349                 if (event->zero) {
350                         ev->pmu->read(ev);
351                         event->prev = event->curr = local64_read(&ev->count);
352                         event->prev_delta = 0;
353                         per_cpu(perf_cnt, cpu)[(*len)++] = attr->key;
354                         per_cpu(perf_cnt, cpu)[(*len)++] = 0;
355                         event->zero = false;
356                 } else {
357                         ev->pmu->read(ev);
358                         event->curr = local64_read(&ev->count);
359                         delta = event->curr - event->prev;
360                         if (delta != 0 || delta != event->prev_delta) {
361                                 event->prev_delta = delta;
362                                 event->prev = event->curr;
363                                 per_cpu(perf_cnt, cpu)[(*len)++] = attr->key;
364                                 if (delta < 0) {
365                                         delta *= -1;
366                                 }
367                                 per_cpu(perf_cnt, cpu)[(*len)++] = delta;
368                         }
369                 }
370         }
371 }
372
373 static int gator_events_perf_pmu_read(int **buffer)
374 {
375         int cnt, len = 0;
376         const int cpu = get_logical_cpu();
377
378         for (cnt = 0; cnt < attr_count; cnt++) {
379                 __read(&len, cpu, &attrs[cnt], &per_cpu(events, cpu)[cnt]);
380         }
381
382         if (cpu == 0) {
383                 for (cnt = 0; cnt < uc_attr_count; cnt++) {
384                         __read(&len, cpu, &uc_attrs[cnt], &uc_events[cnt]);
385                 }
386         }
387
388         if (buffer) {
389                 *buffer = per_cpu(perf_cnt, cpu);
390         }
391
392         return len;
393 }
394
395 static struct gator_interface gator_events_perf_pmu_interface = {
396         .create_files = gator_events_perf_pmu_create_files,
397         .start = gator_events_perf_pmu_start,
398         .stop = gator_events_perf_pmu_stop,
399         .online = gator_events_perf_pmu_online,
400         .online_dispatch = gator_events_perf_pmu_online_dispatch,
401         .offline_dispatch = gator_events_perf_pmu_offline_dispatch,
402         .read = gator_events_perf_pmu_read,
403 };
404
405 static void __attr_init(struct gator_attr *const attr)
406 {
407         attr->name[0] = '\0';
408         attr->enabled = 0;
409         attr->type = 0;
410         attr->event = 0;
411         attr->count = 0;
412         attr->key = gator_events_get_key();
413 }
414
415 #ifdef CONFIG_OF
416
417 static const struct of_device_id arm_cci_matches[] = {
418         {.compatible = "arm,cci-400" },
419         {},
420 };
421
422 static int probe_cci_revision(void)
423 {
424         struct device_node *np;
425         struct resource res;
426         void __iomem *cci_ctrl_base;
427         int rev;
428         int ret = DEFAULT_CCI_REVISION;
429
430         np = of_find_matching_node(NULL, arm_cci_matches);
431         if (!np) {
432                 return ret;
433         }
434
435         if (of_address_to_resource(np, 0, &res)) {
436                 goto node_put;
437         }
438
439         cci_ctrl_base = ioremap(res.start, resource_size(&res));
440
441         rev = (readl_relaxed(cci_ctrl_base + 0xfe8) >> 4) & 0xf;
442
443         if (rev <= 4) {
444                 ret = 0;
445         } else if (rev <= 6) {
446                 ret = 1;
447         }
448
449         iounmap(cci_ctrl_base);
450
451  node_put:
452         of_node_put(np);
453
454         return ret;
455 }
456
457 #else
458
459 static int probe_cci_revision(void)
460 {
461         return DEFAULT_CCI_REVISION;
462 }
463
464 #endif
465
466 static void gator_events_perf_pmu_cci_init(const int type)
467 {
468         int cnt;
469         const char *cci_name;
470
471         switch (probe_cci_revision()) {
472         case 0:
473                 cci_name = "cci-400";
474                 break;
475         case 1:
476                 cci_name = "cci-400-r1";
477                 break;
478         default:
479                 pr_debug("gator: unrecognized cci-400 revision\n");
480                 return;
481         }
482
483         snprintf(uc_attrs[uc_attr_count].name, sizeof(uc_attrs[uc_attr_count].name), "%s_ccnt", cci_name);
484         uc_attrs[uc_attr_count].type = type;
485         ++uc_attr_count;
486
487         for (cnt = 0; cnt < CCI_400; ++cnt, ++uc_attr_count) {
488                 struct gator_attr *const attr = &uc_attrs[uc_attr_count];
489                 snprintf(attr->name, sizeof(attr->name), "%s_cnt%d", cci_name, cnt);
490                 attr->type = type;
491         }
492 }
493
494 static void gator_events_perf_pmu_cpu_init(const struct gator_cpu *const gator_cpu, const int type)
495 {
496         int cnt;
497
498         snprintf(attrs[attr_count].name, sizeof(attrs[attr_count].name), "%s_ccnt", gator_cpu->pmnc_name);
499         attrs[attr_count].type = type;
500         ++attr_count;
501
502         for (cnt = 0; cnt < gator_cpu->pmnc_counters; ++cnt, ++attr_count) {
503                 struct gator_attr *const attr = &attrs[attr_count];
504                 snprintf(attr->name, sizeof(attr->name), "%s_cnt%d", gator_cpu->pmnc_name, cnt);
505                 attr->type = type;
506         }
507 }
508
509 int gator_events_perf_pmu_init(void)
510 {
511         struct perf_event_attr pea;
512         struct perf_event *pe;
513         const struct gator_cpu *gator_cpu;
514         int type;
515         int cpu;
516         int cnt;
517         bool found_cpu = false;
518
519         for (cnt = 0; cnt < CNTMAX; cnt++) {
520                 __attr_init(&attrs[cnt]);
521         }
522         for (cnt = 0; cnt < UCCNT; cnt++) {
523                 __attr_init(&uc_attrs[cnt]);
524         }
525
526         memset(&pea, 0, sizeof(pea));
527         pea.size = sizeof(pea);
528         pea.config = 0xFF;
529         attr_count = 0;
530         uc_attr_count = 0;
531         for (type = PERF_TYPE_MAX; type < 0x20; ++type) {
532                 pea.type = type;
533
534                 // A particular PMU may work on some but not all cores, so try on each core
535                 pe = NULL;
536                 for_each_present_cpu(cpu) {
537 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
538                         pe = perf_event_create_kernel_counter(&pea, cpu, 0, dummy_handler);
539 #else
540                         pe = perf_event_create_kernel_counter(&pea, cpu, 0, dummy_handler, 0);
541 #endif
542                         if (!IS_ERR(pe)) {
543                                 break;
544                         }
545                 }
546                 // Assume that valid PMUs are contiguous
547                 if (IS_ERR(pe)) {
548                         break;
549                 }
550
551                 if (pe->pmu != NULL && type == pe->pmu->type) {
552                         if (strcmp("CCI", pe->pmu->name) == 0 || strcmp("CCI_400", pe->pmu->name) == 0) {
553                                 gator_events_perf_pmu_cci_init(type);
554                         } else if ((gator_cpu = gator_find_cpu_by_pmu_name(pe->pmu->name)) != NULL) {
555                                 found_cpu = true;
556                                 gator_events_perf_pmu_cpu_init(gator_cpu, type);
557                         }
558                         // Initialize gator_attrs for dynamic PMUs here
559                 }
560
561                 perf_event_release_kernel(pe);
562         }
563
564         if (!found_cpu) {
565                 const struct gator_cpu *const gator_cpu = gator_find_cpu_by_cpuid(gator_cpuid());
566                 if (gator_cpu == NULL) {
567                         return -1;
568                 }
569                 gator_events_perf_pmu_cpu_init(gator_cpu, PERF_TYPE_RAW);
570         }
571
572         // Initialize gator_attrs for non-dynamic PMUs here
573
574         if (attr_count > CNTMAX) {
575                 printk(KERN_ERR "gator: Too many perf counters\n");
576                 return -1;
577         }
578
579         if (uc_attr_count > UCCNT) {
580                 printk(KERN_ERR "gator: Too many perf uncore counters\n");
581                 return -1;
582         }
583
584         return gator_events_install(&gator_events_perf_pmu_interface);
585 }
586
587 #endif