1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * ring buffer based function tracer
4 *
5 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
6 * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
7 *
8 * Based on code from the latency_tracer, that is:
9 *
10 * Copyright (C) 2004-2006 Ingo Molnar
11 * Copyright (C) 2004 Nadia Yvette Chambers
12 */
13 #include <linux/ring_buffer.h>
14 #include <linux/debugfs.h>
15 #include <linux/uaccess.h>
16 #include <linux/ftrace.h>
17 #include <linux/slab.h>
18 #include <linux/fs.h>
19
20 #include "trace.h"
21
22 static void tracing_start_function_trace(struct trace_array *tr);
23 static void tracing_stop_function_trace(struct trace_array *tr);
24 static void
25 function_trace_call(unsigned long ip, unsigned long parent_ip,
26 struct ftrace_ops *op, struct ftrace_regs *fregs);
27 static void
28 function_args_trace_call(unsigned long ip, unsigned long parent_ip,
29 struct ftrace_ops *op, struct ftrace_regs *fregs);
30 static void
31 function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
32 struct ftrace_ops *op, struct ftrace_regs *fregs);
33 static void
34 function_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
35 struct ftrace_ops *op, struct ftrace_regs *fregs);
36 static void
37 function_stack_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
38 struct ftrace_ops *op,
39 struct ftrace_regs *fregs);
40 static struct tracer_flags func_flags;
41
42 /* Our option */
43 enum {
44
45 TRACE_FUNC_NO_OPTS = 0x0, /* No flags set. */
46 TRACE_FUNC_OPT_STACK = 0x1,
47 TRACE_FUNC_OPT_NO_REPEATS = 0x2,
48 TRACE_FUNC_OPT_ARGS = 0x4,
49
50 /* Update this to next highest bit. */
51 TRACE_FUNC_OPT_HIGHEST_BIT = 0x8
52 };
53
54 #define TRACE_FUNC_OPT_MASK (TRACE_FUNC_OPT_HIGHEST_BIT - 1)
55
ftrace_allocate_ftrace_ops(struct trace_array * tr)56 int ftrace_allocate_ftrace_ops(struct trace_array *tr)
57 {
58 struct ftrace_ops *ops;
59
60 /* The top level array uses the "global_ops" */
61 if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
62 return 0;
63
64 ops = kzalloc(sizeof(*ops), GFP_KERNEL);
65 if (!ops)
66 return -ENOMEM;
67
68 /* Currently only the non stack version is supported */
69 ops->func = function_trace_call;
70 ops->flags = FTRACE_OPS_FL_PID;
71
72 tr->ops = ops;
73 ops->private = tr;
74
75 return 0;
76 }
77
ftrace_free_ftrace_ops(struct trace_array * tr)78 void ftrace_free_ftrace_ops(struct trace_array *tr)
79 {
80 kfree(tr->ops);
81 tr->ops = NULL;
82 }
83
ftrace_create_function_files(struct trace_array * tr,struct dentry * parent)84 int ftrace_create_function_files(struct trace_array *tr,
85 struct dentry *parent)
86 {
87 int ret;
88 /*
89 * The top level array uses the "global_ops", and the files are
90 * created on boot up.
91 */
92 if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
93 return 0;
94
95 if (!tr->ops)
96 return -EINVAL;
97
98 ret = allocate_fgraph_ops(tr, tr->ops);
99 if (ret) {
100 kfree(tr->ops);
101 return ret;
102 }
103
104 ftrace_create_filter_files(tr->ops, parent);
105
106 return 0;
107 }
108
ftrace_destroy_function_files(struct trace_array * tr)109 void ftrace_destroy_function_files(struct trace_array *tr)
110 {
111 ftrace_destroy_filter_files(tr->ops);
112 ftrace_free_ftrace_ops(tr);
113 free_fgraph_ops(tr);
114 }
115
select_trace_function(u32 flags_val)116 static ftrace_func_t select_trace_function(u32 flags_val)
117 {
118 switch (flags_val & TRACE_FUNC_OPT_MASK) {
119 case TRACE_FUNC_NO_OPTS:
120 return function_trace_call;
121 case TRACE_FUNC_OPT_ARGS:
122 return function_args_trace_call;
123 case TRACE_FUNC_OPT_STACK:
124 return function_stack_trace_call;
125 case TRACE_FUNC_OPT_NO_REPEATS:
126 return function_no_repeats_trace_call;
127 case TRACE_FUNC_OPT_STACK | TRACE_FUNC_OPT_NO_REPEATS:
128 return function_stack_no_repeats_trace_call;
129 default:
130 return NULL;
131 }
132 }
133
handle_func_repeats(struct trace_array * tr,u32 flags_val)134 static bool handle_func_repeats(struct trace_array *tr, u32 flags_val)
135 {
136 if (!tr->last_func_repeats &&
137 (flags_val & TRACE_FUNC_OPT_NO_REPEATS)) {
138 tr->last_func_repeats = alloc_percpu(struct trace_func_repeats);
139 if (!tr->last_func_repeats)
140 return false;
141 }
142
143 return true;
144 }
145
function_trace_init(struct trace_array * tr)146 static int function_trace_init(struct trace_array *tr)
147 {
148 ftrace_func_t func;
149 /*
150 * Instance trace_arrays get their ops allocated
151 * at instance creation. Unless it failed
152 * the allocation.
153 */
154 if (!tr->ops)
155 return -ENOMEM;
156
157 func = select_trace_function(func_flags.val);
158 if (!func)
159 return -EINVAL;
160
161 if (!handle_func_repeats(tr, func_flags.val))
162 return -ENOMEM;
163
164 ftrace_init_array_ops(tr, func);
165
166 tr->array_buffer.cpu = raw_smp_processor_id();
167
168 tracing_start_cmdline_record();
169 tracing_start_function_trace(tr);
170 return 0;
171 }
172
function_trace_reset(struct trace_array * tr)173 static void function_trace_reset(struct trace_array *tr)
174 {
175 tracing_stop_function_trace(tr);
176 tracing_stop_cmdline_record();
177 ftrace_reset_array_ops(tr);
178 }
179
function_trace_start(struct trace_array * tr)180 static void function_trace_start(struct trace_array *tr)
181 {
182 tracing_reset_online_cpus(&tr->array_buffer);
183 }
184
185 /* fregs are guaranteed not to be NULL if HAVE_DYNAMIC_FTRACE_WITH_ARGS is set */
186 #if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS)
187 static __always_inline unsigned long
function_get_true_parent_ip(unsigned long parent_ip,struct ftrace_regs * fregs)188 function_get_true_parent_ip(unsigned long parent_ip, struct ftrace_regs *fregs)
189 {
190 unsigned long true_parent_ip;
191 int idx = 0;
192
193 true_parent_ip = parent_ip;
194 if (unlikely(parent_ip == (unsigned long)&return_to_handler) && fregs)
195 true_parent_ip = ftrace_graph_ret_addr(current, &idx, parent_ip,
196 (unsigned long *)ftrace_regs_get_stack_pointer(fregs));
197 return true_parent_ip;
198 }
199 #else
200 static __always_inline unsigned long
function_get_true_parent_ip(unsigned long parent_ip,struct ftrace_regs * fregs)201 function_get_true_parent_ip(unsigned long parent_ip, struct ftrace_regs *fregs)
202 {
203 return parent_ip;
204 }
205 #endif
206
207 static void
function_trace_call(unsigned long ip,unsigned long parent_ip,struct ftrace_ops * op,struct ftrace_regs * fregs)208 function_trace_call(unsigned long ip, unsigned long parent_ip,
209 struct ftrace_ops *op, struct ftrace_regs *fregs)
210 {
211 struct trace_array *tr = op->private;
212 unsigned int trace_ctx;
213 int bit;
214
215 if (unlikely(!tr->function_enabled))
216 return;
217
218 bit = ftrace_test_recursion_trylock(ip, parent_ip);
219 if (bit < 0)
220 return;
221
222 parent_ip = function_get_true_parent_ip(parent_ip, fregs);
223
224 trace_ctx = tracing_gen_ctx_dec();
225
226 trace_function(tr, ip, parent_ip, trace_ctx, NULL);
227
228 ftrace_test_recursion_unlock(bit);
229 }
230
231 static void
function_args_trace_call(unsigned long ip,unsigned long parent_ip,struct ftrace_ops * op,struct ftrace_regs * fregs)232 function_args_trace_call(unsigned long ip, unsigned long parent_ip,
233 struct ftrace_ops *op, struct ftrace_regs *fregs)
234 {
235 struct trace_array *tr = op->private;
236 unsigned int trace_ctx;
237 int bit;
238
239 if (unlikely(!tr->function_enabled))
240 return;
241
242 bit = ftrace_test_recursion_trylock(ip, parent_ip);
243 if (bit < 0)
244 return;
245
246 trace_ctx = tracing_gen_ctx();
247
248 trace_function(tr, ip, parent_ip, trace_ctx, fregs);
249
250 ftrace_test_recursion_unlock(bit);
251 }
252
253 #ifdef CONFIG_UNWINDER_ORC
254 /*
255 * Skip 2:
256 *
257 * function_stack_trace_call()
258 * ftrace_call()
259 */
260 #define STACK_SKIP 2
261 #else
262 /*
263 * Skip 3:
264 * __trace_stack()
265 * function_stack_trace_call()
266 * ftrace_call()
267 */
268 #define STACK_SKIP 3
269 #endif
270
271 static void
function_stack_trace_call(unsigned long ip,unsigned long parent_ip,struct ftrace_ops * op,struct ftrace_regs * fregs)272 function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
273 struct ftrace_ops *op, struct ftrace_regs *fregs)
274 {
275 struct trace_array *tr = op->private;
276 struct trace_array_cpu *data;
277 unsigned long flags;
278 long disabled;
279 int cpu;
280 unsigned int trace_ctx;
281 int skip = STACK_SKIP;
282
283 if (unlikely(!tr->function_enabled))
284 return;
285
286 /*
287 * Need to use raw, since this must be called before the
288 * recursive protection is performed.
289 */
290 local_irq_save(flags);
291 parent_ip = function_get_true_parent_ip(parent_ip, fregs);
292 cpu = raw_smp_processor_id();
293 data = per_cpu_ptr(tr->array_buffer.data, cpu);
294 disabled = local_inc_return(&data->disabled);
295
296 if (likely(disabled == 1)) {
297 trace_ctx = tracing_gen_ctx_flags(flags);
298 trace_function(tr, ip, parent_ip, trace_ctx, NULL);
299 #ifdef CONFIG_UNWINDER_FRAME_POINTER
300 if (ftrace_pids_enabled(op))
301 skip++;
302 #endif
303 __trace_stack(tr, trace_ctx, skip);
304 }
305
306 local_dec(&data->disabled);
307 local_irq_restore(flags);
308 }
309
is_repeat_check(struct trace_array * tr,struct trace_func_repeats * last_info,unsigned long ip,unsigned long parent_ip)310 static inline bool is_repeat_check(struct trace_array *tr,
311 struct trace_func_repeats *last_info,
312 unsigned long ip, unsigned long parent_ip)
313 {
314 if (last_info->ip == ip &&
315 last_info->parent_ip == parent_ip &&
316 last_info->count < U16_MAX) {
317 last_info->ts_last_call =
318 ring_buffer_time_stamp(tr->array_buffer.buffer);
319 last_info->count++;
320 return true;
321 }
322
323 return false;
324 }
325
process_repeats(struct trace_array * tr,unsigned long ip,unsigned long parent_ip,struct trace_func_repeats * last_info,unsigned int trace_ctx)326 static inline void process_repeats(struct trace_array *tr,
327 unsigned long ip, unsigned long parent_ip,
328 struct trace_func_repeats *last_info,
329 unsigned int trace_ctx)
330 {
331 if (last_info->count) {
332 trace_last_func_repeats(tr, last_info, trace_ctx);
333 last_info->count = 0;
334 }
335
336 last_info->ip = ip;
337 last_info->parent_ip = parent_ip;
338 }
339
340 static void
function_no_repeats_trace_call(unsigned long ip,unsigned long parent_ip,struct ftrace_ops * op,struct ftrace_regs * fregs)341 function_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
342 struct ftrace_ops *op,
343 struct ftrace_regs *fregs)
344 {
345 struct trace_func_repeats *last_info;
346 struct trace_array *tr = op->private;
347 unsigned int trace_ctx;
348 int bit;
349
350 if (unlikely(!tr->function_enabled))
351 return;
352
353 bit = ftrace_test_recursion_trylock(ip, parent_ip);
354 if (bit < 0)
355 return;
356
357 parent_ip = function_get_true_parent_ip(parent_ip, fregs);
358 if (!tracer_tracing_is_on(tr))
359 goto out;
360
361 /*
362 * An interrupt may happen at any place here. But as far as I can see,
363 * the only damage that this can cause is to mess up the repetition
364 * counter without valuable data being lost.
365 * TODO: think about a solution that is better than just hoping to be
366 * lucky.
367 */
368 last_info = this_cpu_ptr(tr->last_func_repeats);
369 if (is_repeat_check(tr, last_info, ip, parent_ip))
370 goto out;
371
372 trace_ctx = tracing_gen_ctx_dec();
373 process_repeats(tr, ip, parent_ip, last_info, trace_ctx);
374
375 trace_function(tr, ip, parent_ip, trace_ctx, NULL);
376
377 out:
378 ftrace_test_recursion_unlock(bit);
379 }
380
381 static void
function_stack_no_repeats_trace_call(unsigned long ip,unsigned long parent_ip,struct ftrace_ops * op,struct ftrace_regs * fregs)382 function_stack_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
383 struct ftrace_ops *op,
384 struct ftrace_regs *fregs)
385 {
386 struct trace_func_repeats *last_info;
387 struct trace_array *tr = op->private;
388 struct trace_array_cpu *data;
389 unsigned long flags;
390 long disabled;
391 int cpu;
392 unsigned int trace_ctx;
393
394 if (unlikely(!tr->function_enabled))
395 return;
396
397 /*
398 * Need to use raw, since this must be called before the
399 * recursive protection is performed.
400 */
401 local_irq_save(flags);
402 parent_ip = function_get_true_parent_ip(parent_ip, fregs);
403 cpu = raw_smp_processor_id();
404 data = per_cpu_ptr(tr->array_buffer.data, cpu);
405 disabled = local_inc_return(&data->disabled);
406
407 if (likely(disabled == 1)) {
408 last_info = per_cpu_ptr(tr->last_func_repeats, cpu);
409 if (is_repeat_check(tr, last_info, ip, parent_ip))
410 goto out;
411
412 trace_ctx = tracing_gen_ctx_flags(flags);
413 process_repeats(tr, ip, parent_ip, last_info, trace_ctx);
414
415 trace_function(tr, ip, parent_ip, trace_ctx, NULL);
416 __trace_stack(tr, trace_ctx, STACK_SKIP);
417 }
418
419 out:
420 local_dec(&data->disabled);
421 local_irq_restore(flags);
422 }
423
424 static struct tracer_opt func_opts[] = {
425 #ifdef CONFIG_STACKTRACE
426 { TRACER_OPT(func_stack_trace, TRACE_FUNC_OPT_STACK) },
427 #endif
428 { TRACER_OPT(func-no-repeats, TRACE_FUNC_OPT_NO_REPEATS) },
429 #ifdef CONFIG_FUNCTION_TRACE_ARGS
430 { TRACER_OPT(func-args, TRACE_FUNC_OPT_ARGS) },
431 #endif
432 { } /* Always set a last empty entry */
433 };
434
435 static struct tracer_flags func_flags = {
436 .val = TRACE_FUNC_NO_OPTS, /* By default: all flags disabled */
437 .opts = func_opts
438 };
439
tracing_start_function_trace(struct trace_array * tr)440 static void tracing_start_function_trace(struct trace_array *tr)
441 {
442 tr->function_enabled = 0;
443 register_ftrace_function(tr->ops);
444 tr->function_enabled = 1;
445 }
446
tracing_stop_function_trace(struct trace_array * tr)447 static void tracing_stop_function_trace(struct trace_array *tr)
448 {
449 tr->function_enabled = 0;
450 unregister_ftrace_function(tr->ops);
451 }
452
453 static struct tracer function_trace;
454
455 static int
func_set_flag(struct trace_array * tr,u32 old_flags,u32 bit,int set)456 func_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)
457 {
458 ftrace_func_t func;
459 u32 new_flags;
460
461 /* Do nothing if already set. */
462 if (!!set == !!(func_flags.val & bit))
463 return 0;
464
465 /* We can change this flag only when not running. */
466 if (tr->current_trace != &function_trace)
467 return 0;
468
469 new_flags = (func_flags.val & ~bit) | (set ? bit : 0);
470 func = select_trace_function(new_flags);
471 if (!func)
472 return -EINVAL;
473
474 /* Check if there's anything to change. */
475 if (tr->ops->func == func)
476 return 0;
477
478 if (!handle_func_repeats(tr, new_flags))
479 return -ENOMEM;
480
481 unregister_ftrace_function(tr->ops);
482 tr->ops->func = func;
483 register_ftrace_function(tr->ops);
484
485 return 0;
486 }
487
488 static struct tracer function_trace __tracer_data =
489 {
490 .name = "function",
491 .init = function_trace_init,
492 .reset = function_trace_reset,
493 .start = function_trace_start,
494 .flags = &func_flags,
495 .set_flag = func_set_flag,
496 .allow_instances = true,
497 #ifdef CONFIG_FTRACE_SELFTEST
498 .selftest = trace_selftest_startup_function,
499 #endif
500 };
501
502 #ifdef CONFIG_DYNAMIC_FTRACE
update_traceon_count(struct ftrace_probe_ops * ops,unsigned long ip,struct trace_array * tr,bool on,void * data)503 static void update_traceon_count(struct ftrace_probe_ops *ops,
504 unsigned long ip,
505 struct trace_array *tr, bool on,
506 void *data)
507 {
508 struct ftrace_func_mapper *mapper = data;
509 long *count;
510 long old_count;
511
512 /*
513 * Tracing gets disabled (or enabled) once per count.
514 * This function can be called at the same time on multiple CPUs.
515 * It is fine if both disable (or enable) tracing, as disabling
516 * (or enabling) the second time doesn't do anything as the
517 * state of the tracer is already disabled (or enabled).
518 * What needs to be synchronized in this case is that the count
519 * only gets decremented once, even if the tracer is disabled
520 * (or enabled) twice, as the second one is really a nop.
521 *
522 * The memory barriers guarantee that we only decrement the
523 * counter once. First the count is read to a local variable
524 * and a read barrier is used to make sure that it is loaded
525 * before checking if the tracer is in the state we want.
526 * If the tracer is not in the state we want, then the count
527 * is guaranteed to be the old count.
528 *
529 * Next the tracer is set to the state we want (disabled or enabled)
530 * then a write memory barrier is used to make sure that
531 * the new state is visible before changing the counter by
532 * one minus the old counter. This guarantees that another CPU
533 * executing this code will see the new state before seeing
534 * the new counter value, and would not do anything if the new
535 * counter is seen.
536 *
537 * Note, there is no synchronization between this and a user
538 * setting the tracing_on file. But we currently don't care
539 * about that.
540 */
541 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
542 old_count = *count;
543
544 if (old_count <= 0)
545 return;
546
547 /* Make sure we see count before checking tracing state */
548 smp_rmb();
549
550 if (on == !!tracer_tracing_is_on(tr))
551 return;
552
553 if (on)
554 tracer_tracing_on(tr);
555 else
556 tracer_tracing_off(tr);
557
558 /* Make sure tracing state is visible before updating count */
559 smp_wmb();
560
561 *count = old_count - 1;
562 }
563
564 static void
ftrace_traceon_count(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)565 ftrace_traceon_count(unsigned long ip, unsigned long parent_ip,
566 struct trace_array *tr, struct ftrace_probe_ops *ops,
567 void *data)
568 {
569 update_traceon_count(ops, ip, tr, 1, data);
570 }
571
572 static void
ftrace_traceoff_count(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)573 ftrace_traceoff_count(unsigned long ip, unsigned long parent_ip,
574 struct trace_array *tr, struct ftrace_probe_ops *ops,
575 void *data)
576 {
577 update_traceon_count(ops, ip, tr, 0, data);
578 }
579
580 static void
ftrace_traceon(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)581 ftrace_traceon(unsigned long ip, unsigned long parent_ip,
582 struct trace_array *tr, struct ftrace_probe_ops *ops,
583 void *data)
584 {
585 if (tracer_tracing_is_on(tr))
586 return;
587
588 tracer_tracing_on(tr);
589 }
590
591 static void
ftrace_traceoff(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)592 ftrace_traceoff(unsigned long ip, unsigned long parent_ip,
593 struct trace_array *tr, struct ftrace_probe_ops *ops,
594 void *data)
595 {
596 if (!tracer_tracing_is_on(tr))
597 return;
598
599 tracer_tracing_off(tr);
600 }
601
602 #ifdef CONFIG_UNWINDER_ORC
603 /*
604 * Skip 3:
605 *
606 * function_trace_probe_call()
607 * ftrace_ops_assist_func()
608 * ftrace_call()
609 */
610 #define FTRACE_STACK_SKIP 3
611 #else
612 /*
613 * Skip 5:
614 *
615 * __trace_stack()
616 * ftrace_stacktrace()
617 * function_trace_probe_call()
618 * ftrace_ops_assist_func()
619 * ftrace_call()
620 */
621 #define FTRACE_STACK_SKIP 5
622 #endif
623
trace_stack(struct trace_array * tr)624 static __always_inline void trace_stack(struct trace_array *tr)
625 {
626 __trace_stack(tr, tracing_gen_ctx_dec(), FTRACE_STACK_SKIP);
627 }
628
629 static void
ftrace_stacktrace(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)630 ftrace_stacktrace(unsigned long ip, unsigned long parent_ip,
631 struct trace_array *tr, struct ftrace_probe_ops *ops,
632 void *data)
633 {
634 trace_stack(tr);
635 }
636
637 static void
ftrace_stacktrace_count(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)638 ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip,
639 struct trace_array *tr, struct ftrace_probe_ops *ops,
640 void *data)
641 {
642 struct ftrace_func_mapper *mapper = data;
643 long *count;
644 long old_count;
645 long new_count;
646
647 if (!tracing_is_on())
648 return;
649
650 /* unlimited? */
651 if (!mapper) {
652 trace_stack(tr);
653 return;
654 }
655
656 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
657
658 /*
659 * Stack traces should only execute the number of times the
660 * user specified in the counter.
661 */
662 do {
663 old_count = *count;
664
665 if (!old_count)
666 return;
667
668 new_count = old_count - 1;
669 new_count = cmpxchg(count, old_count, new_count);
670 if (new_count == old_count)
671 trace_stack(tr);
672
673 if (!tracing_is_on())
674 return;
675
676 } while (new_count != old_count);
677 }
678
update_count(struct ftrace_probe_ops * ops,unsigned long ip,void * data)679 static int update_count(struct ftrace_probe_ops *ops, unsigned long ip,
680 void *data)
681 {
682 struct ftrace_func_mapper *mapper = data;
683 long *count = NULL;
684
685 if (mapper)
686 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
687
688 if (count) {
689 if (*count <= 0)
690 return 0;
691 (*count)--;
692 }
693
694 return 1;
695 }
696
697 static void
ftrace_dump_probe(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)698 ftrace_dump_probe(unsigned long ip, unsigned long parent_ip,
699 struct trace_array *tr, struct ftrace_probe_ops *ops,
700 void *data)
701 {
702 if (update_count(ops, ip, data))
703 ftrace_dump(DUMP_ALL);
704 }
705
706 /* Only dump the current CPU buffer. */
707 static void
ftrace_cpudump_probe(unsigned long ip,unsigned long parent_ip,struct trace_array * tr,struct ftrace_probe_ops * ops,void * data)708 ftrace_cpudump_probe(unsigned long ip, unsigned long parent_ip,
709 struct trace_array *tr, struct ftrace_probe_ops *ops,
710 void *data)
711 {
712 if (update_count(ops, ip, data))
713 ftrace_dump(DUMP_ORIG);
714 }
715
716 static int
ftrace_probe_print(const char * name,struct seq_file * m,unsigned long ip,struct ftrace_probe_ops * ops,void * data)717 ftrace_probe_print(const char *name, struct seq_file *m,
718 unsigned long ip, struct ftrace_probe_ops *ops,
719 void *data)
720 {
721 struct ftrace_func_mapper *mapper = data;
722 long *count = NULL;
723
724 seq_printf(m, "%ps:%s", (void *)ip, name);
725
726 if (mapper)
727 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
728
729 if (count)
730 seq_printf(m, ":count=%ld\n", *count);
731 else
732 seq_puts(m, ":unlimited\n");
733
734 return 0;
735 }
736
737 static int
ftrace_traceon_print(struct seq_file * m,unsigned long ip,struct ftrace_probe_ops * ops,void * data)738 ftrace_traceon_print(struct seq_file *m, unsigned long ip,
739 struct ftrace_probe_ops *ops,
740 void *data)
741 {
742 return ftrace_probe_print("traceon", m, ip, ops, data);
743 }
744
745 static int
ftrace_traceoff_print(struct seq_file * m,unsigned long ip,struct ftrace_probe_ops * ops,void * data)746 ftrace_traceoff_print(struct seq_file *m, unsigned long ip,
747 struct ftrace_probe_ops *ops, void *data)
748 {
749 return ftrace_probe_print("traceoff", m, ip, ops, data);
750 }
751
752 static int
ftrace_stacktrace_print(struct seq_file * m,unsigned long ip,struct ftrace_probe_ops * ops,void * data)753 ftrace_stacktrace_print(struct seq_file *m, unsigned long ip,
754 struct ftrace_probe_ops *ops, void *data)
755 {
756 return ftrace_probe_print("stacktrace", m, ip, ops, data);
757 }
758
759 static int
ftrace_dump_print(struct seq_file * m,unsigned long ip,struct ftrace_probe_ops * ops,void * data)760 ftrace_dump_print(struct seq_file *m, unsigned long ip,
761 struct ftrace_probe_ops *ops, void *data)
762 {
763 return ftrace_probe_print("dump", m, ip, ops, data);
764 }
765
766 static int
ftrace_cpudump_print(struct seq_file * m,unsigned long ip,struct ftrace_probe_ops * ops,void * data)767 ftrace_cpudump_print(struct seq_file *m, unsigned long ip,
768 struct ftrace_probe_ops *ops, void *data)
769 {
770 return ftrace_probe_print("cpudump", m, ip, ops, data);
771 }
772
773
774 static int
ftrace_count_init(struct ftrace_probe_ops * ops,struct trace_array * tr,unsigned long ip,void * init_data,void ** data)775 ftrace_count_init(struct ftrace_probe_ops *ops, struct trace_array *tr,
776 unsigned long ip, void *init_data, void **data)
777 {
778 struct ftrace_func_mapper *mapper = *data;
779
780 if (!mapper) {
781 mapper = allocate_ftrace_func_mapper();
782 if (!mapper)
783 return -ENOMEM;
784 *data = mapper;
785 }
786
787 return ftrace_func_mapper_add_ip(mapper, ip, init_data);
788 }
789
790 static void
ftrace_count_free(struct ftrace_probe_ops * ops,struct trace_array * tr,unsigned long ip,void * data)791 ftrace_count_free(struct ftrace_probe_ops *ops, struct trace_array *tr,
792 unsigned long ip, void *data)
793 {
794 struct ftrace_func_mapper *mapper = data;
795
796 if (!ip) {
797 free_ftrace_func_mapper(mapper, NULL);
798 return;
799 }
800
801 ftrace_func_mapper_remove_ip(mapper, ip);
802 }
803
804 static struct ftrace_probe_ops traceon_count_probe_ops = {
805 .func = ftrace_traceon_count,
806 .print = ftrace_traceon_print,
807 .init = ftrace_count_init,
808 .free = ftrace_count_free,
809 };
810
811 static struct ftrace_probe_ops traceoff_count_probe_ops = {
812 .func = ftrace_traceoff_count,
813 .print = ftrace_traceoff_print,
814 .init = ftrace_count_init,
815 .free = ftrace_count_free,
816 };
817
818 static struct ftrace_probe_ops stacktrace_count_probe_ops = {
819 .func = ftrace_stacktrace_count,
820 .print = ftrace_stacktrace_print,
821 .init = ftrace_count_init,
822 .free = ftrace_count_free,
823 };
824
825 static struct ftrace_probe_ops dump_probe_ops = {
826 .func = ftrace_dump_probe,
827 .print = ftrace_dump_print,
828 .init = ftrace_count_init,
829 .free = ftrace_count_free,
830 };
831
832 static struct ftrace_probe_ops cpudump_probe_ops = {
833 .func = ftrace_cpudump_probe,
834 .print = ftrace_cpudump_print,
835 };
836
837 static struct ftrace_probe_ops traceon_probe_ops = {
838 .func = ftrace_traceon,
839 .print = ftrace_traceon_print,
840 };
841
842 static struct ftrace_probe_ops traceoff_probe_ops = {
843 .func = ftrace_traceoff,
844 .print = ftrace_traceoff_print,
845 };
846
847 static struct ftrace_probe_ops stacktrace_probe_ops = {
848 .func = ftrace_stacktrace,
849 .print = ftrace_stacktrace_print,
850 };
851
852 static int
ftrace_trace_probe_callback(struct trace_array * tr,struct ftrace_probe_ops * ops,struct ftrace_hash * hash,char * glob,char * cmd,char * param,int enable)853 ftrace_trace_probe_callback(struct trace_array *tr,
854 struct ftrace_probe_ops *ops,
855 struct ftrace_hash *hash, char *glob,
856 char *cmd, char *param, int enable)
857 {
858 void *count = (void *)-1;
859 char *number;
860 int ret;
861
862 /* hash funcs only work with set_ftrace_filter */
863 if (!enable)
864 return -EINVAL;
865
866 if (glob[0] == '!')
867 return unregister_ftrace_function_probe_func(glob+1, tr, ops);
868
869 if (!param)
870 goto out_reg;
871
872 number = strsep(¶m, ":");
873
874 if (!strlen(number))
875 goto out_reg;
876
877 /*
878 * We use the callback data field (which is a pointer)
879 * as our counter.
880 */
881 ret = kstrtoul(number, 0, (unsigned long *)&count);
882 if (ret)
883 return ret;
884
885 out_reg:
886 ret = register_ftrace_function_probe(glob, tr, ops, count);
887
888 return ret < 0 ? ret : 0;
889 }
890
891 static int
ftrace_trace_onoff_callback(struct trace_array * tr,struct ftrace_hash * hash,char * glob,char * cmd,char * param,int enable)892 ftrace_trace_onoff_callback(struct trace_array *tr, struct ftrace_hash *hash,
893 char *glob, char *cmd, char *param, int enable)
894 {
895 struct ftrace_probe_ops *ops;
896
897 if (!tr)
898 return -ENODEV;
899
900 /* we register both traceon and traceoff to this callback */
901 if (strcmp(cmd, "traceon") == 0)
902 ops = param ? &traceon_count_probe_ops : &traceon_probe_ops;
903 else
904 ops = param ? &traceoff_count_probe_ops : &traceoff_probe_ops;
905
906 return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
907 param, enable);
908 }
909
910 static int
ftrace_stacktrace_callback(struct trace_array * tr,struct ftrace_hash * hash,char * glob,char * cmd,char * param,int enable)911 ftrace_stacktrace_callback(struct trace_array *tr, struct ftrace_hash *hash,
912 char *glob, char *cmd, char *param, int enable)
913 {
914 struct ftrace_probe_ops *ops;
915
916 if (!tr)
917 return -ENODEV;
918
919 ops = param ? &stacktrace_count_probe_ops : &stacktrace_probe_ops;
920
921 return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
922 param, enable);
923 }
924
925 static int
ftrace_dump_callback(struct trace_array * tr,struct ftrace_hash * hash,char * glob,char * cmd,char * param,int enable)926 ftrace_dump_callback(struct trace_array *tr, struct ftrace_hash *hash,
927 char *glob, char *cmd, char *param, int enable)
928 {
929 struct ftrace_probe_ops *ops;
930
931 if (!tr)
932 return -ENODEV;
933
934 ops = &dump_probe_ops;
935
936 /* Only dump once. */
937 return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
938 "1", enable);
939 }
940
941 static int
ftrace_cpudump_callback(struct trace_array * tr,struct ftrace_hash * hash,char * glob,char * cmd,char * param,int enable)942 ftrace_cpudump_callback(struct trace_array *tr, struct ftrace_hash *hash,
943 char *glob, char *cmd, char *param, int enable)
944 {
945 struct ftrace_probe_ops *ops;
946
947 if (!tr)
948 return -ENODEV;
949
950 ops = &cpudump_probe_ops;
951
952 /* Only dump once. */
953 return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
954 "1", enable);
955 }
956
957 static struct ftrace_func_command ftrace_traceon_cmd = {
958 .name = "traceon",
959 .func = ftrace_trace_onoff_callback,
960 };
961
962 static struct ftrace_func_command ftrace_traceoff_cmd = {
963 .name = "traceoff",
964 .func = ftrace_trace_onoff_callback,
965 };
966
967 static struct ftrace_func_command ftrace_stacktrace_cmd = {
968 .name = "stacktrace",
969 .func = ftrace_stacktrace_callback,
970 };
971
972 static struct ftrace_func_command ftrace_dump_cmd = {
973 .name = "dump",
974 .func = ftrace_dump_callback,
975 };
976
977 static struct ftrace_func_command ftrace_cpudump_cmd = {
978 .name = "cpudump",
979 .func = ftrace_cpudump_callback,
980 };
981
init_func_cmd_traceon(void)982 static int __init init_func_cmd_traceon(void)
983 {
984 int ret;
985
986 ret = register_ftrace_command(&ftrace_traceoff_cmd);
987 if (ret)
988 return ret;
989
990 ret = register_ftrace_command(&ftrace_traceon_cmd);
991 if (ret)
992 goto out_free_traceoff;
993
994 ret = register_ftrace_command(&ftrace_stacktrace_cmd);
995 if (ret)
996 goto out_free_traceon;
997
998 ret = register_ftrace_command(&ftrace_dump_cmd);
999 if (ret)
1000 goto out_free_stacktrace;
1001
1002 ret = register_ftrace_command(&ftrace_cpudump_cmd);
1003 if (ret)
1004 goto out_free_dump;
1005
1006 return 0;
1007
1008 out_free_dump:
1009 unregister_ftrace_command(&ftrace_dump_cmd);
1010 out_free_stacktrace:
1011 unregister_ftrace_command(&ftrace_stacktrace_cmd);
1012 out_free_traceon:
1013 unregister_ftrace_command(&ftrace_traceon_cmd);
1014 out_free_traceoff:
1015 unregister_ftrace_command(&ftrace_traceoff_cmd);
1016
1017 return ret;
1018 }
1019 #else
init_func_cmd_traceon(void)1020 static inline int init_func_cmd_traceon(void)
1021 {
1022 return 0;
1023 }
1024 #endif /* CONFIG_DYNAMIC_FTRACE */
1025
init_function_trace(void)1026 __init int init_function_trace(void)
1027 {
1028 init_func_cmd_traceon();
1029 return register_tracer(&function_trace);
1030 }
1031