2 * ltt/probes/kernel-trace.c
4 * kernel tracepoint probes.
6 * (C) Copyright 2009 - Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
7 * Dual LGPL v2.1/GPL v2 license.
10 #include <linux/module.h>
11 #include <linux/irq.h>
12 #include <trace/events/signal.h>
13 #include <trace/irq.h>
14 #include <trace/sched.h>
15 #include <trace/timer.h>
16 #include <trace/kernel.h>
17 #include <trace/fault.h>
18 #include <trace/events/sched.h>
20 #include "../ltt-tracer.h"
21 #include "../ltt-type-serializer.h"
24 * This should probably be added to s390.
27 static struct pt_regs
*get_irq_regs(void)
29 return task_pt_regs(current
);
35 * currently, the specialized tracepoint probes cannot call into other marker
36 * probes, such as ftrace enable/disable. Given we want them to be as fast as
37 * possible, it might not be so bad to lose this flexibility. But that means
38 * such probes would have to connect to tracepoints on their own.
41 /* kernel_irq_entry specialized tracepoint probe */
43 void probe_irq_entry(void *_data
, unsigned int id
, struct pt_regs
*regs
,
44 struct irqaction
*action
);
46 DEFINE_MARKER_TP(kernel
, irq_entry
, irq_entry
, probe_irq_entry
,
47 "ip %lu handler %p irq_id #2u%u kernel_mode #1u%u");
49 notrace
void probe_irq_entry(void *_data
, unsigned int id
, struct pt_regs
*regs
,
50 struct irqaction
*action
)
52 struct marker
*marker
;
53 struct serialize_long_long_short_char data
;
56 regs
= get_irq_regs();
58 data
.f1
= instruction_pointer(regs
);
59 data
.f4
= !user_mode(regs
);
64 data
.f2
= (unsigned long) (action
? action
->handler
: NULL
);
67 marker
= &GET_MARKER(kernel
, irq_entry
);
68 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
69 &data
, serialize_sizeof(data
), sizeof(long));
72 void probe_irq_next_handler(void *_data
, unsigned int id
, struct irqaction
*action
,
73 irqreturn_t prev_ret
);
75 DEFINE_MARKER_TP(kernel
, irq_next_handler
, irq_next_handler
,
76 probe_irq_next_handler
,
77 "handler %p prev_ret #1u%u");
79 notrace
void probe_irq_next_handler(void *_data
, unsigned int id
, struct irqaction
*action
,
82 struct marker
*marker
;
83 struct serialize_long_char data
;
85 data
.f1
= (unsigned long) (action
? action
->handler
: NULL
);
88 marker
= &GET_MARKER(kernel
, irq_next_handler
);
89 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
90 &data
, serialize_sizeof(data
), sizeof(long));
93 /* kernel_irq_exit specialized tracepoint probe */
95 void probe_irq_exit(void *_data
, irqreturn_t retval
);
97 DEFINE_MARKER_TP(kernel
, irq_exit
, irq_exit
, probe_irq_exit
,
100 notrace
void probe_irq_exit(void *_data
, irqreturn_t retval
)
102 struct marker
*marker
;
105 data
= IRQ_RETVAL(retval
);
107 marker
= &GET_MARKER(kernel
, irq_exit
);
108 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
109 &data
, sizeof(data
), sizeof(data
));
112 /* kernel_softirq_entry specialized tracepoint probe */
114 void probe_softirq_entry(void *_data
, struct softirq_action
*h
,
115 struct softirq_action
*softirq_vec
);
117 DEFINE_MARKER_TP(kernel
, softirq_entry
, softirq_entry
,
118 probe_softirq_entry
, "softirq_id #1u%lu");
120 notrace
void probe_softirq_entry(void *_data
, struct softirq_action
*h
,
121 struct softirq_action
*softirq_vec
)
123 struct marker
*marker
;
126 data
= ((unsigned long)h
- (unsigned long)softirq_vec
) / sizeof(*h
);
128 marker
= &GET_MARKER(kernel
, softirq_entry
);
129 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
130 &data
, sizeof(data
), sizeof(data
));
133 /* kernel_softirq_exit specialized tracepoint probe */
135 void probe_softirq_exit(void *_data
, struct softirq_action
*h
,
136 struct softirq_action
*softirq_vec
);
138 DEFINE_MARKER_TP(kernel
, softirq_exit
, softirq_exit
,
139 probe_softirq_exit
, "softirq_id #1u%lu");
141 notrace
void probe_softirq_exit(void *_data
, struct softirq_action
*h
,
142 struct softirq_action
*softirq_vec
)
144 struct marker
*marker
;
147 data
= ((unsigned long)h
- (unsigned long)softirq_vec
) / sizeof(*h
);
149 marker
= &GET_MARKER(kernel
, softirq_exit
);
150 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
151 &data
, sizeof(data
), sizeof(data
));
154 /* kernel_softirq_raise specialized tracepoint probe */
156 void probe_softirq_raise(void *_data
, unsigned int nr
);
158 DEFINE_MARKER_TP(kernel
, softirq_raise
, softirq_raise
,
159 probe_softirq_raise
, "softirq_id #1u%u");
161 notrace
void probe_softirq_raise(void *_data
, unsigned int nr
)
163 struct marker
*marker
;
168 marker
= &GET_MARKER(kernel
, softirq_raise
);
169 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
170 &data
, sizeof(data
), sizeof(data
));
173 /* Standard probes */
174 void probe_irq_tasklet_low_entry(void *_data
, struct tasklet_struct
*t
)
176 trace_mark_tp(kernel
, tasklet_low_entry
, irq_tasklet_low_entry
,
177 probe_irq_tasklet_low_entry
, "func %p data %lu",
181 void probe_irq_tasklet_low_exit(void *_data
, struct tasklet_struct
*t
)
183 trace_mark_tp(kernel
, tasklet_low_exit
, irq_tasklet_low_exit
,
184 probe_irq_tasklet_low_exit
, "func %p data %lu",
188 void probe_irq_tasklet_high_entry(void *_data
, struct tasklet_struct
*t
)
190 trace_mark_tp(kernel
, tasklet_high_entry
, irq_tasklet_high_entry
,
191 probe_irq_tasklet_high_entry
, "func %p data %lu",
195 void probe_irq_tasklet_high_exit(void *_data
, struct tasklet_struct
*t
)
197 trace_mark_tp(kernel
, tasklet_high_exit
, irq_tasklet_high_exit
,
198 probe_irq_tasklet_high_exit
, "func %p data %lu",
202 void probe_sched_kthread_stop(void *_data
, struct task_struct
*t
)
204 trace_mark_tp(kernel
, kthread_stop
, sched_kthread_stop
,
205 probe_sched_kthread_stop
, "pid %d", t
->pid
);
208 void probe_sched_kthread_stop_ret(void *_data
, int ret
)
210 trace_mark_tp(kernel
, kthread_stop_ret
, sched_kthread_stop_ret
,
211 probe_sched_kthread_stop_ret
, "ret %d", ret
);
214 void probe_sched_wait_task(void *_data
, struct task_struct
*p
)
216 trace_mark_tp(kernel
, sched_wait_task
, sched_wait_task
,
217 probe_sched_wait_task
, "pid %d state #2d%ld",
221 /* kernel_sched_try_wakeup specialized tracepoint probe */
223 void probe_sched_wakeup(void *_data
, struct task_struct
*p
, int success
);
225 DEFINE_MARKER_TP(kernel
, sched_try_wakeup
, sched_wakeup
,
226 probe_sched_wakeup
, "pid %d cpu_id %u state #2d%ld");
228 notrace
void probe_sched_wakeup(void *_data
, struct task_struct
*p
, int success
)
230 struct marker
*marker
;
231 struct serialize_int_int_short data
;
234 data
.f2
= task_cpu(p
);
237 marker
= &GET_MARKER(kernel
, sched_try_wakeup
);
238 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
239 &data
, serialize_sizeof(data
), sizeof(int));
242 void probe_sched_wakeup_new(void *_data
, struct task_struct
*p
, int success
)
244 trace_mark_tp(kernel
, sched_wakeup_new_task
, sched_wakeup_new
,
245 probe_sched_wakeup_new
, "pid %d state #2d%ld cpu_id %u",
246 p
->pid
, p
->state
, task_cpu(p
));
249 /* kernel_sched_schedule specialized tracepoint probe */
251 void probe_sched_switch(void *_data
, struct task_struct
*prev
,
252 struct task_struct
*next
);
254 DEFINE_MARKER_TP(kernel
, sched_schedule
, sched_switch
, probe_sched_switch
,
255 "prev_pid %d next_pid %d prev_state #2d%ld");
257 notrace
void probe_sched_switch(void *_data
, struct task_struct
*prev
,
258 struct task_struct
*next
)
260 struct marker
*marker
;
261 struct serialize_int_int_short data
;
265 data
.f3
= prev
->state
;
267 marker
= &GET_MARKER(kernel
, sched_schedule
);
268 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
269 &data
, serialize_sizeof(data
), sizeof(int));
272 void probe_sched_migrate_task(void *_data
, struct task_struct
*p
, int dest_cpu
)
274 trace_mark_tp(kernel
, sched_migrate_task
, sched_migrate_task
,
275 probe_sched_migrate_task
, "pid %d state #2d%ld dest_cpu %d",
276 p
->pid
, p
->state
, dest_cpu
);
279 void probe_sched_signal_send(void *_data
, int sig
, struct siginfo
*info
, struct task_struct
*t
)
281 trace_mark_tp(kernel
, send_signal
, signal_generate
,
282 probe_sched_signal_send
, "pid %d signal %d", t
->pid
, sig
);
285 void probe_sched_process_free(void *_data
, struct task_struct
*p
)
287 trace_mark_tp(kernel
, process_free
, sched_process_free
,
288 probe_sched_process_free
, "pid %d", p
->pid
);
291 void probe_sched_process_exit(void *_data
, struct task_struct
*p
)
293 trace_mark_tp(kernel
, process_exit
, sched_process_exit
,
294 probe_sched_process_exit
, "pid %d", p
->pid
);
297 void probe_sched_process_wait(void *_data
, struct pid
*pid
)
299 trace_mark_tp(kernel
, process_wait
, sched_process_wait
,
300 probe_sched_process_wait
, "pid %d", pid_nr(pid
));
303 void probe_sched_process_fork(void *_data
, struct task_struct
*parent
,
304 struct task_struct
*child
)
306 trace_mark_tp(kernel
, process_fork
, sched_process_fork
,
307 probe_sched_process_fork
,
308 "parent_pid %d child_pid %d child_tgid %d",
309 parent
->pid
, child
->pid
, child
->tgid
);
312 void probe_sched_kthread_create(void *_data
, void *fn
, int pid
)
314 trace_mark_tp(kernel
, kthread_create
, sched_kthread_create
,
315 probe_sched_kthread_create
,
316 "fn %p pid %d", fn
, pid
);
319 void probe_timer_itimer_expired(void *_data
, struct signal_struct
*sig
)
321 trace_mark_tp(kernel
, timer_itimer_expired
, timer_itimer_expired
,
322 probe_timer_itimer_expired
, "pid %d",
323 pid_nr(sig
->leader_pid
));
326 void probe_timer_itimer_set(void *_data
, int which
, struct itimerval
*value
)
328 trace_mark_tp(kernel
, timer_itimer_set
,
329 timer_itimer_set
, probe_timer_itimer_set
,
330 "which %d interval_sec %ld interval_usec %ld "
331 "value_sec %ld value_usec %ld",
333 value
->it_interval
.tv_sec
,
334 value
->it_interval
.tv_usec
,
335 value
->it_value
.tv_sec
,
336 value
->it_value
.tv_usec
);
339 /* kernel_timer_set specialized tracepoint probe */
341 void probe_timer_set(void *_data
, struct timer_list
*timer
);
343 DEFINE_MARKER_TP(kernel
, timer_set
, timer_set
, probe_timer_set
,
344 "expires %lu function %p data %lu");
346 notrace
void probe_timer_set(void *_data
, struct timer_list
*timer
)
348 struct marker
*marker
;
349 struct serialize_long_long_long data
;
351 data
.f1
= timer
->expires
;
352 data
.f2
= (unsigned long)timer
->function
;
353 data
.f3
= timer
->data
;
355 marker
= &GET_MARKER(kernel
, timer_set
);
356 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
357 &data
, serialize_sizeof(data
), sizeof(long));
360 void probe_timer_update_time(void *_data
, struct timespec
*_xtime
,
361 struct timespec
*_wall_to_monotonic
)
363 trace_mark_tp(kernel
, timer_update_time
, timer_update_time
,
364 probe_timer_update_time
,
365 "jiffies #8u%llu xtime_sec %ld xtime_nsec %ld "
366 "walltomonotonic_sec %ld walltomonotonic_nsec %ld",
367 (unsigned long long)jiffies_64
, _xtime
->tv_sec
, _xtime
->tv_nsec
,
368 _wall_to_monotonic
->tv_sec
, _wall_to_monotonic
->tv_nsec
);
371 void probe_timer_timeout(void *_data
, struct task_struct
*p
)
373 trace_mark_tp(kernel
, timer_timeout
, timer_timeout
,
374 probe_timer_timeout
, "pid %d", p
->pid
);
377 void probe_kernel_printk(void *_data
, unsigned long retaddr
)
379 trace_mark_tp(kernel
, printk
, kernel_printk
,
380 probe_kernel_printk
, "ip 0x%lX", retaddr
);
383 void probe_kernel_vprintk(void *_data
, unsigned long retaddr
, char *buf
, int len
)
386 unsigned int loglevel
;
391 if (buf
[0] == '<' && buf
[1] >= '0' &&
392 buf
[1] <= '7' && buf
[2] == '>') {
393 loglevel
= buf
[1] - '0';
397 loglevel
= default_message_loglevel
;
401 if (mark_buf
[mark_len
- 1] == '\n')
403 saved_char
= mark_buf
[mark_len
];
404 mark_buf
[mark_len
] = '\0';
405 trace_mark_tp(kernel
, vprintk
, kernel_vprintk
,
406 probe_kernel_vprintk
,
407 "loglevel #1u%u string %s ip 0x%lX",
408 loglevel
, mark_buf
, retaddr
);
409 mark_buf
[mark_len
] = saved_char
;
413 #ifdef CONFIG_MODULES
414 void probe_kernel_module_free(void *_data
, struct module
*mod
)
416 trace_mark_tp(kernel
, module_free
, kernel_module_free
,
417 probe_kernel_module_free
, "name %s", mod
->name
);
420 void probe_kernel_module_load(void *_data
, struct module
*mod
)
422 trace_mark_tp(kernel
, module_load
, kernel_module_load
,
423 probe_kernel_module_load
, "name %s", mod
->name
);
427 void probe_kernel_panic(void *_data
, const char *fmt
, va_list args
)
430 vsnprintf(info
, sizeof(info
), fmt
, args
);
431 trace_mark_tp(kernel
, panic
, kernel_panic
, probe_kernel_panic
,
435 void probe_kernel_kernel_kexec(void *_data
, struct kimage
*image
)
437 trace_mark_tp(kernel
, kernel_kexec
, kernel_kernel_kexec
,
438 probe_kernel_kernel_kexec
, "image %p", image
);
441 void probe_kernel_crash_kexec(void *_data
, struct kimage
*image
, struct pt_regs
*regs
)
443 trace_mark_tp(kernel
, crash_kexec
, kernel_crash_kexec
,
444 probe_kernel_crash_kexec
, "image %p ip %p", image
,
445 regs
? (void *)instruction_pointer(regs
) : NULL
);
448 /* kernel_page_fault_entry specialized tracepoint probe */
450 void probe_kernel_page_fault_entry(void *_data
, struct pt_regs
*regs
, int trapnr
,
451 struct mm_struct
*mm
, struct vm_area_struct
*vma
,
452 unsigned long address
, int write_access
);
454 DEFINE_MARKER_TP(kernel
, page_fault_entry
, page_fault_entry
,
455 probe_kernel_page_fault_entry
,
456 "ip #p%lu address #p%lu trap_id #2u%u write_access #1u%u");
458 notrace
void probe_kernel_page_fault_entry(void *_data
, struct pt_regs
*regs
, int trapnr
,
459 struct mm_struct
*mm
, struct vm_area_struct
*vma
,
460 unsigned long address
, int write_access
)
462 struct marker
*marker
;
463 struct serialize_long_long_short_char data
;
466 data
.f1
= instruction_pointer(regs
);
470 data
.f3
= (unsigned short)trapnr
;
471 data
.f4
= (unsigned char)!!write_access
;
473 marker
= &GET_MARKER(kernel
, page_fault_entry
);
474 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
475 &data
, serialize_sizeof(data
), sizeof(long));
478 /* kernel_page_fault_exit specialized tracepoint probe */
480 void probe_kernel_page_fault_exit(void *_data
, int res
);
482 DEFINE_MARKER_TP(kernel
, page_fault_exit
, page_fault_exit
,
483 probe_kernel_page_fault_exit
,
486 notrace
void probe_kernel_page_fault_exit(void *_data
, int res
)
488 struct marker
*marker
;
490 marker
= &GET_MARKER(kernel
, page_fault_exit
);
491 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
492 &res
, sizeof(res
), sizeof(res
));
495 /* kernel_page_fault_nosem_entry specialized tracepoint probe */
497 void probe_kernel_page_fault_nosem_entry(void *_data
, struct pt_regs
*regs
,
498 int trapnr
, unsigned long address
);
500 DEFINE_MARKER_TP(kernel
, page_fault_nosem_entry
, page_fault_nosem_entry
,
501 probe_kernel_page_fault_nosem_entry
,
502 "ip #p%lu address #p%lu trap_id #2u%u");
504 notrace
void probe_kernel_page_fault_nosem_entry(void *_data
, struct pt_regs
*regs
,
505 int trapnr
, unsigned long address
)
507 struct marker
*marker
;
508 struct serialize_long_long_short data
;
511 data
.f1
= instruction_pointer(regs
);
515 data
.f3
= (unsigned short)trapnr
;
517 marker
= &GET_MARKER(kernel
, page_fault_nosem_entry
);
518 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
519 &data
, serialize_sizeof(data
), sizeof(long));
522 /* kernel_page_fault_nosem_exit specialized tracepoint probe */
524 void probe_kernel_page_fault_nosem_exit(void *_data
, int res
);
526 DEFINE_MARKER_TP(kernel
, page_fault_nosem_exit
, page_fault_nosem_exit
,
527 probe_kernel_page_fault_nosem_exit
,
530 notrace
void probe_kernel_page_fault_nosem_exit(void *_data
, int res
)
532 struct marker
*marker
;
534 marker
= &GET_MARKER(kernel
, page_fault_nosem_exit
);
535 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
539 /* kernel_page_fault_get_user_entry specialized tracepoint probe */
541 void probe_kernel_page_fault_get_user_entry(void *_data
, struct mm_struct
*mm
,
542 struct vm_area_struct
*vma
, unsigned long address
, int write_access
);
544 DEFINE_MARKER_TP(kernel
, page_fault_get_user_entry
, page_fault_get_user_entry
,
545 probe_kernel_page_fault_get_user_entry
,
546 "address #p%lu write_access #1u%u");
548 notrace
void probe_kernel_page_fault_get_user_entry(void *_data
, struct mm_struct
*mm
,
549 struct vm_area_struct
*vma
, unsigned long address
, int write_access
)
551 struct marker
*marker
;
552 struct serialize_long_char data
;
555 data
.f2
= (unsigned char)!!write_access
;
557 marker
= &GET_MARKER(kernel
, page_fault_get_user_entry
);
558 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
559 &data
, serialize_sizeof(data
), sizeof(long));
562 /* kernel_page_fault_get_user_exit specialized tracepoint probe */
564 void probe_kernel_page_fault_get_user_exit(void *_data
, int res
);
566 DEFINE_MARKER_TP(kernel
, page_fault_get_user_exit
, page_fault_get_user_exit
,
567 probe_kernel_page_fault_get_user_exit
,
570 notrace
void probe_kernel_page_fault_get_user_exit(void *_data
, int res
)
572 struct marker
*marker
;
574 marker
= &GET_MARKER(kernel
, page_fault_get_user_exit
);
575 ltt_specialized_trace(marker
, marker
->single
.probe_private
,
576 &res
, sizeof(res
), sizeof(res
));
579 MODULE_LICENSE("GPL and additional rights");
580 MODULE_AUTHOR("Mathieu Desnoyers");
581 MODULE_DESCRIPTION("kernel Tracepoint Probes");