1 /* 2 * trace context switch 3 * 4 * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com> 5 * 6 */ 7 #include <linux/module.h> 8 #include <linux/fs.h> 9 #include <linux/debugfs.h> 10 #include <linux/kallsyms.h> 11 #include <linux/uaccess.h> 12 #include <linux/ftrace.h> 13 #include <trace/events/sched.h> 14 15 #include "trace.h" 16 17 static int sched_ref; 18 static DEFINE_MUTEX(sched_register_mutex); 19 20 static void 21 probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next) 22 { 23 if (unlikely(!sched_ref)) 24 return; 25 26 tracing_record_cmdline(prev); 27 tracing_record_cmdline(next); 28 } 29 30 static void 31 probe_sched_wakeup(void *ignore, struct task_struct *wakee, int success) 32 { 33 if (unlikely(!sched_ref)) 34 return; 35 36 tracing_record_cmdline(current); 37 } 38 39 static int tracing_sched_register(void) 40 { 41 int ret; 42 43 ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL); 44 if (ret) { 45 pr_info("wakeup trace: Couldn't activate tracepoint" 46 " probe to kernel_sched_wakeup\n"); 47 return ret; 48 } 49 50 ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 51 if (ret) { 52 pr_info("wakeup trace: Couldn't activate tracepoint" 53 " probe to kernel_sched_wakeup_new\n"); 54 goto fail_deprobe; 55 } 56 57 ret = register_trace_sched_switch(probe_sched_switch, NULL); 58 if (ret) { 59 pr_info("sched trace: Couldn't activate tracepoint" 60 " probe to kernel_sched_switch\n"); 61 goto fail_deprobe_wake_new; 62 } 63 64 return ret; 65 fail_deprobe_wake_new: 66 unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 67 fail_deprobe: 68 unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 69 return ret; 70 } 71 72 static void tracing_sched_unregister(void) 73 { 74 unregister_trace_sched_switch(probe_sched_switch, NULL); 75 unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 76 unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 77 } 78 79 static void tracing_start_sched_switch(void) 80 { 81 mutex_lock(&sched_register_mutex); 82 if (!(sched_ref++)) 83 tracing_sched_register(); 84 mutex_unlock(&sched_register_mutex); 85 } 86 87 static void tracing_stop_sched_switch(void) 88 { 89 mutex_lock(&sched_register_mutex); 90 if (!(--sched_ref)) 91 tracing_sched_unregister(); 92 mutex_unlock(&sched_register_mutex); 93 } 94 95 void tracing_start_cmdline_record(void) 96 { 97 tracing_start_sched_switch(); 98 } 99 100 void tracing_stop_cmdline_record(void) 101 { 102 tracing_stop_sched_switch(); 103 } 104