misc: tegra-profiler: reduce size of sample
[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.record_type = QUADD_RECORD_TYPE_HEADER;
117
118         hdr->magic = QUADD_HEADER_MAGIC;
119         hdr->version = QUADD_SAMPLES_VERSION;
120
121         hdr->backtrace = param->backtrace;
122         hdr->use_freq = param->use_freq;
123         hdr->system_wide = param->system_wide;
124
125         /* TODO: dynamically */
126 #ifdef QM_DEBUG_SAMPLES_ENABLE
127         hdr->debug_samples = 1;
128 #else
129         hdr->debug_samples = 0;
130 #endif
131
132         hdr->freq = param->freq;
133         hdr->ma_freq = param->ma_freq;
134         hdr->power_rate_freq = param->power_rate_freq;
135
136         hdr->power_rate = hdr->power_rate_freq > 0 ? 1 : 0;
137         hdr->get_mmap = (extra & QUADD_PARAM_IDX_EXTRA_GET_MMAP) ? 1 : 0;
138
139         hdr->reserved = 0;
140         hdr->extra_length = 0;
141
142         if (pmu)
143                 nr_events += pmu->get_current_events(events, max_events);
144
145         if (pl310)
146                 nr_events += pl310->get_current_events(events + nr_events,
147                                                        max_events - nr_events);
148
149         hdr->nr_events = nr_events;
150
151         vec.base = events;
152         vec.len = nr_events * sizeof(events[0]);
153
154         quadd_put_sample(&record, &vec, 1);
155 }
156
157 void quadd_put_sample(struct quadd_record_data *data,
158                       struct quadd_iovec *vec, int vec_count)
159 {
160         struct quadd_comm_data_interface *comm = hrt.quadd_ctx->comm;
161
162         comm->put_sample(data, vec, vec_count);
163         atomic64_inc(&hrt.counter_samples);
164 }
165
166 static int get_sample_data(struct quadd_sample_data *sample,
167                            struct pt_regs *regs,
168                            struct task_struct *task)
169 {
170         unsigned int cpu, flags;
171         struct quadd_ctx *quadd_ctx = hrt.quadd_ctx;
172
173         cpu = quadd_get_processor_id(regs, &flags);
174         sample->cpu = cpu;
175
176         sample->lp_mode =
177                 (flags & QUADD_CPUMODE_TEGRA_POWER_CLUSTER_LP) ? 1 : 0;
178         sample->thumb_mode = (flags & QUADD_CPUMODE_THUMB) ? 1 : 0;
179         sample->user_mode = user_mode(regs) ? 1 : 0;
180
181         sample->ip = instruction_pointer(regs);
182
183         /* For security reasons, hide IPs from the kernel space. */
184         if (!sample->user_mode && !quadd_ctx->collect_kernel_ips)
185                 sample->ip = 0;
186         else
187                 sample->ip = instruction_pointer(regs);
188
189         sample->time = quadd_get_time();
190         sample->reserved = 0;
191         sample->pid = task->pid;
192         sample->in_interrupt = in_interrupt() ? 1 : 0;
193
194         return 0;
195 }
196
197 static int read_source(struct quadd_event_source_interface *source,
198                        struct pt_regs *regs,
199                        struct hrt_event_value *events_vals,
200                        int max_events)
201 {
202         int nr_events, i;
203         u32 prev_val, val, res_val;
204         struct event_data events[QUADD_MAX_COUNTERS];
205
206         if (!source)
207                 return 0;
208
209         max_events = min_t(int, max_events, QUADD_MAX_COUNTERS);
210         nr_events = source->read(events, max_events);
211
212         for (i = 0; i < nr_events; i++) {
213                 struct event_data *s = &events[i];
214
215                 prev_val = s->prev_val;
216                 val = s->val;
217
218                 if (prev_val <= val)
219                         res_val = val - prev_val;
220                 else
221                         res_val = QUADD_U32_MAX - prev_val + val;
222
223                 if (s->event_source == QUADD_EVENT_SOURCE_PL310) {
224                         int nr_active = atomic_read(&hrt.nr_active_all_core);
225                         if (nr_active > 1)
226                                 res_val = res_val / nr_active;
227                 }
228
229                 events_vals[i].event_id = s->event_id;
230                 events_vals[i].value = res_val;
231         }
232
233         return nr_events;
234 }
235
236 static void
237 read_all_sources(struct pt_regs *regs, struct task_struct *task)
238 {
239         u32 state;
240         int i, vec_idx = 0, bt_size = 0;
241         int nr_events = 0, nr_positive_events = 0;
242         struct pt_regs *user_regs;
243         struct quadd_iovec vec[3];
244         struct hrt_event_value events[QUADD_MAX_COUNTERS];
245         u32 events_extra[QUADD_MAX_COUNTERS];
246
247         struct quadd_record_data record_data;
248         struct quadd_sample_data *s = &record_data.sample;
249
250         struct quadd_ctx *ctx = hrt.quadd_ctx;
251         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
252         struct quadd_callchain *cc_data = &cpu_ctx->callchain_data;
253
254         if (!regs)
255                 return;
256
257         if (atomic_read(&cpu_ctx->nr_active) == 0)
258                 return;
259
260         if (!task) {
261                 pid_t pid;
262                 struct pid *pid_s;
263                 struct quadd_thread_data *t_data;
264
265                 t_data = &cpu_ctx->active_thread;
266                 pid = t_data->pid;
267
268                 rcu_read_lock();
269                 pid_s = find_vpid(pid);
270                 if (pid_s)
271                         task = pid_task(pid_s, PIDTYPE_PID);
272                 rcu_read_unlock();
273                 if (!task)
274                         return;
275         }
276
277         if (ctx->pmu && ctx->pmu_info.active)
278                 nr_events += read_source(ctx->pmu, regs,
279                                          events, QUADD_MAX_COUNTERS);
280
281         if (ctx->pl310 && ctx->pl310_info.active)
282                 nr_events += read_source(ctx->pl310, regs,
283                                          events + nr_events,
284                                          QUADD_MAX_COUNTERS - nr_events);
285
286         if (!nr_events)
287                 return;
288
289         if (user_mode(regs))
290                 user_regs = regs;
291         else
292                 user_regs = task_pt_regs(current);
293
294         if (get_sample_data(s, regs, task))
295                 return;
296
297         if (ctx->param.backtrace) {
298                 bt_size = quadd_get_user_callchain(user_regs, cc_data);
299                 if (bt_size > 0) {
300                         vec[vec_idx].base = cc_data->callchain;
301                         vec[vec_idx].len =
302                                 bt_size * sizeof(cc_data->callchain[0]);
303                         vec_idx++;
304                 }
305         }
306         s->callchain_nr = bt_size;
307
308         record_data.record_type = QUADD_RECORD_TYPE_SAMPLE;
309
310         s->events_flags = 0;
311         for (i = 0; i < nr_events; i++) {
312                 u32 value = events[i].value;
313                 if (value > 0) {
314                         s->events_flags |= 1 << i;
315                         events_extra[nr_positive_events++] = value;
316                 }
317         }
318
319         if (nr_positive_events == 0)
320                 return;
321
322         vec[vec_idx].base = events_extra;
323         vec[vec_idx].len = nr_positive_events * sizeof(events_extra[0]);
324         vec_idx++;
325
326         state = task->state;
327         if (state) {
328                 s->state = 1;
329                 vec[vec_idx].base = &state;
330                 vec[vec_idx].len = sizeof(state);
331                 vec_idx++;
332         } else {
333                 s->state = 0;
334         }
335
336         quadd_put_sample(&record_data, vec, vec_idx);
337 }
338
339 static inline int
340 is_profile_process(struct task_struct *task)
341 {
342         int i;
343         pid_t pid, profile_pid;
344         struct quadd_ctx *ctx = hrt.quadd_ctx;
345
346         if (!task)
347                 return 0;
348
349         pid = task->tgid;
350
351         for (i = 0; i < ctx->param.nr_pids; i++) {
352                 profile_pid = ctx->param.pids[i];
353                 if (profile_pid == pid)
354                         return 1;
355         }
356         return 0;
357 }
358
359 static int
360 add_active_thread(struct quadd_cpu_context *cpu_ctx, pid_t pid, pid_t tgid)
361 {
362         struct quadd_thread_data *t_data = &cpu_ctx->active_thread;
363
364         if (t_data->pid > 0 ||
365                 atomic_read(&cpu_ctx->nr_active) > 0) {
366                 pr_warn_once("Warning for thread: %d\n", (int)pid);
367                 return 0;
368         }
369
370         t_data->pid = pid;
371         t_data->tgid = tgid;
372         return 1;
373 }
374
375 static int remove_active_thread(struct quadd_cpu_context *cpu_ctx, pid_t pid)
376 {
377         struct quadd_thread_data *t_data = &cpu_ctx->active_thread;
378
379         if (t_data->pid < 0)
380                 return 0;
381
382         if (t_data->pid == pid) {
383                 t_data->pid = -1;
384                 t_data->tgid = -1;
385                 return 1;
386         }
387
388         pr_warn_once("Warning for thread: %d\n", (int)pid);
389         return 0;
390 }
391
392 void __quadd_task_sched_in(struct task_struct *prev,
393                            struct task_struct *task)
394 {
395         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
396         struct quadd_ctx *ctx = hrt.quadd_ctx;
397         struct event_data events[QUADD_MAX_COUNTERS];
398         /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
399
400         if (likely(!hrt.active))
401                 return;
402 /*
403         if (__ratelimit(&ratelimit_state))
404                 pr_info("sch_in, cpu: %d, prev: %u (%u) \t--> curr: %u (%u)\n",
405                         smp_processor_id(), (unsigned int)prev->pid,
406                         (unsigned int)prev->tgid, (unsigned int)task->pid,
407                         (unsigned int)task->tgid);
408 */
409
410         if (is_profile_process(task)) {
411                 add_active_thread(cpu_ctx, task->pid, task->tgid);
412                 atomic_inc(&cpu_ctx->nr_active);
413
414                 if (atomic_read(&cpu_ctx->nr_active) == 1) {
415                         if (ctx->pmu)
416                                 ctx->pmu->start();
417
418                         if (ctx->pl310)
419                                 ctx->pl310->read(events, 1);
420
421                         start_hrtimer(cpu_ctx);
422                         atomic_inc(&hrt.nr_active_all_core);
423                 }
424         }
425 }
426
427 void __quadd_task_sched_out(struct task_struct *prev,
428                             struct task_struct *next)
429 {
430         int n;
431         struct pt_regs *user_regs;
432         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
433         struct quadd_ctx *ctx = hrt.quadd_ctx;
434         /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
435
436         if (likely(!hrt.active))
437                 return;
438 /*
439         if (__ratelimit(&ratelimit_state))
440                 pr_info("sch_out: cpu: %d, prev: %u (%u) \t--> next: %u (%u)\n",
441                         smp_processor_id(), (unsigned int)prev->pid,
442                         (unsigned int)prev->tgid, (unsigned int)next->pid,
443                         (unsigned int)next->tgid);
444 */
445
446         if (is_profile_process(prev)) {
447                 user_regs = task_pt_regs(prev);
448                 if (user_regs)
449                         read_all_sources(user_regs, prev);
450
451                 n = remove_active_thread(cpu_ctx, prev->pid);
452                 atomic_sub(n, &cpu_ctx->nr_active);
453
454                 if (atomic_read(&cpu_ctx->nr_active) == 0) {
455                         cancel_hrtimer(cpu_ctx);
456                         atomic_dec(&hrt.nr_active_all_core);
457
458                         if (ctx->pmu)
459                                 ctx->pmu->stop();
460                 }
461         }
462 }
463
464 void __quadd_event_mmap(struct vm_area_struct *vma)
465 {
466         struct quadd_parameters *param;
467
468         if (likely(!hrt.active))
469                 return;
470
471         if (!is_profile_process(current))
472                 return;
473
474         param = &hrt.quadd_ctx->param;
475         quadd_process_mmap(vma, param->pids[0]);
476 }
477 EXPORT_SYMBOL(__quadd_event_mmap);
478
479 static void reset_cpu_ctx(void)
480 {
481         int cpu_id;
482         struct quadd_cpu_context *cpu_ctx;
483         struct quadd_thread_data *t_data;
484
485         for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
486                 cpu_ctx = per_cpu_ptr(hrt.cpu_ctx, cpu_id);
487                 t_data = &cpu_ctx->active_thread;
488
489                 atomic_set(&cpu_ctx->nr_active, 0);
490
491                 t_data->pid = -1;
492                 t_data->tgid = -1;
493         }
494 }
495
496 int quadd_hrt_start(void)
497 {
498         int err;
499         u64 period;
500         long freq;
501         unsigned int extra;
502         struct quadd_ctx *ctx = hrt.quadd_ctx;
503         struct quadd_parameters *param = &ctx->param;
504
505         freq = ctx->param.freq;
506         freq = max_t(long, QUADD_HRT_MIN_FREQ, freq);
507         period = NSEC_PER_SEC / freq;
508         hrt.sample_period = period;
509
510         if (ctx->param.ma_freq > 0)
511                 hrt.ma_period = MSEC_PER_SEC / ctx->param.ma_freq;
512         else
513                 hrt.ma_period = 0;
514
515         atomic64_set(&hrt.counter_samples, 0);
516
517         reset_cpu_ctx();
518
519         put_header();
520
521         extra = param->reserved[QUADD_PARAM_IDX_EXTRA];
522
523         if (extra & QUADD_PARAM_IDX_EXTRA_GET_MMAP) {
524                 err = quadd_get_current_mmap(param->pids[0]);
525                 if (err) {
526                         pr_err("error: quadd_get_current_mmap\n");
527                         return err;
528                 }
529         }
530
531         if (ctx->pl310)
532                 ctx->pl310->start();
533
534         quadd_ma_start(&hrt);
535
536         hrt.active = 1;
537
538         pr_info("Start hrt: freq/period: %ld/%llu\n", freq, period);
539         return 0;
540 }
541
542 void quadd_hrt_stop(void)
543 {
544         struct quadd_ctx *ctx = hrt.quadd_ctx;
545
546         pr_info("Stop hrt, number of samples: %llu\n",
547                 atomic64_read(&hrt.counter_samples));
548
549         if (ctx->pl310)
550                 ctx->pl310->stop();
551
552         quadd_ma_stop(&hrt);
553
554         hrt.active = 0;
555
556         atomic64_set(&hrt.counter_samples, 0);
557
558         /* reset_cpu_ctx(); */
559 }
560
561 void quadd_hrt_deinit(void)
562 {
563         if (hrt.active)
564                 quadd_hrt_stop();
565
566         free_percpu(hrt.cpu_ctx);
567 }
568
569 void quadd_hrt_get_state(struct quadd_module_state *state)
570 {
571         state->nr_all_samples = atomic64_read(&hrt.counter_samples);
572         state->nr_skipped_samples = 0;
573 }
574
575 struct quadd_hrt_ctx *quadd_hrt_init(struct quadd_ctx *ctx)
576 {
577         int cpu_id;
578         u64 period;
579         long freq;
580         struct quadd_cpu_context *cpu_ctx;
581
582         hrt.quadd_ctx = ctx;
583         hrt.active = 0;
584
585         freq = ctx->param.freq;
586         freq = max_t(long, QUADD_HRT_MIN_FREQ, freq);
587         period = NSEC_PER_SEC / freq;
588         hrt.sample_period = period;
589
590         if (ctx->param.ma_freq > 0)
591                 hrt.ma_period = MSEC_PER_SEC / ctx->param.ma_freq;
592         else
593                 hrt.ma_period = 0;
594
595         atomic64_set(&hrt.counter_samples, 0);
596
597         hrt.cpu_ctx = alloc_percpu(struct quadd_cpu_context);
598         if (!hrt.cpu_ctx)
599                 return ERR_PTR(-ENOMEM);
600
601         for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
602                 cpu_ctx = per_cpu_ptr(hrt.cpu_ctx, cpu_id);
603
604                 atomic_set(&cpu_ctx->nr_active, 0);
605
606                 cpu_ctx->active_thread.pid = -1;
607                 cpu_ctx->active_thread.tgid = -1;
608
609                 init_hrtimer(cpu_ctx);
610         }
611
612         return &hrt;
613 }