748d24338756c7ca92faea1ca3cc95fe664448a0
[linux-3.10.git] / drivers / misc / tegra-profiler / hrt.c
1 /*
2  * drivers/misc/tegra-profiler/hrt.c
3  *
4  * Copyright (c) 2015-2017, 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/sched.h>
20 #include <linux/hrtimer.h>
21 #include <linux/slab.h>
22 #include <linux/cpu.h>
23 #include <linux/ptrace.h>
24 #include <linux/interrupt.h>
25 #include <linux/err.h>
26 #include <clocksource/arm_arch_timer.h>
27
28 #include <asm/cputype.h>
29 #include <asm/irq_regs.h>
30 #include <asm/arch_timer.h>
31
32 #include <linux/tegra_profiler.h>
33
34 #include "quadd.h"
35 #include "hrt.h"
36 #include "comm.h"
37 #include "mmap.h"
38 #include "ma.h"
39 #include "power_clk.h"
40 #include "tegra.h"
41 #include "debug.h"
42
43 static struct quadd_hrt_ctx hrt;
44
45 static void
46 read_all_sources(struct pt_regs *regs, struct task_struct *task, int is_sched);
47
48 struct hrt_event_value {
49         int event_id;
50         u32 value;
51 };
52
53 static inline u32 get_task_state(struct task_struct *task)
54 {
55         return (u32)(task->state | task->exit_state);
56 }
57
58 static enum hrtimer_restart hrtimer_handler(struct hrtimer *hrtimer)
59 {
60         struct pt_regs *regs;
61
62         regs = get_irq_regs();
63
64         if (!atomic_read(&hrt.active))
65                 return HRTIMER_NORESTART;
66
67         qm_debug_handler_sample(regs);
68
69         if (regs)
70                 read_all_sources(regs, current, 0);
71
72         hrtimer_forward_now(hrtimer, ns_to_ktime(hrt.sample_period));
73         qm_debug_timer_forward(regs, hrt.sample_period);
74
75         return HRTIMER_RESTART;
76 }
77
78 static void start_hrtimer(struct quadd_cpu_context *cpu_ctx)
79 {
80         u64 period = hrt.sample_period;
81
82         __hrtimer_start_range_ns(&cpu_ctx->hrtimer,
83                                  ns_to_ktime(period), 0,
84                                  HRTIMER_MODE_REL_PINNED, 0);
85         qm_debug_timer_start(NULL, period);
86 }
87
88 static void cancel_hrtimer(struct quadd_cpu_context *cpu_ctx)
89 {
90         hrtimer_cancel(&cpu_ctx->hrtimer);
91         qm_debug_timer_cancel();
92 }
93
94 static void init_hrtimer(struct quadd_cpu_context *cpu_ctx)
95 {
96         hrtimer_init(&cpu_ctx->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
97         cpu_ctx->hrtimer.function = hrtimer_handler;
98 }
99
100 static inline u64 get_posix_clock_monotonic_time(void)
101 {
102         struct timespec ts;
103
104         do_posix_clock_monotonic_gettime(&ts);
105         return timespec_to_ns(&ts);
106 }
107
108 static inline u64 get_arch_time(struct timecounter *tc)
109 {
110         cycle_t value;
111         const struct cyclecounter *cc = tc->cc;
112
113         value = cc->read(cc);
114         return cyclecounter_cyc2ns(cc, value);
115 }
116
117 u64 quadd_get_time(void)
118 {
119         struct timecounter *tc = hrt.tc;
120
121         return (tc && hrt.use_arch_timer) ?
122                 get_arch_time(tc) :
123                 get_posix_clock_monotonic_time();
124 }
125
126 static void
127 __put_sample(struct quadd_record_data *data,
128              struct quadd_iovec *vec,
129              int vec_count, int cpu_id)
130 {
131         ssize_t err;
132         struct quadd_comm_data_interface *comm = hrt.quadd_ctx->comm;
133
134         err = comm->put_sample(data, vec, vec_count, cpu_id);
135         if (err < 0)
136                 atomic64_inc(&hrt.skipped_samples);
137
138         atomic64_inc(&hrt.counter_samples);
139 }
140
141 void
142 quadd_put_sample_this_cpu(struct quadd_record_data *data,
143                           struct quadd_iovec *vec, int vec_count)
144 {
145         __put_sample(data, vec, vec_count, -1);
146 }
147
148 void
149 quadd_put_sample(struct quadd_record_data *data,
150                  struct quadd_iovec *vec, int vec_count)
151 {
152         __put_sample(data, vec, vec_count, 0);
153 }
154
155 static void put_header(int cpuid)
156 {
157         int nr_events = 0, max_events = QUADD_MAX_COUNTERS;
158         int events[QUADD_MAX_COUNTERS];
159         struct quadd_record_data record;
160         struct quadd_header_data *hdr = &record.hdr;
161         struct quadd_parameters *param = &hrt.quadd_ctx->param;
162         unsigned int extra = param->reserved[QUADD_PARAM_IDX_EXTRA];
163         struct quadd_iovec vec[2];
164         struct quadd_ctx *ctx = hrt.quadd_ctx;
165         struct quadd_event_source_interface *pmu = ctx->pmu;
166         struct quadd_event_source_interface *pl310 = ctx->pl310;
167         u32 cpuid_data = cpuid;
168
169         record.record_type = QUADD_RECORD_TYPE_HEADER;
170
171         hdr->magic = QUADD_HEADER_MAGIC;
172         hdr->version = QUADD_SAMPLES_VERSION;
173
174         hdr->backtrace = param->backtrace;
175         hdr->use_freq = param->use_freq;
176         hdr->system_wide = param->system_wide;
177
178         /* TODO: dynamically */
179 #ifdef QM_DEBUG_SAMPLES_ENABLE
180         hdr->debug_samples = 1;
181 #else
182         hdr->debug_samples = 0;
183 #endif
184
185         hdr->freq = param->freq;
186         hdr->ma_freq = param->ma_freq;
187         hdr->power_rate_freq = param->power_rate_freq;
188
189         hdr->power_rate = hdr->power_rate_freq > 0 ? 1 : 0;
190         hdr->get_mmap = (extra & QUADD_PARAM_EXTRA_GET_MMAP) ? 1 : 0;
191
192         hdr->reserved = 0;
193         hdr->extra_length = 0;
194
195         if (hdr->backtrace) {
196                 struct quadd_unw_methods *um = &hrt.um;
197
198                 hdr->reserved |= um->fp ? QUADD_HDR_BT_FP : 0;
199                 hdr->reserved |= um->ut ? QUADD_HDR_BT_UT : 0;
200                 hdr->reserved |= um->ut_ce ? QUADD_HDR_BT_UT_CE : 0;
201                 hdr->reserved |= um->dwarf ? QUADD_HDR_BT_DWARF : 0;
202         }
203
204         if (hrt.use_arch_timer)
205                 hdr->reserved |= QUADD_HDR_USE_ARCH_TIMER;
206
207         if (hrt.get_stack_offset)
208                 hdr->reserved |= QUADD_HDR_STACK_OFFSET;
209
210         hdr->reserved |= QUADD_HDR_HAS_CPUID;
211
212         if (pmu)
213                 nr_events += pmu->get_current_events(cpuid, events + nr_events,
214                                                      max_events - nr_events);
215
216         if (pl310)
217                 nr_events += pl310->get_current_events(cpuid,
218                                                        events + nr_events,
219                                                        max_events - nr_events);
220
221         hdr->nr_events = nr_events;
222
223         vec[0].base = events;
224         vec[0].len = nr_events * sizeof(events[0]);
225
226         vec[1].base = &cpuid_data;
227         vec[1].len = sizeof(cpuid_data);
228
229         __put_sample(&record, &vec[0], 2, cpuid);
230 }
231
232 static void
233 put_sched_sample(struct task_struct *task, int is_sched_in)
234 {
235         unsigned int cpu, flags;
236         struct quadd_record_data record;
237         struct quadd_sched_data *s = &record.sched;
238
239         record.record_type = QUADD_RECORD_TYPE_SCHED;
240
241         cpu = quadd_get_processor_id(NULL, &flags);
242         s->cpu = cpu;
243         s->lp_mode = (flags & QUADD_CPUMODE_TEGRA_POWER_CLUSTER_LP) ? 1 : 0;
244
245         s->sched_in = is_sched_in ? 1 : 0;
246         s->time = quadd_get_time();
247         s->pid = task->pid;
248         s->tgid = task->tgid;
249
250         s->reserved = 0;
251
252         s->data[QUADD_SCHED_IDX_TASK_STATE] = get_task_state(task);
253         s->data[QUADD_SCHED_IDX_RESERVED] = 0;
254
255         quadd_put_sample_this_cpu(&record, NULL, 0);
256 }
257
258 static int get_sample_data(struct quadd_sample_data *sample,
259                            struct pt_regs *regs,
260                            struct task_struct *task)
261 {
262         unsigned int cpu, flags;
263         struct quadd_ctx *quadd_ctx = hrt.quadd_ctx;
264
265         cpu = quadd_get_processor_id(regs, &flags);
266         sample->cpu = cpu;
267
268         sample->lp_mode =
269                 (flags & QUADD_CPUMODE_TEGRA_POWER_CLUSTER_LP) ? 1 : 0;
270         sample->thumb_mode = (flags & QUADD_CPUMODE_THUMB) ? 1 : 0;
271         sample->user_mode = user_mode(regs) ? 1 : 0;
272
273         /* For security reasons, hide IPs from the kernel space. */
274         if (!sample->user_mode && !quadd_ctx->collect_kernel_ips)
275                 sample->ip = 0;
276         else
277                 sample->ip = instruction_pointer(regs);
278
279         sample->time = quadd_get_time();
280         sample->reserved = 0;
281         sample->pid = task->pid;
282         sample->tgid = task->tgid;
283         sample->in_interrupt = in_interrupt() ? 1 : 0;
284
285         return 0;
286 }
287
288 static int read_source(struct quadd_event_source_interface *source,
289                        struct pt_regs *regs,
290                        struct hrt_event_value *events_vals,
291                        int max_events)
292 {
293         int nr_events, i;
294         u32 prev_val, val, res_val;
295         struct event_data events[QUADD_MAX_COUNTERS];
296
297         if (!source)
298                 return 0;
299
300         max_events = min_t(int, max_events, QUADD_MAX_COUNTERS);
301         nr_events = source->read(events, max_events);
302
303         for (i = 0; i < nr_events; i++) {
304                 struct event_data *s = &events[i];
305
306                 prev_val = s->prev_val;
307                 val = s->val;
308
309                 if (prev_val <= val)
310                         res_val = val - prev_val;
311                 else
312                         res_val = QUADD_U32_MAX - prev_val + val;
313
314                 if (s->event_source == QUADD_EVENT_SOURCE_PL310) {
315                         int nr_active = atomic_read(&hrt.nr_active_all_core);
316
317                         if (nr_active > 1)
318                                 res_val /= nr_active;
319                 }
320
321                 events_vals[i].event_id = s->event_id;
322                 events_vals[i].value = res_val;
323         }
324
325         return nr_events;
326 }
327
328 static long
329 get_stack_offset(struct task_struct *task,
330                  struct pt_regs *regs,
331                  struct quadd_callchain *cc)
332 {
333         unsigned long sp;
334         struct vm_area_struct *vma;
335         struct mm_struct *mm = task->mm;
336
337         if (!regs || !mm)
338                 return -ENOMEM;
339
340         sp = cc->nr > 0 ? cc->curr_sp :
341                 quadd_user_stack_pointer(regs);
342
343         vma = find_vma(mm, sp);
344         if (!vma)
345                 return -ENOMEM;
346
347         return vma->vm_end - sp;
348 }
349
350 static void
351 read_all_sources(struct pt_regs *regs, struct task_struct *task, int is_sched)
352 {
353         u32 state, extra_data = 0, urcs = 0;
354         int i, vec_idx = 0, bt_size = 0;
355         int nr_events = 0, nr_positive_events = 0;
356         struct pt_regs *user_regs;
357         struct quadd_iovec vec[6];
358         struct hrt_event_value events[QUADD_MAX_COUNTERS];
359         u32 events_extra[QUADD_MAX_COUNTERS];
360         struct quadd_event_context event_ctx;
361
362         struct quadd_record_data record_data;
363         struct quadd_sample_data *s = &record_data.sample;
364
365         struct quadd_ctx *ctx = hrt.quadd_ctx;
366         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
367         struct quadd_callchain *cc = &cpu_ctx->cc;
368
369         if (atomic_read(&cpu_ctx->nr_active) == 0)
370                 return;
371
372         if (task->flags & PF_EXITING)
373                 return;
374
375         if (ctx->pmu && ctx->get_pmu_info()->active)
376                 nr_events += read_source(ctx->pmu, regs,
377                                          events, QUADD_MAX_COUNTERS);
378
379         if (ctx->pl310 && ctx->pl310_info.active)
380                 nr_events += read_source(ctx->pl310, regs,
381                                          events + nr_events,
382                                          QUADD_MAX_COUNTERS - nr_events);
383
384         if (!nr_events)
385                 return;
386
387         if (user_mode(regs))
388                 user_regs = regs;
389         else
390                 user_regs = current_pt_regs();
391
392         if (get_sample_data(s, regs, task))
393                 return;
394
395         vec[vec_idx].base = &extra_data;
396         vec[vec_idx].len = sizeof(extra_data);
397         vec_idx++;
398
399         s->reserved = 0;
400         cc->nr = 0;
401
402         event_ctx.regs = user_regs;
403         event_ctx.task = task;
404         event_ctx.user_mode = user_mode(regs);
405         event_ctx.is_sched = is_sched;
406
407         if (ctx->param.backtrace) {
408                 cc->um = hrt.um;
409
410                 bt_size = quadd_get_user_callchain(&event_ctx, cc, ctx);
411                 if (bt_size > 0) {
412                         int ip_size = cc->cs_64 ? sizeof(u64) : sizeof(u32);
413                         int nr_types = DIV_ROUND_UP(bt_size, 8);
414
415                         vec[vec_idx].base = cc->cs_64 ?
416                                 (void *)cc->ip_64 : (void *)cc->ip_32;
417                         vec[vec_idx].len = bt_size * ip_size;
418                         vec_idx++;
419
420                         vec[vec_idx].base = cc->types;
421                         vec[vec_idx].len = nr_types * sizeof(cc->types[0]);
422                         vec_idx++;
423
424                         if (cc->cs_64)
425                                 extra_data |= QUADD_SED_IP64;
426                 }
427
428                 urcs |= (cc->urc_fp & QUADD_SAMPLE_URC_MASK) <<
429                         QUADD_SAMPLE_URC_SHIFT_FP;
430                 urcs |= (cc->urc_ut & QUADD_SAMPLE_URC_MASK) <<
431                         QUADD_SAMPLE_URC_SHIFT_UT;
432                 urcs |= (cc->urc_dwarf & QUADD_SAMPLE_URC_MASK) <<
433                         QUADD_SAMPLE_URC_SHIFT_DWARF;
434
435                 s->reserved |= QUADD_SAMPLE_RES_URCS_ENABLED;
436
437                 vec[vec_idx].base = &urcs;
438                 vec[vec_idx].len = sizeof(urcs);
439                 vec_idx++;
440         }
441         s->callchain_nr = bt_size;
442
443         if (hrt.get_stack_offset) {
444                 long offset = get_stack_offset(task, user_regs, cc);
445
446                 if (offset > 0) {
447                         u32 off = offset >> 2;
448
449                         off = min_t(u32, off, 0xffff);
450                         extra_data |= off << QUADD_SED_STACK_OFFSET_SHIFT;
451                 }
452         }
453
454         record_data.record_type = QUADD_RECORD_TYPE_SAMPLE;
455
456         s->events_flags = 0;
457         for (i = 0; i < nr_events; i++) {
458                 u32 value = events[i].value;
459
460                 if (value > 0) {
461                         s->events_flags |= 1 << i;
462                         events_extra[nr_positive_events++] = value;
463                 }
464         }
465
466         if (nr_positive_events == 0)
467                 return;
468
469         vec[vec_idx].base = events_extra;
470         vec[vec_idx].len = nr_positive_events * sizeof(events_extra[0]);
471         vec_idx++;
472
473         state = get_task_state(task);
474         if (state) {
475                 s->state = 1;
476                 vec[vec_idx].base = &state;
477                 vec[vec_idx].len = sizeof(state);
478                 vec_idx++;
479         } else {
480                 s->state = 0;
481         }
482
483         quadd_put_sample_this_cpu(&record_data, vec, vec_idx);
484 }
485
486 static inline int
487 is_sample_process(struct task_struct *task)
488 {
489         int i;
490         pid_t pid, profile_pid;
491         struct quadd_ctx *ctx = hrt.quadd_ctx;
492
493         if (!task)
494                 return 0;
495
496         pid = task->tgid;
497
498         for (i = 0; i < ctx->param.nr_pids; i++) {
499                 profile_pid = ctx->param.pids[i];
500                 if (profile_pid == pid)
501                         return 1;
502         }
503         return 0;
504 }
505
506 static inline int
507 is_swapper_task(struct task_struct *task)
508 {
509         if (task->pid == 0)
510                 return 1;
511
512         return 0;
513 }
514
515 static inline int
516 is_trace_process(struct task_struct *task)
517 {
518         struct quadd_ctx *ctx = hrt.quadd_ctx;
519
520         if (!task)
521                 return 0;
522
523         if (is_swapper_task(task))
524                 return 0;
525
526         if (ctx->param.trace_all_tasks)
527                 return 1;
528
529         return is_sample_process(task);
530 }
531
532 static int
533 add_active_thread(struct quadd_cpu_context *cpu_ctx, pid_t pid, pid_t tgid)
534 {
535         struct quadd_thread_data *t_data = &cpu_ctx->active_thread;
536
537         if (t_data->pid > 0 ||
538                 atomic_read(&cpu_ctx->nr_active) > 0) {
539                 pr_warn_once("Warning for thread: %d\n", (int)pid);
540                 return 0;
541         }
542
543         t_data->pid = pid;
544         t_data->tgid = tgid;
545         return 1;
546 }
547
548 static int remove_active_thread(struct quadd_cpu_context *cpu_ctx, pid_t pid)
549 {
550         struct quadd_thread_data *t_data = &cpu_ctx->active_thread;
551
552         if (t_data->pid < 0)
553                 return 0;
554
555         if (t_data->pid == pid) {
556                 t_data->pid = -1;
557                 t_data->tgid = -1;
558                 return 1;
559         }
560
561         pr_warn_once("Warning for thread: %d\n", (int)pid);
562         return 0;
563 }
564
565 void __quadd_task_sched_in(struct task_struct *prev,
566                            struct task_struct *task)
567 {
568         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
569         struct quadd_ctx *ctx = hrt.quadd_ctx;
570         struct event_data events[QUADD_MAX_COUNTERS];
571         /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
572
573         if (likely(!atomic_read(&hrt.active)))
574                 return;
575 /*
576         if (__ratelimit(&ratelimit_state))
577                 pr_info("sch_in, cpu: %d, prev: %u (%u) \t--> curr: %u (%u)\n",
578                         smp_processor_id(), (unsigned int)prev->pid,
579                         (unsigned int)prev->tgid, (unsigned int)task->pid,
580                         (unsigned int)task->tgid);
581 */
582
583         if (is_trace_process(task))
584                 put_sched_sample(task, 1);
585
586         if (is_sample_process(task)) {
587                 add_active_thread(cpu_ctx, task->pid, task->tgid);
588                 atomic_inc(&cpu_ctx->nr_active);
589
590                 if (atomic_read(&cpu_ctx->nr_active) == 1) {
591                         if (ctx->pmu)
592                                 ctx->pmu->start();
593
594                         if (ctx->pl310)
595                                 ctx->pl310->read(events, 1);
596
597                         start_hrtimer(cpu_ctx);
598                         atomic_inc(&hrt.nr_active_all_core);
599                 }
600         }
601 }
602
603 void __quadd_task_sched_out(struct task_struct *prev,
604                             struct task_struct *next)
605 {
606         int n;
607         struct pt_regs *user_regs;
608         struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
609         struct quadd_ctx *ctx = hrt.quadd_ctx;
610         /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
611
612         if (likely(!atomic_read(&hrt.active)))
613                 return;
614 /*
615         if (__ratelimit(&ratelimit_state))
616                 pr_info("sch_out: cpu: %d, prev: %u (%u) \t--> next: %u (%u)\n",
617                         smp_processor_id(), (unsigned int)prev->pid,
618                         (unsigned int)prev->tgid, (unsigned int)next->pid,
619                         (unsigned int)next->tgid);
620 */
621
622         if (is_sample_process(prev)) {
623                 user_regs = task_pt_regs(prev);
624                 if (user_regs)
625                         read_all_sources(user_regs, prev, 1);
626
627                 n = remove_active_thread(cpu_ctx, prev->pid);
628                 atomic_sub(n, &cpu_ctx->nr_active);
629
630                 if (n && atomic_read(&cpu_ctx->nr_active) == 0) {
631                         cancel_hrtimer(cpu_ctx);
632                         atomic_dec(&hrt.nr_active_all_core);
633
634                         if (ctx->pmu)
635                                 ctx->pmu->stop();
636                 }
637         }
638
639         if (is_trace_process(prev))
640                 put_sched_sample(prev, 0);
641 }
642
643 void __quadd_event_mmap(struct vm_area_struct *vma)
644 {
645         struct quadd_parameters *param;
646
647         if (likely(!atomic_read(&hrt.active)))
648                 return;
649
650         if (!is_sample_process(current))
651                 return;
652
653         param = &hrt.quadd_ctx->param;
654         quadd_process_mmap(vma, param->pids[0]);
655 }
656
657 static void reset_cpu_ctx(void)
658 {
659         int cpu_id;
660         struct quadd_cpu_context *cpu_ctx;
661         struct quadd_thread_data *t_data;
662
663         for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
664                 cpu_ctx = per_cpu_ptr(hrt.cpu_ctx, cpu_id);
665                 t_data = &cpu_ctx->active_thread;
666
667                 atomic_set(&cpu_ctx->nr_active, 0);
668
669                 t_data->pid = -1;
670                 t_data->tgid = -1;
671         }
672 }
673
674 int quadd_hrt_start(void)
675 {
676         int err;
677         int cpuid;
678         u64 period;
679         long freq;
680         unsigned int extra;
681         struct quadd_ctx *ctx = hrt.quadd_ctx;
682         struct quadd_parameters *param = &ctx->param;
683
684         freq = ctx->param.freq;
685         freq = max_t(long, QUADD_HRT_MIN_FREQ, freq);
686         period = NSEC_PER_SEC / freq;
687         hrt.sample_period = period;
688
689         if (ctx->param.ma_freq > 0)
690                 hrt.ma_period = MSEC_PER_SEC / ctx->param.ma_freq;
691         else
692                 hrt.ma_period = 0;
693
694         atomic64_set(&hrt.counter_samples, 0);
695         atomic64_set(&hrt.skipped_samples, 0);
696
697         reset_cpu_ctx();
698
699         extra = param->reserved[QUADD_PARAM_IDX_EXTRA];
700
701         if (param->backtrace) {
702                 struct quadd_unw_methods *um = &hrt.um;
703
704                 um->fp = extra & QUADD_PARAM_EXTRA_BT_FP ? 1 : 0;
705                 um->ut = extra & QUADD_PARAM_EXTRA_BT_UT ? 1 : 0;
706                 um->ut_ce = extra & QUADD_PARAM_EXTRA_BT_UT_CE ? 1 : 0;
707                 um->dwarf = extra & QUADD_PARAM_EXTRA_BT_DWARF ? 1 : 0;
708
709                 pr_info("unw methods: fp/ut/ut_ce/dwarf: %u/%u/%u/%u\n",
710                         um->fp, um->ut, um->ut_ce, um->dwarf);
711         }
712
713         if (hrt.tc && (extra & QUADD_PARAM_EXTRA_USE_ARCH_TIMER))
714                 hrt.use_arch_timer = 1;
715         else
716                 hrt.use_arch_timer = 0;
717
718         pr_info("timer: %s\n", hrt.use_arch_timer ? "arch" : "monotonic clock");
719
720         hrt.get_stack_offset =
721                 (extra & QUADD_PARAM_EXTRA_STACK_OFFSET) ? 1 : 0;
722
723         for_each_possible_cpu(cpuid)
724                 put_header(cpuid);
725
726         if (extra & QUADD_PARAM_EXTRA_GET_MMAP) {
727                 err = quadd_get_current_mmap(param->pids[0]);
728                 if (err) {
729                         pr_err("error: quadd_get_current_mmap\n");
730                         return err;
731                 }
732         }
733
734         if (ctx->pl310)
735                 ctx->pl310->start();
736
737         quadd_ma_start(&hrt);
738
739         atomic_set(&hrt.active, 1);
740
741         pr_info("Start hrt: freq/period: %ld/%llu\n", freq, period);
742         return 0;
743 }
744
745 void quadd_hrt_stop(void)
746 {
747         struct quadd_ctx *ctx = hrt.quadd_ctx;
748
749         pr_info("Stop hrt, samples all/skipped: %lld/%lld\n",
750                 (long long)atomic64_read(&hrt.counter_samples),
751                 (long long)atomic64_read(&hrt.skipped_samples));
752
753         if (ctx->pl310)
754                 ctx->pl310->stop();
755
756         quadd_ma_stop(&hrt);
757
758         atomic_set(&hrt.active, 0);
759
760         atomic64_set(&hrt.counter_samples, 0);
761         atomic64_set(&hrt.skipped_samples, 0);
762
763         /* reset_cpu_ctx(); */
764 }
765
766 void quadd_hrt_deinit(void)
767 {
768         if (atomic_read(&hrt.active))
769                 quadd_hrt_stop();
770
771         free_percpu(hrt.cpu_ctx);
772 }
773
774 void quadd_hrt_get_state(struct quadd_module_state *state)
775 {
776         state->nr_all_samples = atomic64_read(&hrt.counter_samples);
777         state->nr_skipped_samples = atomic64_read(&hrt.skipped_samples);
778 }
779
780 static void init_arch_timer(void)
781 {
782         u32 cntkctl = arch_timer_get_cntkctl();
783
784         if (cntkctl & ARCH_TIMER_USR_VCT_ACCESS_EN)
785                 hrt.tc = arch_timer_get_timecounter();
786         else
787                 hrt.tc = NULL;
788 }
789
790 struct quadd_hrt_ctx *quadd_hrt_init(struct quadd_ctx *ctx)
791 {
792         int cpu_id;
793         u64 period;
794         long freq;
795         struct quadd_cpu_context *cpu_ctx;
796
797         hrt.quadd_ctx = ctx;
798         atomic_set(&hrt.active, 0);
799
800         freq = ctx->param.freq;
801         freq = max_t(long, QUADD_HRT_MIN_FREQ, freq);
802         period = NSEC_PER_SEC / freq;
803         hrt.sample_period = period;
804
805         if (ctx->param.ma_freq > 0)
806                 hrt.ma_period = MSEC_PER_SEC / ctx->param.ma_freq;
807         else
808                 hrt.ma_period = 0;
809
810         atomic64_set(&hrt.counter_samples, 0);
811         init_arch_timer();
812
813         hrt.cpu_ctx = alloc_percpu(struct quadd_cpu_context);
814         if (!hrt.cpu_ctx)
815                 return ERR_PTR(-ENOMEM);
816
817         for_each_possible_cpu(cpu_id) {
818                 cpu_ctx = per_cpu_ptr(hrt.cpu_ctx, cpu_id);
819
820                 atomic_set(&cpu_ctx->nr_active, 0);
821
822                 cpu_ctx->active_thread.pid = -1;
823                 cpu_ctx->active_thread.tgid = -1;
824
825                 cpu_ctx->cc.hrt = &hrt;
826
827                 init_hrtimer(cpu_ctx);
828         }
829
830         return &hrt;
831 }