c6e7bc477b916d1db38a0a5c69fa10170d699c9c
[linux-2.6.git] / drivers / misc / tegra-profiler / hrt.c
1 /*
2  * drivers/misc/tegra-profiler/hrt.c
3  *
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/module.h>
20 #include <linux/kallsyms.h>
21 #include <linux/sched.h>
22 #include <linux/hrtimer.h>
23 #include <linux/slab.h>
24 #include <linux/cpu.h>
25 #include <linux/ratelimit.h>
26 #include <linux/ptrace.h>
27 #include <linux/interrupt.h>
28 #include <linux/err.h>
29
30 #include <asm/cputype.h>
31 #include <asm/irq_regs.h>
32
33 #include <linux/tegra_profiler.h>
34
35 #include "quadd.h"
36 #include "hrt.h"
37 #include "comm.h"
38 #include "mmap.h"
39 #include "ma.h"
40 #include "power_clk.h"
41 #include "tegra.h"
42 #include "debug.h"
43
44 static struct quadd_hrt_ctx hrt;
45
46 static void
47 read_all_sources(struct pt_regs *regs, struct task_struct *task);
48
49 struct hrt_event_value {
50         int event_id;
51         u32 value;
52 };
53
54 static enum hrtimer_restart hrtimer_handler(struct hrtimer *hrtimer)
55 {
56         struct pt_regs *regs;
57
58         regs = get_irq_regs();
59
60         if (!hrt.active)
61                 return HRTIMER_NORESTART;
62
63         qm_debug_handler_sample(regs);
64
65         if (regs)
66                 read_all_sources(regs, NULL);
67
68         hrtimer_forward_now(hrtimer, ns_to_ktime(hrt.sample_period));
69         qm_debug_timer_forward(regs, hrt.sample_period);
70
71         return HRTIMER_RESTART;
72 }
73
74 static void start_hrtimer(struct quadd_cpu_context *cpu_ctx)
75 {
76         u64 period = hrt.sample_period;
77
78         hrtimer_start(&cpu_ctx->hrtimer, ns_to_ktime(period),
79                       HRTIMER_MODE_REL_PINNED);
80         qm_debug_timer_start(NULL, period);
81 }
82
83 static void cancel_hrtimer(struct quadd_cpu_context *cpu_ctx)
84 {
85         hrtimer_cancel(&cpu_ctx->hrtimer);
86         qm_debug_timer_cancel();
87 }
88
89 static void init_hrtimer(struct quadd_cpu_context *cpu_ctx)
90 {
91         hrtimer_init(&cpu_ctx->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
92         cpu_ctx->hrtimer.function = hrtimer_handler;
93 }
94
95 u64 quadd_get_time(void)
96 {
97         struct timespec ts;
98
99         do_posix_clock_monotonic_gettime(&ts);
100         return timespec_to_ns(&ts);
101 }
102
103 static void put_header(void)
104 {
105         int nr_events = 0, max_events = QUADD_MAX_COUNTERS;
106         unsigned int events[QUADD_MAX_COUNTERS];
107         struct quadd_record_data record;
108         struct quadd_header_data *hdr = &record.hdr;
109         struct quadd_parameters *param = &hrt.quadd_ctx->param;
110         unsigned int extra = param->reserved[QUADD_PARAM_IDX_EXTRA];
111         struct quadd_iovec vec;
112         struct quadd_ctx *ctx = hrt.quadd_ctx;
113         struct quadd_event_source_interface *pmu = ctx->pmu;
114         struct quadd_event_source_interface *pl310 = ctx->pl310;
115
116         record.magic = QUADD_RECORD_MAGIC;
117         record.record_type = QUADD_RECORD_TYPE_HEADER;
118
119         hdr->magic = QUADD_HEADER_MAGIC;
120         hdr->version = QUADD_SAMPLES_VERSION;
121
122         hdr->backtrace = param->backtrace;
123         hdr->use_freq = param->use_freq;
124         hdr->system_wide = param->system_wide;
125
126         /* TODO: dynamically */
127 #ifdef QM_DEBUG_SAMPLES_ENABLE
128         hdr->debug_samples = 1;
129 #else
130         hdr->debug_samples = 0;
131 #endif
132
133         hdr->freq = param->freq;
134         hdr->ma_freq = param->ma_freq;
135         hdr->power_rate_freq = param->power_rate_freq;
136
137         hdr->power_rate = hdr->power_rate_freq > 0 ? 1 : 0;
138         hdr->get_mmap = (extra & QUADD_PARAM_IDX_EXTRA_GET_MMAP) ? 1 : 0;
139
140         hdr->reserved = 0;
141         hdr->extra_length = 0;
142
143         if (pmu)
144                 nr_events += pmu->get_current_events(events, max_events);
145
146         if (pl310)
147                 nr_events += pl310->get_current_events(events + nr_events,
148                                                        max_events - nr_events);
149
150         hdr->nr_events = nr_events;
151
152         vec.base = events;
153         vec.len = nr_events * sizeof(events[0]);
154
155         quadd_put_sample(&record, &vec, 1);
156 }
157
158 void quadd_put_sample(struct quadd_record_data *data,
159                       struct quadd_iovec *vec, int vec_count)
160 {
161         struct quadd_comm_data_interface *comm = hrt.quadd_ctx->comm;
162
163         comm->put_sample(data, vec, vec_count);
164         atomic64_inc(&hrt.counter_samples);
165 }
166
167 static int get_sample_data(struct quadd_sample_data *sample,
168                            struct pt_regs *regs,
169                            struct task_struct *task)
170 {
171         unsigned int cpu, flags;
172         struct quadd_ctx *quadd_ctx = hrt.quadd_ctx;
173
174         cpu = quadd_get_processor_id(regs, &flags);
175         sample->cpu = cpu;
176
177         sample->lp_mode =
178                 (flags & QUADD_CPUMODE_TEGRA_POWER_CLUSTER_LP) ? 1 : 0;
179         sample->thumb_mode = (flags & QUADD_CPUMODE_THUMB) ? 1 : 0;
180         sample->user_mode = user_mode(regs) ? 1 : 0;
181
182         sample->ip = instruction_pointer(regs);
183
184         /* For security reasons, hide IPs from the kernel space. */
185         if (!sample->user_mode && !quadd_ctx->collect_kernel_ips)
186                 sample->ip = 0;
187         else
188                 sample->ip = instruction_pointer(regs);
189
190         sample->time = quadd_get_time();
191         sample->reserved = 0;
192         sample->pid = task->pid;
193         sample->in_interrupt = in_interrupt() ? 1 : 0;
194
195         return 0;
196 }
197
198 static int read_source(struct quadd_event_source_interface *source,
199                        struct pt_regs *regs,
200                        struct hrt_event_value *events_vals,
201                        int max_events)
202 {
203         int nr_events, i;
204         u32 prev_val, val, res_val;
205         struct event_data events[QUADD_MAX_COUNTERS];
206
207         if (!source)
208                 return 0;
209
210         max_events = min_t(int, max_events, QUADD_MAX_COUNTERS);
211         nr_events = source->read(events, max_events);
212
213         for (i = 0; i < nr_events; i++) {
214                 struct event_data *s = &events[i];
215
216                 prev_val = s->prev_val;
217                 val = s->val;
218
219                 if (prev_val <= val)
220                         res_val = val - prev_val;
221                 else
222                         res_val = QUADD_U32_MAX - prev_val + val;
223
224                 if (s->event_source == QUADD_EVENT_SOURCE_PL310) {
225                         int nr_active = atomic_read(&hrt.nr_active_all_core);
226                         if (nr_active > 1)
227                                 res_val = res_val / nr_active;
228                 }
229
230                 events_vals[i].event_id = s->event_id;
231                 events_vals[i].value = res_val;
232         }
233
234         return nr_events;
235 }
236
237 static void
238 read_all_sources(struct pt_regs *regs, struct task_struct *task)
239 {
240         u32 state;
241         int i, vec_idx = 0, bt_size = 0;
242         int nr_events = 0, nr_positive_events = 0;
243         struct pt_regs *user_regs;
244         struct quadd_iovec vec[3];
245         struct hrt_event_value events[QUADD_MAX_COUNTERS];
246         u32 events_extra[QUADD_MAX_COUNTERS];
247
248         struct quadd_record_data record_data;
249         struct quadd_sample_data *s = &record_data.sample;
250
251         struct quadd_ctx *ctx = hrt.quadd_ctx;
252         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
253         struct quadd_callchain *cc_data = &cpu_ctx->callchain_data;
254
255         if (!regs)
256                 return;
257
258         if (atomic_read(&cpu_ctx->nr_active) == 0)
259                 return;
260
261         if (!task) {
262                 pid_t pid;
263                 struct pid *pid_s;
264                 struct quadd_thread_data *t_data;
265
266                 t_data = &cpu_ctx->active_thread;
267                 pid = t_data->pid;
268
269                 rcu_read_lock();
270                 pid_s = find_vpid(pid);
271                 if (pid_s)
272                         task = pid_task(pid_s, PIDTYPE_PID);
273                 rcu_read_unlock();
274                 if (!task)
275                         return;
276         }
277
278         if (ctx->pmu && ctx->pmu_info.active)
279                 nr_events += read_source(ctx->pmu, regs,
280                                          events, QUADD_MAX_COUNTERS);
281
282         if (ctx->pl310 && ctx->pl310_info.active)
283                 nr_events += read_source(ctx->pl310, regs,
284                                          events + nr_events,
285                                          QUADD_MAX_COUNTERS - nr_events);
286
287         if (!nr_events)
288                 return;
289
290         if (user_mode(regs))
291                 user_regs = regs;
292         else
293                 user_regs = task_pt_regs(current);
294
295         if (get_sample_data(s, regs, task))
296                 return;
297
298         if (ctx->param.backtrace) {
299                 bt_size = quadd_get_user_callchain(user_regs, cc_data);
300                 if (bt_size > 0) {
301                         vec[vec_idx].base = cc_data->callchain;
302                         vec[vec_idx].len =
303                                 bt_size * sizeof(cc_data->callchain[0]);
304                         vec_idx++;
305                 }
306         }
307         s->callchain_nr = bt_size;
308
309         record_data.magic = QUADD_RECORD_MAGIC;
310         record_data.record_type = QUADD_RECORD_TYPE_SAMPLE;
311
312         s->events_flags = 0;
313         for (i = 0; i < nr_events; i++) {
314                 u32 value = events[i].value;
315                 if (value > 0) {
316                         s->events_flags |= 1 << i;
317                         events_extra[nr_positive_events++] = value;
318                 }
319         }
320
321         if (nr_positive_events == 0)
322                 return;
323
324         vec[vec_idx].base = events_extra;
325         vec[vec_idx].len = nr_positive_events * sizeof(events_extra[0]);
326         vec_idx++;
327
328         state = task->state;
329         if (state) {
330                 s->state = 1;
331                 vec[vec_idx].base = &state;
332                 vec[vec_idx].len = sizeof(state);
333                 vec_idx++;
334         } else {
335                 s->state = 0;
336         }
337
338         quadd_put_sample(&record_data, vec, vec_idx);
339 }
340
341 static inline int
342 is_profile_process(struct task_struct *task)
343 {
344         int i;
345         pid_t pid, profile_pid;
346         struct quadd_ctx *ctx = hrt.quadd_ctx;
347
348         if (!task)
349                 return 0;
350
351         pid = task->tgid;
352
353         for (i = 0; i < ctx->param.nr_pids; i++) {
354                 profile_pid = ctx->param.pids[i];
355                 if (profile_pid == pid)
356                         return 1;
357         }
358         return 0;
359 }
360
361 static int
362 add_active_thread(struct quadd_cpu_context *cpu_ctx, pid_t pid, pid_t tgid)
363 {
364         struct quadd_thread_data *t_data = &cpu_ctx->active_thread;
365
366         if (t_data->pid > 0 ||
367                 atomic_read(&cpu_ctx->nr_active) > 0) {
368                 pr_warn_once("Warning for thread: %d\n", (int)pid);
369                 return 0;
370         }
371
372         t_data->pid = pid;
373         t_data->tgid = tgid;
374         return 1;
375 }
376
377 static int remove_active_thread(struct quadd_cpu_context *cpu_ctx, pid_t pid)
378 {
379         struct quadd_thread_data *t_data = &cpu_ctx->active_thread;
380
381         if (t_data->pid < 0)
382                 return 0;
383
384         if (t_data->pid == pid) {
385                 t_data->pid = -1;
386                 t_data->tgid = -1;
387                 return 1;
388         }
389
390         pr_warn_once("Warning for thread: %d\n", (int)pid);
391         return 0;
392 }
393
394 void __quadd_task_sched_in(struct task_struct *prev,
395                            struct task_struct *task)
396 {
397         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
398         struct quadd_ctx *ctx = hrt.quadd_ctx;
399         struct event_data events[QUADD_MAX_COUNTERS];
400         /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
401
402         if (likely(!hrt.active))
403                 return;
404 /*
405         if (__ratelimit(&ratelimit_state))
406                 pr_info("sch_in, cpu: %d, prev: %u (%u) \t--> curr: %u (%u)\n",
407                         smp_processor_id(), (unsigned int)prev->pid,
408                         (unsigned int)prev->tgid, (unsigned int)task->pid,
409                         (unsigned int)task->tgid);
410 */
411
412         if (is_profile_process(task)) {
413                 add_active_thread(cpu_ctx, task->pid, task->tgid);
414                 atomic_inc(&cpu_ctx->nr_active);
415
416                 if (atomic_read(&cpu_ctx->nr_active) == 1) {
417                         if (ctx->pmu)
418                                 ctx->pmu->start();
419
420                         if (ctx->pl310)
421                                 ctx->pl310->read(events, 1);
422
423                         start_hrtimer(cpu_ctx);
424                         atomic_inc(&hrt.nr_active_all_core);
425                 }
426         }
427 }
428
429 void __quadd_task_sched_out(struct task_struct *prev,
430                             struct task_struct *next)
431 {
432         int n;
433         struct pt_regs *user_regs;
434         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
435         struct quadd_ctx *ctx = hrt.quadd_ctx;
436         /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
437
438         if (likely(!hrt.active))
439                 return;
440 /*
441         if (__ratelimit(&ratelimit_state))
442                 pr_info("sch_out: cpu: %d, prev: %u (%u) \t--> next: %u (%u)\n",
443                         smp_processor_id(), (unsigned int)prev->pid,
444                         (unsigned int)prev->tgid, (unsigned int)next->pid,
445                         (unsigned int)next->tgid);
446 */
447
448         if (is_profile_process(prev)) {
449                 user_regs = task_pt_regs(prev);
450                 if (user_regs)
451                         read_all_sources(user_regs, prev);
452
453                 n = remove_active_thread(cpu_ctx, prev->pid);
454                 atomic_sub(n, &cpu_ctx->nr_active);
455
456                 if (atomic_read(&cpu_ctx->nr_active) == 0) {
457                         cancel_hrtimer(cpu_ctx);
458                         atomic_dec(&hrt.nr_active_all_core);
459
460                         if (ctx->pmu)
461                                 ctx->pmu->stop();
462                 }
463         }
464 }
465
466 void __quadd_event_mmap(struct vm_area_struct *vma)
467 {
468         struct quadd_parameters *param;
469
470         if (likely(!hrt.active))
471                 return;
472
473         if (!is_profile_process(current))
474                 return;
475
476         param = &hrt.quadd_ctx->param;
477         quadd_process_mmap(vma, param->pids[0]);
478 }
479 EXPORT_SYMBOL(__quadd_event_mmap);
480
481 static void reset_cpu_ctx(void)
482 {
483         int cpu_id;
484         struct quadd_cpu_context *cpu_ctx;
485         struct quadd_thread_data *t_data;
486
487         for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
488                 cpu_ctx = per_cpu_ptr(hrt.cpu_ctx, cpu_id);
489                 t_data = &cpu_ctx->active_thread;
490
491                 atomic_set(&cpu_ctx->nr_active, 0);
492
493                 t_data->pid = -1;
494                 t_data->tgid = -1;
495         }
496 }
497
498 int quadd_hrt_start(void)
499 {
500         int err;
501         u64 period;
502         long freq;
503         unsigned int extra;
504         struct quadd_ctx *ctx = hrt.quadd_ctx;
505         struct quadd_parameters *param = &ctx->param;
506
507         freq = ctx->param.freq;
508         freq = max_t(long, QUADD_HRT_MIN_FREQ, freq);
509         period = NSEC_PER_SEC / freq;
510         hrt.sample_period = period;
511
512         if (ctx->param.ma_freq > 0)
513                 hrt.ma_period = MSEC_PER_SEC / ctx->param.ma_freq;
514         else
515                 hrt.ma_period = 0;
516
517         atomic64_set(&hrt.counter_samples, 0);
518
519         reset_cpu_ctx();
520
521         put_header();
522
523         extra = param->reserved[QUADD_PARAM_IDX_EXTRA];
524
525         if (extra & QUADD_PARAM_IDX_EXTRA_GET_MMAP) {
526                 err = quadd_get_current_mmap(param->pids[0]);
527                 if (err) {
528                         pr_err("error: quadd_get_current_mmap\n");
529                         return err;
530                 }
531         }
532
533         if (ctx->pl310)
534                 ctx->pl310->start();
535
536         quadd_ma_start(&hrt);
537
538         hrt.active = 1;
539
540         pr_info("Start hrt: freq/period: %ld/%llu\n", freq, period);
541         return 0;
542 }
543
544 void quadd_hrt_stop(void)
545 {
546         struct quadd_ctx *ctx = hrt.quadd_ctx;
547
548         pr_info("Stop hrt, number of samples: %llu\n",
549                 atomic64_read(&hrt.counter_samples));
550
551         if (ctx->pl310)
552                 ctx->pl310->stop();
553
554         quadd_ma_stop(&hrt);
555
556         hrt.active = 0;
557
558         atomic64_set(&hrt.counter_samples, 0);
559
560         /* reset_cpu_ctx(); */
561 }
562
563 void quadd_hrt_deinit(void)
564 {
565         if (hrt.active)
566                 quadd_hrt_stop();
567
568         free_percpu(hrt.cpu_ctx);
569 }
570
571 void quadd_hrt_get_state(struct quadd_module_state *state)
572 {
573         state->nr_all_samples = atomic64_read(&hrt.counter_samples);
574         state->nr_skipped_samples = 0;
575 }
576
577 struct quadd_hrt_ctx *quadd_hrt_init(struct quadd_ctx *ctx)
578 {
579         int cpu_id;
580         u64 period;
581         long freq;
582         struct quadd_cpu_context *cpu_ctx;
583
584         hrt.quadd_ctx = ctx;
585         hrt.active = 0;
586
587         freq = ctx->param.freq;
588         freq = max_t(long, QUADD_HRT_MIN_FREQ, freq);
589         period = NSEC_PER_SEC / freq;
590         hrt.sample_period = period;
591
592         if (ctx->param.ma_freq > 0)
593                 hrt.ma_period = MSEC_PER_SEC / ctx->param.ma_freq;
594         else
595                 hrt.ma_period = 0;
596
597         atomic64_set(&hrt.counter_samples, 0);
598
599         hrt.cpu_ctx = alloc_percpu(struct quadd_cpu_context);
600         if (!hrt.cpu_ctx)
601                 return ERR_PTR(-ENOMEM);
602
603         for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
604                 cpu_ctx = per_cpu_ptr(hrt.cpu_ctx, cpu_id);
605
606                 atomic_set(&cpu_ctx->nr_active, 0);
607
608                 cpu_ctx->active_thread.pid = -1;
609                 cpu_ctx->active_thread.tgid = -1;
610
611                 init_hrtimer(cpu_ctx);
612         }
613
614         return &hrt;
615 }