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